JAVA实现贪吃蛇游戏的实践记录(四)

  • 一、问题分析报告:
  • 二、功能扩展报告:
  • 三、预期功能展望:
  • 四、程序代码展示:

本文链接

相关文章(一)

相关文章(二)

相关文章(三)


一、问题分析报告:

  • 上一期提出了问题优化和功能补充。
  • 通过测试发现程序有个一问题待优化:
    1:食物会生成出现在蛇当前所占有的位置上
  • 设置问题解决方案:
    1:随机生成食物位置坐标时增设不重合判断

二、功能扩展报告:

  • 增设了有毒食物,蛇吃掉poison食物后死亡,游戏失败
  • 将失败种类细分,增加wallFail、ownFail、poisonFail等失败的判定
  • 设置了游戏帮助提示,提供食物信息和按键操作
  • 设置了游戏系统托盘,游戏最小化时转入系统托盘,且托盘带有open/hide/exit等控制操作

三、预期功能展望:

  • 功能补充:
  1. 增设致幻食物
  2. 设置弹窗交互

四、程序代码展示:

1、程序的入口

StartGame.java

代码如下:

package snakegame4;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;//程序启动
public class StartGame4 {public static void main(String[] args) {//绘制静态窗口JFrame frame = new JFrame("贪吃蛇小游戏");//设置界面的宽高frame.setSize(965, 655);//屏幕中央弹出frame.setLocationRelativeTo(null);//窗口大小固定frame.setResizable(false);//关闭窗口时退出程序frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//添加窗口图标frame.setIconImage(Data4.Timage);//添加游戏面板frame.add(new GamePanel4());//设置窗体可见frame.setVisible(true);//如果平台支持系统托盘则设置系统托盘if (SystemTray.isSupported()) {//新建弹出菜单PopupMenu popupMenu = new PopupMenu();//新建菜单选项MenuItem openItem = new MenuItem("open");MenuItem hideItem = new MenuItem("hide");MenuItem exitItem = new MenuItem("exit");//设置open菜单监听openItem.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (!frame.isShowing()) {frame.setExtendedState(JFrame.NORMAL);frame.setVisible(true);}}});//设置hide菜单监听hideItem.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent actionEvent) {frame.setExtendedState(JFrame.ICONIFIED);}});//设置exit菜单监听exitItem.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.exit(0);}});//添加菜单项popupMenu.add(openItem);popupMenu.add(hideItem);popupMenu.add(exitItem);//调用构造器//图片/信息/菜单TrayIcon trayIcon = new TrayIcon(Data4.image, "贪吃蛇小游戏", popupMenu);//获得系统托盘SystemTray systemTray = SystemTray.getSystemTray();//自适应图片大小trayIcon.setImageAutoSize(true);//添加到系统托盘try {systemTray.add(trayIcon);} catch (AWTException e) {e.printStackTrace();}//窗口最小化事件监听frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowIconified(WindowEvent e) {frame.dispose();}});//鼠标点击托盘事件监听trayIcon.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON1 && !frame.isShowing()) {frame.setExtendedState(JFrame.NORMAL);frame.setVisible(true);}}});}}
}

2、程序的主体

GamePanel.java

代码如下:

package snakegame4;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;//游戏面板
public class GamePanel4 extends JPanel implements KeyListener, ActionListener {//一、基本属性//定义蛇int length; //蛇的长度//蛇的坐标int[] snakeX = new int[800];int[] snakeY = new int[800];String order; //方向,"R"(右),"L"(左),"U"(上),"D"(下);boolean isStart; //开始判断(默认暂停)boolean isFail; //死亡判断(默认存活)//细分失败种类判定boolean wallFail;boolean ownFail;boolean poisonFail;//初始化定时器Timer timer = new Timer(100, this);//定义食物//定义一随机数,用于概率生成不同食物int randomInt;//食物的坐标int foodX;int foodY;//实例化Random对象Random random = new Random();//设置积分系统int score; //积分int f = 50; //蓝豆50分int Df = 100; //红豆100分//有毒食物int poisonX;int poisonY;//二、初始化操作//定义构造器public GamePanel4() {init(); //调用初始化方法//获取键盘监听事件this.setFocusable(true); //对窗口设置键盘焦点this.addKeyListener(this); //添加监听器//启动定时器timer.start();}//生成食物坐标的方法public void foodUpdate() {//生成随机数(0~100)//用于概率生成不同食物//(0~20)(大积分),(20~100)(小积分)randomInt = (int) (Math.random() * 100);//随机生成食物/毒食物位置int cnt;do {//生成食物坐标foodX = 25 + 25 * random.nextInt(36);foodY = 50 + 25 * random.nextInt(22);poisonX = 100 + 25 * random.nextInt(30);poisonY = 100 + 25 * random.nextInt(16);//循环判定是否有两者坐标重合cnt = 0;for (int i = 0; i <= length; i++) {if (!((snakeX[i] == foodX && snakeY[i] == foodY) ||(snakeX[i] == poisonX && snakeY[i] != poisonY) ||(foodX == poisonX && foodY == poisonY))) { //只要有两者位置重合则不执行自加操作cnt++;}}} while (cnt <= length); //cnt小于等于length证明有重合现象,回到循环}//定义初始化方法public void init() {length = 3; //初始化蛇长(3节)score = 0; //积分清零//初始化失败判定isFail = false;poisonFail = false;wallFail = false;ownFail = false;//随机生成蛇头位置//25为最小单位snakeX[0] = 100 + 25 * random.nextInt(30);snakeY[0] = 100 + 25 * random.nextInt(16);//等概率生成蛇头方向//根据蛇头方向生成初始蛇身int r = (int) (Math.random() * 4);int a = snakeX[0];int b = snakeY[0];switch (r) {case 0:order = "R";snakeX[1] = a - 25;snakeY[1] = b;snakeX[2] = a - 50;snakeY[2] = b;snakeX[3] = a - 75;snakeY[3] = b;break;case 1:order = "L";snakeX[1] = a + 25;snakeY[1] = b;snakeX[2] = a + 50;snakeY[2] = b;snakeX[3] = a;snakeY[3] = b + 75;break;case 2:order = "U";snakeX[1] = a;snakeY[1] = b + 25;snakeX[2] = a;snakeY[2] = b + 50;snakeX[3] = a;snakeY[3] = b + 75;break;case 3:order = "D";snakeX[1] = a;snakeY[1] = b - 25;snakeX[2] = a;snakeY[2] = b - 50;snakeX[3] = a;snakeY[3] = b - 75;break;}foodUpdate(); //调用食物位置初始化方法}//三、画板:绘制操作@Overrideprotected void paintComponent(Graphics g) {//画界面super.paintComponent(g); //清屏操作this.setBackground(Color.white); //设置背景颜色//绘制游戏区域g.setColor(Color.black);g.fillRect(25, 50, 900, 550);//绘制帮助提示Data4.food.paintIcon(this, g, 125, -1);Data4.Dfood.paintIcon(this, g, 210, -1);Data4.poison.paintIcon(this, g, 300, -1);g.setFont(new Font("方正舒体", Font.BOLD, 20));g.drawString("食物列表:", 25, 20);//g.drawString("50分", 155, 20);g.drawString("100分", 240, 20);g.drawString("死亡", 330, 20);g.drawString("按键控制:(W/A/S/D)/(UP/LEFT/DOWN/RIGHT)=>(上/左/下/右)", 25, 45);g.drawRect(25, 0, 650, 25);g.drawRect(25, 25, 650, 25);//画积分g.setColor(Color.black); //设置字体颜色g.setFont(new Font("方正舒体", Font.BOLD, 25));g.drawString("分数:" + (score) + "分", 380, 20);g.drawString("长度:" + (length) + "节", 530, 20);//根据当前的方向(order)画蛇头switch (order) {case "R":Data4.right.paintIcon(this, g, snakeX[0], snakeY[0]);break;case "L":Data4.left.paintIcon(this, g, snakeX[0], snakeY[0]);break;case "U":Data4.up.paintIcon(this, g, snakeX[0], snakeY[0]);break;case "D":Data4.down.paintIcon(this, g, snakeX[0], snakeY[0]);break;}//画蛇身for (int i = 1; i < length; i++) {Data4.body.paintIcon(this, g, snakeX[i], snakeY[i]);}//画食物if (randomInt < 20) { //蓝豆(1/5)Data4.Dfood.paintIcon(this, g, foodX, foodY);} else { //红豆(4/5)Data4.food.paintIcon(this, g, foodX, foodY);}if (!poisonFail) { //非中毒死亡则显示有毒食物Data4.poison.paintIcon(this, g, poisonX, poisonY);}//交互设置//游戏开始提示语句(游戏暂停时且游戏未失败)if (!isStart && !isFail) {g.setColor(Color.white);g.setFont(new Font("方正舒体", Font.PLAIN, 50));g.drawString("按空格键开始游戏", 290, 330);}//游戏结束提示语句(游戏失败时)if (isFail) {//根据失败种类绘制失败提示g.setColor(Color.red);g.setFont(new Font("方正舒体", Font.PLAIN, 60));if (wallFail) {g.drawString("您撞到了墙壁,游戏结束", 140, 290);} else if (ownFail) {g.drawString("您撞到了自己,游戏结束", 140, 290);} else {g.drawString("您吃了毒食物,游戏结束", 140, 290);}g.setColor(Color.white);g.setFont(new Font("方正舒体", Font.PLAIN, 40));g.drawString("本次得分:" + (score) + "分,按空格键重新开始", 160, 400);isStart = false; //停止游戏}}//四、监听器:执行键盘操作@Override//键盘按下(未释放)public void keyPressed(KeyEvent e) {//接收键盘的输入int keyCode = e.getKeyCode();//若按下了空格键if (keyCode == KeyEvent.VK_SPACE) {//如果结束,按下空格键重新开始if (isFail) {init(); //重新做初始化}//按下空格键开始/暂停游戏isStart = !isStart;//刷新(重画)界面repaint();}//('W'/'S'/'A'/'D'键或'up'/'down'/'left'/'right'键)按键控制蛇头转向//防止蛇头反向转动if (isStart) { //防止游戏暂停时方向按键被有效监听if ((keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) && !order.equals("R")) {order = "L";} else if ((keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) && !order.equals("L")) {order = "R";} else if ((keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_W) && !order.equals("D")) {order = "U";} else if ((keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) && !order.equals("U")) {order = "D";}}}//五、定时器:执行定时操作@Overridepublic void actionPerformed(ActionEvent e) {//若游戏处于开始状态(蛇发生移动)if (isStart) {//蛇身移动//保留第length个蛇身的坐标for (int i = length; i > 0; i--) {snakeX[i] = snakeX[i - 1];snakeY[i] = snakeY[i - 1];}//蛇头移动switch (order) {case "R":snakeX[0] += 25;break;case "L":snakeX[0] -= 25;break;case "U":snakeY[0] -= 25;break;case "D":snakeY[0] += 25;break;}//游戏失败判定//蛇头碰到墙后失败(判定蛇头坐标是否在墙外)if (snakeX[0] > 900 || snakeX[0] < 25 || snakeY[0] < 50 || snakeY[0] > 575) {//判定为失败isFail = true;wallFail = true;}//蛇头碰到蛇身后失败(循环判定蛇头坐标是否与任一节蛇身重合)for (int i = 1; i < length; i++) {if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {//判定为失败isFail = true;ownFail = true;break;}}//游戏失败后对蛇体展示优化if (isFail) {snakeX[0] = snakeX[1];snakeY[0] = snakeY[1];snakeX[1] = snakeX[length];snakeY[1] = snakeY[length];}//蛇吃到毒食物(坐标重合)后游戏失败if (snakeX[0] == poisonX && snakeY[0] == poisonY) {isFail = true;poisonFail = true;}//蛇吃到食物(坐标重合)后增长/积分if (snakeX[0] == foodX && snakeY[0] == foodY) {length++; //蛇身长度加一//根据随机数判断生成的食物if (randomInt < 20) {score += Df;} else {score += f;}foodUpdate(); //调用食物位置初始化方法}//刷新(重画)界面repaint();}//启动定时器timer.start();}@Overridepublic void keyTyped(KeyEvent keyEvent) {}@Overridepublic void keyReleased(KeyEvent keyEvent) {}
}

3、存放图片资源

Data.java

代码如下:

package snakegame4;import javax.swing.*;
import java.awt.*;public class Data4 {//导入素材图片//窗口图标public static Image Timage = new ImageIcon(Data4.class.getResource("/resources4/Thetitle4.jpg")).getImage(); //title//托盘图标public static Image image = Toolkit.getDefaultToolkit().getImage(Data4.class.getResource("/resources4/Thetitle4.jpg")); //tray//蛇头图片public static ImageIcon up = new ImageIcon(Data4.class.getResource("/resources4/up4.jpg")); //上public static ImageIcon left = new ImageIcon(Data4.class.getResource("/resources4/left4.jpg")); //左public static ImageIcon right = new ImageIcon(Data4.class.getResource("/resources4/right4.jpg")); //右public static ImageIcon down = new ImageIcon(Data4.class.getResource("/resources4/down4.jpg")); //下//蛇身图片public static ImageIcon body = new ImageIcon(Data4.class.getResource("/resources4/body4.jpg")); //body//食物图片public static ImageIcon food = new ImageIcon(Data4.class.getResource("/resources4/food4.jpg")); //蓝豆public static ImageIcon Dfood = new ImageIcon(Data4.class.getResource("/resources4/Dfood4.jpg")); //红豆public static ImageIcon poison = new ImageIcon(Data4.class.getResource("/resources4/poison4.jpg")); //黄豆
}

【JAVA】贪吃蛇的初步实现(四)相关推荐

