我正在参加中秋创意投稿大赛,详情请看:中秋创意投稿大赛
前言
当我看到中秋创意投稿大赛的时候,我一开始的想法就是做个中秋相关的小游戏。经过我的冥思苦想,最终确立了游戏的内容是接月饼。
跟我一起看一下,我是如何实现这个接月饼小游戏的吧!
tips:以下代码均已在Github上开源:Java接月饼游戏
一、游戏内容
接月饼小游戏的内容主要分为以下两个部分:
- 场景和物体
- 具体玩法
场景和物体
接月饼设定在一个星空中,所以背景就是一张星空的图片,如下所示:
游戏中的物体有 嫦娥、月亮、月饼三种,图片如下所示:
游戏整体的效果如下所示:
具体玩法
嫦娥:作为游戏中的角色,供玩家来移动
月亮:游戏中的障碍物,如果嫦娥在移动的过程中碰到了月亮,则游戏停止
月饼:游戏中的得分道具,如果嫦娥在移动的过程中碰到了月饼,则分数 +1
玩家可以操控嫦娥来吃月饼,直到碰到了月亮,游戏结束并提示中秋快乐提示语和吃到的月饼个数
试玩动图
试玩效果的动图如下所示:
二、实现思路
理论上讲这个想法做一个 H5 小游戏是非常好的,还可以在线试玩。但是考虑到不会利用 JS 和 CSS 来制作动画效果,故此方案弃用。
经过一番思考,我想到了 Java 中可以使用 Swing 来进行图形绘制,那么实现动画效果也并非难事了。故最终选择了 Swing 来实现这个小游戏。
实现的大致思路分为以下几个部分:
嫦娥可以看做一个方块,随着方向键←和→而移动月亮和月饼都可以看做一个圆,从上向下移动,即从y = 0移动到y = Height- 当
嫦娥碰到月亮时游戏结束,当嫦娥碰到月饼时分数+1
代码实现
Moon月亮类
/**
* 障碍物-月亮,碰到会死亡
*/
public class Moon extends BaseGameObj {
private int speed = 10;
public Moon(int x, int y, String imageFile) {
super(x, y, imageFile, BaseGameObj.CIRCLE);
}
public void move() {
setY(y += speed);
}
// getter and setter
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
}
Cake月饼类
/**
* 得分物体-月饼,碰到加一分
*/
public class Cake extends BaseGameObj {
private int speed = 5; // 月饼跑慢一点,利于得分
public Cake(int x, int y, String imageFile) {
super(x, y, imageFile, CIRCLE);
}
public void move() {
++speed;
setY(y += speed);
}
// getter and setter
public int getSpeed() {
return speed;
}
}
ChangE嫦娥类
public class ChangeE extends BaseGameObj {
private final int frameWith;
public ChangeE(int x, int y, String imageFile, int frameWith) {
super(x, y, imageFile, BaseGameObj.RECTANGLE);
this.frameWith = frameWith;
}
public void move(int deltaX)
{
// 判断是否会超出左右边界
int nextX = getX() + deltaX;
if (nextX + getWidth() > frameWith) {
nextX = frameWith - getWidth();
} else if (nextX < 0) {
nextX = 0;
}
setX(nextX);
}
}
JPanel面板中绘制图像的主要代码
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// 绘制背景
ImageIcon icon=new ImageIcon(Thread.currentThread().getContextClassLoader().getResource("background.png"));
Image img=icon.getImage();
g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
// 绘制玩家
g.drawImage(myChangeE.getImage(), myChangeE.getX(), myChangeE.getY(), this);
// 绘制月亮
for(Moon moon : moons) {
g.drawImage(moon.getImage(), moon.getX(), moon.getY(), this);
}
// 绘制月饼
for (Cake cake : cakes) {
g.drawImage(cake.getImage(), cake.getX(), cake.getY(), this);
}
}
- 游戏逻辑的主要代码
当月亮移动到了屏幕外,则移除该月亮
当月饼移动到了屏幕外,则移除该月饼
如果列表为空则再添加两个月亮和一个月饼
/**
* 更新窗口
*/
private void updateFrame() {
ticks++;
for(int i = 0; i < moons.size(); i++)
{
Moon moon = moons.get(i);
if(ticks % 25 == 0 && moon.getSpeed() < 10)
{
moon.setSpeed(moon.getSpeed() + 2);
}
}
Iterator<Moon> moonIterator = moons.iterator();
while (moonIterator.hasNext()) {
Moon moon = moonIterator.next();
// 超出屏幕
if(moon.getY() > HEIGHT) {
moonIterator.remove();
} else
moon.move();
}
Iterator<Cake> cakeIterator = cakes.iterator();
while (cakeIterator.hasNext()) {
Cake cake = cakeIterator.next();
// 超出屏幕
if(cake.getY() > HEIGHT) {
cakeIterator.remove();
} else
cake.move();
}
if(moons.size() == 0) {
addMoonAndCake();
}
}
判断嫦娥是碰到了月亮,如果碰到了月亮,则游戏结束并提示中秋快乐!
判断嫦娥是碰到了月饼,如果碰到了则让分数+1,并移除该月饼。
private boolean checkCollision() {
Rectangle rectangle = (Rectangle) changeE.getShape();
for(Moon moon : moons) {
Ellipse2D circle = (Ellipse2D) moon.getShape();
// 判断是否与圆形相撞
if (circle.intersects(rectangle)) {
gameOver = true;
}
}
Iterator<Cake> cakeIterator = cakes.iterator();
while (cakeIterator.hasNext()) {
Cake cake = cakeIterator.next();
Ellipse2D circle = (Ellipse2D) cake.getShape();
if (circle.intersects(rectangle)) {
score ++; // 得分
cakeIterator.remove();
}
}
return gameOver;
}
三、总结
其实这个游戏更多的是提供了一种想法,可完善的地方还有很多。
感谢你可以看到这里,非常荣幸能够帮助到你!❤