贪吃蛇小游戏

在B站看视频的时候,看到下面这个视频就比较感兴趣,跟着手动做了一遍,写下这篇博客,

     【狂神说Java】一小时开发贪吃蛇游戏  https://www.bilibili.com/video/BV1HE41127CV?p=1 

最终游戏的界面长这个(都是画图做的图片,能力有限)

   具体的步骤,可以参照上面的视频听一下,简单易懂,

游戏规则:小蛇初始长度为3,可以上下左右四个方向移动,吃到蓝色的食物,身体长度加一,分数加10,

可以穿过自己的身体,也可以穿过墙壁,(没有死亡,因为触碰身体就死掉的话很不爽,也有这个功能,只不过注释掉了)

      贪吃蛇小游戏

玩了一会,之后的界面

      贪吃蛇小游戏

之前使用IDEA写的代码,但是一直说的激活码失效了,一直自动退出,就很气,改用eclipse了 

下面开始说一下,编写的步骤:

   1. 首先创建一个简单的java项目 File -> 右键 - > New -> Project 

     贪吃蛇小游戏

2.创建以下目录

      贪吃蛇小游戏

3,把相关的图片添加到此文件夹下

       贪吃蛇小游戏

4. 创建一个 StartGames 类,用来绘制窗口

     贪吃蛇小游戏

 1 package com.wang.snake;
 2 
 3 import javax.swing.*;
 4 
 5 public class StartGames {
 6     public static void main(String[] args) {
 7         // 1.绘制一个静态窗口
 8         JFrame frame = new JFrame("贪吃蛇小游戏");
 9         // 2.设置界面的大小
10         frame.setBounds(100,10,910,720);
11         // 3.设置窗口不可调整大小
12         frame.setResizable(false);
13         // 4.“X”的关闭事件,关闭窗口
14         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
15         // 5.把面板添加到窗口里
16         frame.add(new GamePanel());
17         // 6.让窗口可以展示
18         frame.setVisible(true);
19     }
20 }

5.创建Data类,获取添加的图片信息

贪吃蛇小游戏

 1 package com.wang.snake;
 2 
 3 import javax.swing.*;
 4 import java.net.URL;
 5 
 6 /**
 7  * 存放数据
 8  */
 9 public class Data {
10 
11     // 获取标题栏图片的相对路径
12     public static URL headerURL = Data.class.getResource("/statics/header.png");
13     // 转换成图片
14     public static ImageIcon header = new ImageIcon(headerURL);
15 
16     // 获取小蛇的头部图片
17     public static URL upURL = Data.class.getResource("/statics/up.png");
18     public static URL rightURL = Data.class.getResource("/statics/right.png");
19     public static URL downURL = Data.class.getResource("/statics/down.png");
20     public static URL leftURL = Data.class.getResource("/statics/left.png");
21     public static ImageIcon upHeader = new ImageIcon(upURL);
22     public static ImageIcon rightHeader = new ImageIcon(rightURL);
23     public static ImageIcon downHeader = new ImageIcon(downURL);
24     public static ImageIcon leftHeader = new ImageIcon(leftURL);
25 
26     // 获取小蛇的身体图片
27     public static URL bodyURL = Data.class.getResource("/statics/body.png");
28     public static ImageIcon body = new ImageIcon(bodyURL);
29 
30     // 获取食物的图片
31     public static URL foodURL = Data.class.getResource("/statics/food.png");
32     public static ImageIcon food = new ImageIcon(foodURL);
33 
34 }

 6.创建GamePanel类,绘制界面,包含了标题块,游戏块,以及小蛇的移动等功能的实现类

