用JAVA写贪吃蛇游戏 超详细注释及原理讲解
来源:互联网 发布:最好的中国象棋软件 编辑:程序博客网 时间:2024/05/29 08:31
snake.java
package snake;
import javax.swing.JFrame;
public class snake2 {
public static void main(String[] args) {
//框架三步骤
JFrame frame = new JFrame();
frame.setBounds(10,10,900,720);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//先建的框架 然后在框架上铺上画布 就是SnakePanel.java类
//后续的所有工作都在这个画布上画
SnakePanel panel = new SnakePanel();
frame.add(panel);
frame.setVisible(true);
}
}
SnakePanel.java
package snake2;
import java.awt.Color; // eclipse 用 shift+ctrl+O 自动添加包、类
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class SnakePanel extends JPanel implements KeyListener,ActionListener{
//图片导入方法: 直接拖住 然后添加到工程的文件夹中 这个方便 但是不规范
// 可以在工程文件下建立一个专门放图片的文件夹 我的是image 这样看起来清晰 但是路径要写清楚 文件夹/图片名
ImageIcon up = new ImageIcon(“image/up.png”);
ImageIcon down = new ImageIcon(“image/down.png”);
ImageIcon right = new ImageIcon(“image/right.png”);
ImageIcon left = new ImageIcon(“image/left.png”);
ImageIcon snake = new ImageIcon(“image/snake.png”);
ImageIcon food = new ImageIcon(“image/food.png”);
ImageIcon body = new ImageIcon(“image/body.png”);
//所有要用的变量都定义在一起 最好放在方法前面 方便查找int[] snakex = new int[750]; //放蛇的数组int[] snakey = new int[750];Random rand = new Random(); // 随机产生食物int foodx = rand.nextInt(34)*25+25; //放事物的数组int foody = rand.nextInt(24)*25+75;int len = 3; // 蛇身体的长度int score = 0; //游戏积分String fangxiang = "R"; //蛇头的方向boolean isStarted = false; //判断游戏是否开始 关系到后面的空格键事件以及 Timer是否开始boolean isFailed = false; //判断游戏是否失败 即蛇头是否撞到身体//蛇移动的原理:就是不断的重画 即下面的热paint()函数 重画的频率由timer控制 单位是毫秒Timer timer = new Timer(100,this); //控制蛇的移动的速度public SnakePanel() { //构造函数 即给类初始化 即运行工程后的初始状态 this.setFocusable(true); //选中焦点 即对画布 上的按钮起作用 this.addKeyListener(this); //键盘监听 即你按键盘的时候我们的程序有反映 setup(); //重置 初始化 timer.start(); //Timer类的启动 相当于定闹钟 然后工程开始repaint 蛇才能运动}public void paint(Graphics g) { //此函数相当于一支画笔 在panel画布上画各种东西(蛇 事物 文字等) this.setBackground(Color.white); snake.paintIcon(this, g, 25, 11); //上面导入的图片就是用paintIcon函数来画出来 这是在画标题图片 g.fillRect(25, 75, 850, 600); //填写指定的矩形 //画蛇头 if(fangxiang.equals("R")) { //键盘监听后对蛇头方向的判断后 这这里画出 right.paintIcon(this, g, snakex[0], snakey[0]); }else if(fangxiang.equals("L")) { left.paintIcon(this, g, snakex[0], snakey[0]); }else if(fangxiang.equals("U")) { up.paintIcon(this, g, snakex[0], snakey[0]); }else if(fangxiang.equals("D")) { down.paintIcon(this, g, snakex[0], snakey[0]); } //画蛇身体 for(int i=1;i<len;i++) { //身体的画发就是把body.png图片画在数组中 body.paintIcon(this, g, snakex[i], snakey[i]); } if(!isStarted) { //数据结构中判读出没开始 就在这里画出下面的东西 即出现一行提示字 g.setColor(Color.red);//每次画东西想要不懂的颜色 都要重新 占墨水 即重新给画笔设置颜色 g.setFont(new Font("宋体",Font.BOLD,30)); //同样 设置画笔的字体 g.drawString("按空格键开始游戏!", 300, 300);//然后画出文字 后面的300 300 是指文字出现的位置 } if(isFailed) { //数据结构判断失败了 就在这里画出下面的东西 每次画东西都是基于数据的判断 即这是画表面 g.setColor(Color.red); g.setFont(new Font("宋体",Font.BOLD,30)); g.drawString("游戏失败!", 300, 300); } food.paintIcon(this, g, foodx, foody); //画食物 g.setColor(Color.RED); //重置画笔 画分数表 g.setFont(new Font("arial",Font.BOLD,10)); g.drawString("Score:"+score, 800, 100); g.drawString("Length:"+len, 800, 120);}public void setup() { //重置初始化函数 len = 3; score = 0; isStarted = false; isFailed = false; fangxiang = "R"; //蛇头默认方向为右 snakex[0] = 100; //蛇刚出发的位置 snakey[0] = 100; snakex[1] = 75; snakey[1] = 100; snakex[2] = 50; snakey[2] = 100;}//这三个函数是在实现KeyListener类时生成的函数 作用是监听键盘 我们是需要用第二 即键盘按下时的反映@Overridepublic void keyTyped(KeyEvent e) { // TODO Auto-generated method stub}@Overridepublic void keyPressed(KeyEvent e) { //键盘按下时 工程需要的操作 int keyCode = e.getKeyCode(); //获取按键的keycode值 每个按键都有不同的值 if(keyCode == KeyEvent.VK_SPACE) { //判断按键是否为空格键 VK_SPACE就是空格键默认的值 if(isFailed) { setup(); //如果是空格键且游戏结束了 就调用这个函数重置初始化 }else { isStarted = !isStarted; //如果是空格键且游戏没结束了 判断变量变成相反量 } }else if(keyCode == KeyEvent.VK_UP && fangxiang !="D" ) { //如果不是空格键而是方向建 则蛇头变成相应的方向 fangxiang = "U"; }else if(keyCode == KeyEvent.VK_DOWN && fangxiang !="U") { fangxiang = "D"; }else if(keyCode == KeyEvent.VK_RIGHT && fangxiang !="L") { fangxiang = "R"; }else if(keyCode == KeyEvent.VK_LEFT && fangxiang !="R") { fangxiang = "L"; }}@Overridepublic void keyReleased(KeyEvent e) { // TODO Auto-generated method stub}@Overridepublic void actionPerformed(ActionEvent e) { //这个函数是在实现ActionListener类时生成的功能 当事件发生时,当事件发生时调用 //再定1个闹钟 事件开始是以闹钟响起开始 即 开始paint timer.start(); //先移动数据 只有数据发生变化了 画笔才能画出相应的画 if(isStarted && !isFailed) { for(int i=len;i>0;i--) { //蛇身体的移动 数据的变化 真正的移动在下面的repaint中实现 snakex[i] = snakex[i-1]; snakey[i] = snakey[i-1]; } if(fangxiang.equals("R")) { //蛇头的移动 数据的变化 真正的变化在下面的repaint 中的实现 snakex[0] = snakex[0]+25; if(snakex[0]>850) snakex[0] = 25; //四个if语句 判断蛇头是否超出画布 }else if(fangxiang.equals("L")) { snakex[0] = snakex[0]-25; if(snakex[0]<25) snakex[0] = 850; }else if(fangxiang.equals("U")) { snakey[0] = snakey[0]-25; if(snakey[0]<75) snakey[0] = 650; }else if(fangxiang.equals("D")) { snakey[0] = snakey[0]+25; if(snakey[0]>650) snakey[0] = 75; } if(snakex[0] == foodx && snakey[0] == foody) { //判断蛇是否吃到食物 len++; score++; foodx = rand.nextInt(34)*25+25;//食物出现的 x y坐标 在画布内 foody = rand.nextInt(24)*25+75; } for(int i=1;i<len;i++) { //判断蛇头是否撞到蛇身体 if(snakex[0]==snakex[i] && snakey[0]==snakey[i]) { isFailed = true; //如果撞到 判断游戏失败的变量变为真 即游戏失败 } } } //重画 repaint(); }
}
开始界面
结束界面
总结
1.所有的运动 图片都是基于数据的变换
2. 简单的操作就是数据操作变换个可视化呈现分开函数
3. 细节的推敲非常重要
- 用JAVA写贪吃蛇游戏 超详细注释及原理讲解
- 用java写的贪吃蛇游戏
- 用java写的贪吃蛇游戏
- 贪吃蛇游戏~~~c++代码全文。。。附有详细注释。。。。。。
- 以前用java写的贪吃蛇游戏
- 以前用java写的贪吃蛇游戏
- 用java的swing框架自己写贪吃蛇游戏
- java写的简易贪吃蛇游戏
- 用opencv3写的超详细注释的车牌检测
- python+opencv图像金字塔融合 (超详细讲解原理及代码讲解)
- Java贪吃蛇游戏
- Java贪吃蛇游戏
- java贪吃蛇游戏
- JS小游戏贪吃蛇+详细注释
- JS小游戏贪吃蛇+详细注释
- 关于用Java写的贪吃蛇游戏的一些感想
- C++手打游戏--<<贪吃蛇>>讲解
- 用java开发贪吃蛇游戏
- 2017多校-10
- Tree POJ
- 排序算法(1)—冒泡排序
- 网关、路由器、网桥,中继器,交换机的区别
- 死锁案例及查看方法
- 用JAVA写贪吃蛇游戏 超详细注释及原理讲解
- 算法系列——从尾到头打印链表(剑指offer)
- 2016-2017 ACM-ICPC, NEERC, Moscow Subregional Contest K. Knights of the Old Republic kruskal
- 【面试】HTTP中Get与Post的区别
- AS3 前端网页游戏系统的开发
- (十一)Spring Boot整合Mybatis使用druid实现多数据源自动切换
- HDU 6172 Array Challenge 找规律+矩阵快速幂
- SCARA 机器人概述
- vue标签属性条件渲染