🐇前言
在中秋国庆佳节来临之际,我特地为大家制作了一款极具节日氛围的小游戏——《兔饼大作战》。在这个拥有着浓浓年味的节日里,让我们一起来帮助可爱的🐇吃到更多的月饼,创造更高的得分吧!
在游戏中,我们可以通过控制🐇的方向键,让它顺畅地移动,并不断吃到食物以增加身体长度和得分。同时,🐇还会有吃到月饼的机会,获得更多的长度,但也需要注意月饼的存在时间,不要错过了哦~随着游戏的进行,兔子的运动速度和难度会逐渐增加,让我们来挑战更高的得分和更高的难度吧!
来吧,先亮个相,show time!
同时我已将游戏打包成了一个exe可执行文件,上传到了GitHub / Gitee,直接在Windows桌面中即开即玩,欢迎小伙伴踊跃试玩,摸鱼必备神器,被抓了就说自己开发的,正在做bug测试呢🙃。
🐇1. 游戏介绍
《兔饼大作战》是一款基于纯Java语言开发的小游戏(制作思路来自《贪吃蛇》);玩家需要控制兔子在游戏界面上收集食物,随着游戏的进行,难度逐渐增加,同时还有月亮障碍等玩法元素。
本文将详细介绍该游戏的制作思路、制作过程、核心实现方法及游戏玩法。
🐇2. 游戏玩法
玩家扮演一只爱吃月饼的兔子,在一个游戏界面中控制兔子进行移动,通过吃食物增长身体,获得得分,并挑战自己的最高分。同时在游戏过程中,还会出现月亮障碍物,如果吃了月亮,兔子会增加身体长度,但是会扣除当前分数,并且月亮只有存在十秒钟,过了时间后,月亮会消失。
🐇3. 制作思路
我先给大家分析一下制作这个游戏的整体思路:仅供参考
- 游戏界面:游戏界面包括静态的边框、动态的小兔子、食物和月亮等元素。
- 兔子的运动:通过方向键来控制兔子的运动方向,每次移动一个格子的距离,碰到边界会回到另一侧,碰到身体或者失败则game over!
- 食物的生成:食物随机掉落在游戏界面的某个位置,兔子通过碰到食物会获得得分,并重新随机掉落一个新的食物。
- 月亮的生成:随着游戏的进行,随机时间会出现月亮障碍,兔子吃掉月亮可以获得额外的”奖励“,但同时也会增加游戏难度。
- 游戏难度:随着游戏进展,难度逐渐增加,包括移动速度加快、食物价值增加、月亮出现时间缩短等。
🐇4. 制作过程
接下来我就来一步步实现这个小游戏。首先,我们需要准备游戏所需要的资源文件:
- 兔子、食物、月亮的图标文件(25x25像素大小的 png 格式文件)。
- 游戏背景音乐(可选)。
然后就可以开始coding啦,我们按照逻辑来依次实现游戏的各个部分。
🐰4.1 游戏界面设计
首先我们要设计游戏的界面,包括静态的边框、动态的小兔子、食物和月亮等元素。我们可以先定义游戏面板的大小,然后在paintComponent()
方法中绘制各个元素。
游戏面板大小: 850x600像素。
各个元素绘制方式:
- 游戏界面:绘制一个灰色背景的矩形,位置与大小通过常量定义。
- 食物:随机生成在游戏界面内的一个位置,用
ImageData.food
图标绘制在界面上。 - 月亮:随着游戏进程的进行,随机出现在游戏界面内,用ImageData.moon图标绘制在界面上。
- 小兔子:用
ImageData.right、left、up、down
四个方向的图标绘制在界面上,根据兔子的方向在paintComponent()
方法中判断绘制哪个图标。 - 得分、难度等级等游戏信息:用
g.drawString()
在界面上绘制。
🐰4.2 兔子的运动
兔子的运动实现方式比较简单,我们需要通过键盘监听来获取玩家的输入,通过判断按下的方向键来控制兔子的运动方向,每次移动一个格子的距离,碰到边界会回到另一侧,碰到身体或者失败则结束游戏。
在GamePanel
类中,我们定义以下变量:
length
:兔子的长度rabbitX
、rabbitY
:兔子每一节身体的坐标rabbitOrientation
:兔子的头部方向,初值为right
(向右)cheat
:作弊模式,是否免疫身体碰撞
其中,rabbitX
、rabbitY
数组存储了兔子每一节身体的坐标,初值为(100,100)
,即兔子的初始位置。每次移动,我们只需要先将身体的位置向前移动一格,然后再更新头部的位置即可。具体实现见actionPerformed()
方法。
🐰4.3 食物的生成
食物的生成比较简单,我们只需要随机生成在游戏界面内的一个位置,用ImageData.food
图标绘制在界面上,然后等待兔子碰到食物后重新生成一个新的食物即可。
在GamePanel类中,我们定义以下变量:
foodX
、foodY
:食物的坐标foodValue
:食物分数,初值为1
食物的生成通过init()
方法实现,游戏开始时调用一次,在其中生成随机的食物坐标。位置随机可以利用Java中的Random
类来实现,生成的坐标需要满足以下条件:
- X坐标在[25,850]之间,每隔25像素一个格子;
- Y坐标在[75,600]之间,每隔25像素一个格子。
在兔子碰到食物后,我们通过actionPerformed()
方法中的条件判断来判断是否吃到了食物,如果吃到,则更新得分,重新生成新的食物。
🐰4.4 月亮的生成
月亮的生成需要在兔子的长度大于5时,随机生成在游戏界面内的一个位置,用ImageData.moon
图标绘制在界面上。在兔子吃掉月亮后,需要重新生成食物,并隐藏月亮。
在GamePanel
类中,我们定义以下变量:
hasMoon
:月亮的状态,true表示月亮正在游戏界面上moonX
、moonY
:月亮的坐标,初值为(-50,-50)moonCountdown
:月亮出现后倒计时的时间,初值为10000(10秒)eatMoonAddLen
:吃掉月亮后增加的身体格数,初值为3。
月亮的生成和隐藏需要在actionPerformed()
方法中实现,判断月亮状态和倒计时即可。月亮出现时,通过随机生成的坐标用ImageData.moon
图标绘制在界面上。
在兔子吃掉月亮后,我们需要增加兔子的身体长度,并扣除一定的得分,然后重新生成新的食物,隐藏月亮。
🐰4.5 游戏难度的控制
游戏难度的控制实现方式比较简单,我们在actionPerformed()
方法中根据兔子的长度来判断游戏的难度等级,然后修改游戏移动速度、食物价值等参数即可。
在GamePanel
类中,我们定义以下变量:
rabbitSpeed
:兔子每次移动的速度level
:游戏难度等级,初值为1higtScore
:历史最高得分,初值为0。
在游戏难度等级升高时,我们需要通过setDelay()
方法改变定时器的延迟时间来控制兔子的移动速度。
🐰4.6 游戏状态的控制
游戏状态的控制包括游戏开始、暂停、失败等情况的判断和处理,以及历史最高得分的更新等问题。
🌛4.6.1 游戏开始和暂停
游戏开始和暂停是通过空格键来控制的,当玩家按下空格键时,判断当前游戏状态,如果是暂停状态,则将isStart
变量设置为true
,游戏开始;如果是游戏进行中,则将isStart
变量设置为false
,游戏暂停。
在GamePanel
类中,我们需要定义以下变量:
isStart
:游戏是否开始,初值为false
(暂停状态)
在键盘监听器中,我们需要监听空格键的按下事件,按下时改变isStart
的值并重新绘制界面。
protected class keyboardListener extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();//获得按下的键
if (keyCode == KeyEvent.VK_SPACE) {
if (isFail) {
//空格控制重新开始
isFail = false;
//更新历史最高分
if (score > higtScore) {
higtScore = score;
}
init();
} else {
//空格控制游戏暂停
isStart = !isStart; //isStart取反
}
repaint();
}
//其他按键的处理略...
}
}
🌛4.6.2 游戏失败和重新开始
游戏失败是指兔子碰到了游戏界面的边缘或者碰到了自己的身体,此时游戏状态变为失败状态,停止游戏并提示玩家。玩家可以按下空格键重新开始游戏。
在GamePanel
类中,我们需要定义以下变量:
isFail
:游戏是否失败,初值为false
higtScore
:历史最高得分,初值为0。
在actionPerformed()
方法中,检查兔子是否碰到了边缘或者身体,如果是,则将isFail
变量设置为true
,并停止游戏运行,然后更新历史最高得分和游戏状态,并重新绘制界面。
在键盘监听器中,我们需要监听空格键的按下事件,按下时判断是否处于游戏失败状态,如果是,则重新开始游戏。
protected class keyboardListener extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();//获得按下的键
if (keyCode == KeyEvent.VK_SPACE) {
if (isFail) {
//空格控制重新开始
isFail = false;
//更新历史最高分
if (score > higtScore) {
higtScore = score;
}
init();
} else {
//空格控制游戏暂停
isStart = !isStart;
}
repaint();
}
//其他按键的处理略...
}
}
🐰4.7 其他细节问题
在游戏的实现过程中,还有一些细节问题需要注意,比如键盘监听、兔子速度的控制、界面刷新等问题,这里留着日后慢慢啃。
🐰4.8 核心方法解读
如下介绍下游戏代码中比较核心的代码,方便同学们参考。
🌛4.8.1.init()
初始化游戏状态和兔子、食物等数据。在该方法中,我们可以初始化兔子的长度、头部坐标、方向、食物的坐标和分数,游戏状态和难度等级等。
🌛4.8.2.paintComponent(Graphics g)
在该方法中,我们可以绘制游戏面板、各元素,并展示游戏状态信息。
🌛4.8.3.actionPerformed(ActionEvent e)
该方法是定时器的事件处理方法,其中包含了游戏的核心逻辑:兔子的移动、吃食物、吃月饼、失败判断、修改速度等。
🌛4.8.4.keyboardListener
该内部类是键盘监听器,用于监听玩家的键盘输入,包括控制兔子的移动和游戏的暂停和重新开始等功能。
🐇5. 游戏演示
🐰5.1 制作应用程序
我为了同学们能更好的体验这个款小游戏,我历尽千辛,先是将项目打包成Jar包,后才把Jar打成了一个exe,随后我将它上传到了GitHub,希望小伙伴们踊跃试玩,别辜负我的一片良苦用心。
🐰5.2 启动游戏
双击[兔饼大作战.exe]文件即可启动游戏,随后会同时弹出两个窗口,小黑窗请不要关闭,缩小搁置即可,然弹出的另一个窗口便是游戏界面啦,示例如下:
🐰5.3 暂停界面
通过键盘按下空格键即可立马暂停游戏,再次敲击空格键则继续游戏,演示如下:
🐰5.4 死亡界面
本游戏中唯一会触发Game Over 特效的就是自己咬自己,所以我真已经尽力降低游戏难度啦。
🐰5.5 "奖励"界面
当身体长度达到了6,便会触发月亮掉落,拾一颗月亮,会触发扣分机制,总得分-3,身体长度+3。注意看右上角的长度值与当前得分变化。
🐰5.6 加速机制
随着长度的累加,会触发移动速度,这也是本游戏给玩家设置的第一道阻碍,毕竟移动速度越快越难控制自己咬自己。
🐇结束语 · 举杯邀月饮🥤
本小游戏利用Java
开发语言制作而成,使用Java面向对象的编程思想,采用定时器和键盘监听等技术,实现了一款拥有贪吃蛇的基本功能并在其上做了升级,并丰富了游戏的玩法。在制作过程中,需要注意游戏状态和数据的变化,以及各元素的位置和大小等细节。希望本小游戏能给大家带来乐趣,也欢迎大家模仿和扩展该项目。
如果你觉得这个小游戏有点儿意思,点个赞,鼓励一下bug菌,哈哈。
最后,提前祝愿所有的读者朋友们,中秋国庆双节快乐!身体康健!最重要的是一起升职又加薪啦。
---End
标注:游戏图标素材来源 阿里巴巴矢量图标库;游戏思路模仿自贪吃蛇,供大家玩儿图个乐呵。