  1. 【JAVA】贪吃蛇的初步实现(五)

    JAVA实现贪吃蛇游戏的实践记录(五)[完结] 一.总结: 二.功能扩展报告: 三.预期功能展望: 四.游戏效果展示: 五.程序代码展示: 本文链接 相关文章(一) 相关文章(二) 相关文章(三) 相 ...

  2. java贪吃蛇课程设计报告_java贪吃蛇课程设计报告().doc

    java贪吃蛇课程设计报告() <Java应用开发> 课程设计报告 题 目: JAVA小游戏 - 贪吃蛇 指导老师: 姓 名: 专 业: 班 级: 日 期: 目 录 一.系统总体设计1 ( ...

  3. Java 贪吃蛇 最简易地实现方法 超简短代码实现 (附源码 详解)

      分享一个我刚刚写的贪吃蛇小游戏,非常简短的代码实现方法.这可能是全网最简单实现方法,效果图如下: ps 最新贪吃蛇源码+教学视频+论文下载 java贪吃蛇  有多简短呢 ? 上代码!!   一共四 ...

  4. Java 贪吃蛇游戏引言

    欢迎关注公众号: 贪吃蛇小游戏是一款十分经典的小游戏,适合用于新手的练习,花了近两个月的时间,终于可以运行出比较完善的贪吃蛇了,相比于CSDN中的大神,花个几天的时间就可以做出Java版本的贪吃蛇小游 ...

  5. 手把手教你做一个Java贪吃蛇小游戏

    大家好,我是孙不坚1208,这篇博客给大家分享一下:如何做一个贪吃蛇小游戏(Java版)的exe应用程序,希望能给需要帮助的朋友带来方便. 手把手教你做一个Java贪吃蛇小游戏的exe应用程序 一.J ...

  6. java贪吃蛇系统架构_java贪吃蛇游戏框架搭建

    java贪吃蛇游戏框根据面向对象的思想建立蛇类.食物类.周围石头类.面板类.控制中心类.监听器类.组建类. Food.java public class Food { //蛇是否吃到了食物方法 pub ...

  7. 【JAVA】贪吃蛇的初步实现(一)

    JAVA实现贪吃蛇游戏的实践记录(一) 一.前言: 二.实现基本功能: 三.预期功能展望: 四.程序代码展示: 本文链接 一.前言: 贪吃蛇游戏是一款非常大众化的小游戏.整个游戏的任务很简单,就是通过 ...

  8. 【JAVA】贪吃蛇的初步实现(三)

    JAVA实现贪吃蛇游戏的实践记录(三) 一.问题分析报告: 二.功能扩展报告: 三.预期功能展望: 四.程序代码展示: 本文链接 相关文章(一) 相关文章(二) 一.问题分析报告: 上一期实现了贪吃蛇 ...

  9. 【JAVA】贪吃蛇的初步实现(二)

    JAVA实现贪吃蛇游戏的实践记录(二) 一.功能扩展报告: 二.预期功能展望: 三.程序代码展示: 本文链接 相关文章(一) 一.功能扩展报告: 使蛇体能够发生移动 按键控制蛇体的转向 游戏的启止控制 ...

最新文章

  1. php 生成动态键值 数组_你的PHP项目遇到性能问题了吗?看完这篇性能分析恍然大悟...
  2. 4、变量和方法被static和final两个关键字修饰,为什么这么做?
  3. C#_动态获取鼠标位置的颜色
  4. 使用pyinstaller打包python_使用pyinstaller打包Python项目,python
  5. RabbitMQ的Work能者多劳模式
  6. Vue 父子组件间的通信
  7. 【ElasticSearch】Es 源码之 MonitorService 源码解读
  8. [PyTorch] 基于python和pytorch的多项式回归
  9. 98五笔86五笔及五笔字型口诀字根表
  10. [笔记]unity渲染相关各种方案总结
  11. HDLC和PPP协议的配置
  12. SQL 中文首字母提取与自定义排序
  13. 混淆矩阵、ROC、AUC 学习记录
  14. 1U,2U,3U,4U机箱面板,U的含义
  15. 打孔的问题和打孔的位置
  16. markdown中插入数学公式
  17. git版本管理,有这一篇就够了(后端开发人员必备技能)
  18. 【杂谈】我的书籍推荐
  19. eclipse的常用操作
  20. 支持居者有其屋,支持房产税出台与落地。

热门文章

  1. STM32学习之串口采用DMA收发数据:需要利用状态机加DMA加串口
  2. 毕业设计-基于机器学习的恶意域名检测系统
  3. 解决Ubuntu里Chrome浏览器打开慢/卡死现象
  4. Codeforces Gym 100114 H. Milestones 离线树状数组
  5. arguments函数
  6. 在拆下一切之后,我好像找到了 Reno 把 10 倍混合光学变焦不凸起塞入了手机的秘密...
  7. win7下显示文件后缀的方法
  8. 0基础学Mysql:mysql入门视频教程!
  9. threejs导入模型为黑色原因
  10. CTO如何帮助业务?