一、团队成员以及负责模块二、Git提交记录三、项目简介四、项目功能架构图
1.流程图2.UML类图 五、运行截图六、主要代码
1.*主要流程2.* 抓取返回3.红线摇摆以及终点坐标计算4.碰撞检测5.背景设计
属性 :方法 :
打印图形界面倒计时函数设计重新开始游戏函数GUI界面对应程序文字样式 七、个人博客链接八、脱离IDE运行
一、团队成员以及负责模块
| 成员 | 负责模块 |
|---|---|
| 陈锐(组长) | 编码规范,生成物品的类的编写,GUI界面设计,脱离IDE运行 |
| 郑子健 | 编码规范,游戏主窗口的编写,红线功能设计,素材收集 |
仿照黄金矿工的经典游戏模式,我们做了一个集大矿工小游戏。
开始界面
游戏界面
失败界面
void launch() {
this.setVisible(true);
this.setSize(768, 1000);
this.setLocationRelativeTo(null);
this.setTitle("集大矿工");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
int leftButton = 1;
int rightButton = 3;
switch (gameState) {
case 0:
if (e.getButton() == rightButton) {
gameState = 1;
backGround.startTime = System.currentTimeMillis();
}
break;
case 1:
if (e.getButton() == leftButton && line.lineState == 0) {
line.lineState = 1;
}
int capture = 3;
if (e.getButton() == rightButton && line.lineState == capture && BackGround.batteryNum > 0) {
BackGround.batteryState = true;
BackGround.batteryNum--;
}
break;
case 2:
if (e.getButton() == leftButton) {
backGround.shop = true;
}
if (e.getButton() == rightButton) {
gameState = 1;
backGround.startTime = System.currentTimeMillis();
}
break;
case 3:
case 4:
if (e.getButton() == leftButton) {
gameState = 0;
backGround.reGame();
line.reGame();
}
break;
default:
}
}
}
简述:设定一个鼠标事件监听器,用户的左键和右键会有不同的返回值,以此来控制游戏开始。设定变量gameState来记录游戏现在处于哪个状态。
2.* 抓取返回case 3:
int mass = 1;
if (length >= minLength) {
length = length - 5;
lines(g);
for (Objects subject : this.frame.objectList) {
if (subject.isMove) {
mass = subject.mass;
subject.x = endX - subject.getWidth() / 2;
subject.y = endY;
if (length <= minLength) {
subject.x = -150;
subject.y = -150;
subject.isMove = false;
// 加分
BackGround.count += subject.score;
BackGround.batteryState = false;
lineState = 0;
}
if (BackGround.batteryState) {
if (subject.type == 1) {
// 课本
mass = 1;
} else if (subject.type == 2) {
// 炸弹
subject.x = -150;
subject.y = -150;
subject.isMove = false;
BackGround.batteryState = false;
lineState = 2;
}
}
}
}
}
try {
Thread.sleep(mass);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
此时已经确认抓到物体,于是线开始收回,此时判断抓到的是课本还是炸弹,若是课本,则使用道具会加快回收(使mass=1),若是炸弹,使用道具则会直接丢炸弹并收回红线。通过Thread.sleep(mass)来控制回收速度,质量大的物体使线程的睡眠时间更久,看起来回收的更缓慢。
3.红线摇摆以及终点坐标计算endX = (int) (startX + length * Math.cos(angle * Math.PI)); endY = (int) (startY + length * Math.sin(angle * Math.PI));
原理:
红线起点固定,终点坐标随角度和线长变化
并且通过查阅资料得知,计算机中的x,y轴设定不一样,如图
故而我们需要的角度变化为0-Π。设置角度变量在0-1之间再*Π,再添加一个方向变量direction,若红线到达边界则将direction置为相反数来改变方向。
4.碰撞检测void collisionDetection() {
for (Objects subject : this.frame.objectList) {
if (endX > subject.x && endX < subject.x + subject.width && endY > subject.y
&& endY < subject.y + subject.height) {
lineState = 3;
subject.isMove = true;
}
}
}
5.背景设计
游戏背景类
选取图片
人物选择可爱的皮卡丘
关卡,电池数量,当前分数,目标分数,倒计时
方法 : 打印图形界面
void paintSelf(Graphics g) {
switch (GameWin.gameState) {
case 0:
g.drawImage(startPicture, 0, 0, null);
drawWord(g, 80, Color.ORANGE, "集大矿工", 40, 150);
drawWord(g, 40, Color.lightGray, "轻触右键开始", 40, 210);
break;
case 1:
g.drawImage(backGroundPicture, 0, 200, null);
g.drawImage(backGroundPicture1, 0, 0, null);
g.drawImage(minerPicture, 310, 50, null);
drawWord(g, 30, Color.black, "积分:" + count, 30, 150);
g.drawImage(batteryPicture, 550, 40, null);
drawWord(g, 30, Color.black, "*" + batteryNum, 610, 70);
drawWord(g, 20, Color.black, "第" + level + "关", 30, 60);
drawWord(g, 30, Color.black, "目标" + goal, 30, 110);
endTime = System.currentTimeMillis();
long tim = 20 - (endTime - startTime) / 1000;
drawWord(g, 30, Color.black, "时间:" + (tim > 0 ? tim : 0), 520, 150);
break;
case 2:
g.drawImage(backGroundPicture, 0, 200, null);
g.drawImage(backGroundPicture1, 0, 0, null);
g.drawImage(batteryPicture, 300, 400, null);
drawWord(g, 30, Color.black, "价格:" + price, 300, 500);
drawWord(g, 30, Color.black, "左键购买 右键取消", 250, 600);
if (shop) {
count = count - price;
batteryNum++;
shop = false;
GameWin.gameState = 1;
startTime = System.currentTimeMillis();
}
break;
case 3:
g.drawImage(defeatPicture, 0, 0, null);
drawWord(g, 80, Color.red, "失败 " + "积分:" + count, 100, 100);
drawWord(g, 40, Color.gray, "左键重新开始游戏", 150, 150);
break;
case 4:
g.drawImage(winPicture, 0, 0, null);
drawWord(g, 80, Color.red, "成功 " + "积分:" + count, 100, 100);
drawWord(g, 40, Color.gray, "左键重新开始游戏", 200, 520);
break;
default:
}
}
倒计时函数设计
每一关设计游戏时间为20秒
boolean gameTime() {
int gameTime = 20;
long time = (endTime - startTime) / 1000;
if (time > gameTime) {
return true;
}
return false;
}
重新开始游戏函数
void reGame() {
level = 1;
goal = level * 10;
count = 0;
batteryNum = 3;
batteryState = false;
}
GUI界面对应程序文字样式
默认使用黑体
public static void drawWord(Graphics g, int size, Color color, String string, int x, int y) {
g.setColor(color);
g.setFont(new Font("黑体", Font.BOLD, size));
g.drawString(string, x, y);
}
}
碰撞检测其实就是判断红线的终点坐标是否落在物体所生成的矩形内,若在,则将该物体的isMove属性置为true。
七、个人博客链接https://blog.csdn.net/qq_50747725/article/details/122426640
https://blog.csdn.net/qq_57821790/article/details/122432442
八、脱离IDE运行链接:https://pan.baidu.com/s/1H7zdlBMJJeJzNymUQIJX1Q
提取码:1111