贪吃蛇小游戏

 

  1 package com.wang.snake;
  2 
  3 import javax.swing.*;
  4 import java.awt.*;
  5 import java.awt.event.ActionEvent;
  6 import java.awt.event.ActionListener;
  7 import java.awt.event.KeyEvent;
  8 import java.awt.event.KeyListener;
  9 import java.util.Iterator;
 10 import java.util.Random;
 11 
 12 public class GamePanel extends JPanel implements KeyListener, ActionListener {
 13 
 14     // 游戏是否开始flag
 15     boolean isStart = false;
 16     // 游戏是否失败flag
 17     boolean isFail = false;  
 18  
 19     //定义一个记分系统
 20     int score;
 21 
 22     // 定义一个小蛇
 23     String fx;                      // 定义小蛇头部的朝向
 24     int length;                    // 小蛇的长度
 25     int[] snakeX = new int[600];   // 小蛇的X坐标
 26     int[] snakeY = new int[500];   // 小蛇的Y坐标
 27 
 28     // 定义一个食物
 29     int foodX;   // 食物的X坐标
 30     int foodY;   // 食物的Y坐标
 31     // 随机数的对象
 32     Random random = new Random();
 33 
 34     // 定义一个定时器
 35     Timer timer = new Timer(100,this);
 36 
 37     //创建构造器,调用init方法,
 38     public  GamePanel(){
 39         // 小蛇的初始化
 40         init();
 41 
 42         // 获取键盘的监听事件
 43         // 获取焦点,默认是不获取焦点的
 44         this.setFocusable(true);
 45         // 添加监听
 46         this.addKeyListener(this);
 47         // 启动定时器
 48         timer.start();
 49     }
 50 
 51     // 小蛇和食物的初始化的长度及位置
 52     public void init(){
 53         // 记分的初期值设置为0
 54         score = 0;
 55         
 56         // 小蛇的长度是3个,头部位置在X:100,Y:100的坐标处,朝向右
 57         fx = "R";
 58         length = 3;
 59         snakeX[0] = 100;
 60         snakeY[0] = 100;
 61         // 身体部分的坐标,第一部分的位置在X:75,Y:100的坐标处,
 62         snakeX[1] = 75;
 63         snakeY[1] = 100;
 64         // 第二部分的位置在X:50,Y:100的坐标处,
 65         snakeX[2] = 50;
 66         snakeY[2] = 100;
 67 
 68         // 食物的初期的位置随机的坐标,
 69         foodX = 25 + 25 * random.nextInt(34);
 70         foodY = 75 + 25 * random.nextInt(24);
 71     }
 72 
 73     // Graphics 画笔
 74     // 面板:画界面,画小蛇
 75     @Override
 76     protected void paintComponent(Graphics g) {
 77         // 调用父类方法,清屏
 78         super.paintComponent(g);
 79 
 80         // 设置面板背景颜色(黑色)
 81         this.setBackground(Color.white);
 82 
 83         // 绘制头部的标题栏
 84         Data.header.paintIcon(this,g,25,10);
 85         
 86         // 绘制游戏区域
 87         g.fillRect(25,75,850,600);
 88 
 89         // 创建一个静态的小蛇
 90         if (fx.equals("R")){
 91             Data.rightHeader.paintIcon(this,g,snakeX[0], snakeY[0]);
 92         } else if (fx.equals("L")){
 93             Data.leftHeader.paintIcon(this,g,snakeX[0], snakeY[0]);
 94         } else if (fx.equals("U")){
 95             Data.upHeader.paintIcon(this,g,snakeX[0], snakeY[0]);
 96         } else if (fx.equals("D")){
 97             Data.downHeader.paintIcon(this,g,snakeX[0], snakeY[0]);
 98         }
 99 
100         // 通过for循环,创建小蛇的身体部分
101         for (int i = 1; i < length; i++){
102             Data.body.paintIcon(this,g,snakeX[i], snakeY[i]);
103         }
104 
105         // 把食物添加到窗口里
106         Data.food.paintIcon(this,g,foodX, foodY);
107 
108         // 游戏开始提示:是否开始游戏
109         if (isStart == false){
110             // 提示文字的属性,
111             g.setColor(Color.white);
112             g.setFont(new Font("微软雅黑",Font.BOLD,40));
113             g.drawString("按下空格开始游戏",300,300);
114         }
115         
116         // 游戏失败提示:游戏失败
117         if (isFail){
118             // 提示文字的属性,
119             g.setColor(Color.red);
120             g.setFont(new Font("微软雅黑",Font.BOLD,40));
121             g.drawString("游戏失败,按下空格重新开始游戏",200,300);
122         }
123         
124         // 记分提示文字的属性,
125         g.setColor(Color.white);
126         g.setFont(new Font("微软雅黑",Font.BOLD,18));
127         g.drawString("长度:" + length,750,33);
128         g.drawString("分数:" + score,750,55);
129     }
130 
131     /**
132      * 接受键盘的输入,进行监听
133      * @param e
134      */
135     @Override
136     public void keyPressed(KeyEvent e) {
137         // 获取键盘按下的是哪一个键
138         int keyCode = e.getKeyCode();
139 
140         // 如果按下的是空格键,就启动或者暂停
141         if (keyCode == KeyEvent.VK_SPACE){
142             // 如果游戏失败
143             if (isFail) {
144                 // 游戏重新开始
145                 isFail = false;
146                 // 重新初始化游戏
147                 init();
148             } else {
149                 // 暂停游戏
150                 isStart = !isStart;
151             }        
152 
153             // 刷新界面
154             repaint();
155         }
156 
157         // 判断键盘按下的上下左右键,控制小蛇的走向
158         if (keyCode == KeyEvent.VK_LEFT) {
159             fx = "L";
160         } else if (keyCode == KeyEvent.VK_RIGHT){
161             fx = "R";
162         }else if (keyCode == KeyEvent.VK_UP) {
163             fx = "U";
164         }else if (keyCode == KeyEvent.VK_DOWN) {
165             fx = "D";
166         }
167 
168     }
169 
170     /**
171      * 定时器,监听事件,执行定时操作
172      * @param e
173      */
174     @Override
175     public void actionPerformed(ActionEvent e) {
176 
177         // 如果游戏处于开始状态,并且游戏没有结束,小蛇就移动
178         if (isStart && isFail == false){
179 
180             // 除了头部,身体都跟着往右移动
181             for (int i = length - 1; i > 0; i--) {
182                 snakeX[i] = snakeX[i-1];
183                 snakeY[i] = snakeY[i-1];
184             }
185 
186             // 通过控制方向,移动头部
187             if (fx.equals("R")){
188                 // 头部向右移动一步
189                 snakeX[0] = snakeX[0] + 25;
190                 // 如果已经到达边界,则从最右侧重新开始
191                 if (snakeX[0] > 850){
192                     snakeX[0] = 25;
193                 }
194             } else if (fx.equals("L")){
195                 // 头部向左移动一步
196                 snakeX[0] = snakeX[0] - 25;
197                 // 如果已经到达边界,则从最右侧重新开始
198                 if (snakeX[0] < 25){
199                     snakeX[0] = 850;
200                 }
201             } else if (fx.equals("U")){
202                 // 头部向左移动一步
203                 snakeY[0] = snakeY[0] - 25;
204                 // 如果已经到达边界,则从最右侧重新开始
205                 if (snakeY[0] < 75){
206                     snakeY[0] = 650;
207                 }
208             } else if (fx.equals("D")){
209                 // 头部向左移动一步
210                 snakeY[0] = snakeY[0] + 25;
211                 // 如果已经到达边界,则从最右侧重新开始
212                 if (snakeY[0] > 650){
213                     snakeY[0] = 75;
214                 }
215             }
216 
217             //System.out.println("snakeX = "+snakeX[0]+" foodX="+foodX +"////snakeY = "+snakeY[0]+" foodY="+foodY);
218             // 判断小蛇的头的坐标和食物的坐标重合的情况下
219               if (snakeX[0] == foodX && snakeY[0] == foodY)
220             {
221                 // 小蛇的身体长度加1
222                 length ++ ;
snakeX[length-1] = snakeX[length-2] * 2 - snakeX[length-3]; snakeY[length-1] = snakeY[length-2] * 2 - snakeY[length-3];
223 224 // 每当吃掉一个食物,积分+10 225 score = score + 10; 226 227 // 生成新的食物 228 foodX = 25 + 25 * random.nextInt(34); 229 foodY = 75 + 25 * random.nextInt(24); 230 } 231 232 // 结束判断:头和身体有接触,则游戏失败 233 //for (int i = 1; i < length; i++) { 234 // if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) { 235 // // isFail = true; 236 // 237 // } 238 //}
239 // 刷新界面 240 repaint(); 241 } 242 // 定时器启动 243 timer.start(); 244 } 245 246 /** 247 * 键盘按下, 248 * @param e 249 */ 250 @Override 251 public void keyTyped(KeyEvent e) { 252 253 } 254 255 /** 256 * 257 * @param e 258 */ 259 @Override 260 public void keyReleased(KeyEvent e) { 261 262 } 263 264 265 }

 贪吃蛇小游戏

 

贪吃蛇小游戏

上一篇:什么是事务?事务的四个特征(ACID)


下一篇:elementui el-select显示value不显示label