小游戏项目-贪吃蛇

贪吃蛇

项目结构

 

 

 StartGame

复制代码
 1 package com.luckylu.gui.snake;
 2 
 3 import javax.swing.*;
 4 
 5 public class StartGame {
 6     public static void main(String[] args) {
 7         JFrame jframe = new JFrame();
 8         jframe.setTitle("曈曈爸的小游戏-贪吃蛇");
 9         jframe.setBounds(100,100,900,770);  //窗口位置&大小
10         jframe.setResizable(false);  //窗口不可调
11         jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //关闭窗口
12         jframe.setVisible(true); // 可见
13         jframe.add(new GamePanel()); //加载GamePanel类
14     }
15 
16 }
复制代码

Data

复制代码
 1 package com.luckylu.gui.snake;
 2 
 3 import javax.swing.*;
 4 import java.net.URL;
 5 
 6 //数据中心
 7 public class Data {
 8 
 9     //相对路径  tx.jpg
10     //绝对路径   /  相当于当前的项目
11     public static URL headerURL = Data.class.getResource("statics/header.png");
12     public static ImageIcon header = new ImageIcon(headerURL);
13     public static URL upURL = Data.class.getResource("statics/up.png");
14     public static URL downURL = Data.class.getResource("statics/down.png");
15     public static URL leftURL = Data.class.getResource("statics/left.png");
16     public static URL rightURL = Data.class.getResource("statics/right.png");
17     public static ImageIcon up = new ImageIcon(upURL);
18     public static ImageIcon down = new ImageIcon(downURL);
19     public static ImageIcon left = new ImageIcon(leftURL);
20     public static ImageIcon right = new ImageIcon(rightURL);
21     public static URL bodyURL = Data.class.getResource("statics/body.png");
22     public static ImageIcon body = new ImageIcon(bodyURL);
23     public static URL foodURL = Data.class.getResource("./statics/food.png");
24     public static ImageIcon food = new ImageIcon(foodURL);
25     
26 }
复制代码

GamePanel

复制代码
  1 package com.luckylu.gui.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.Random;
 10 
 11 // 画板 ,执行监听器,按键监听KeyListener,事件监听ActionListener
 12 public class GamePanel extends JPanel implements KeyListener, ActionListener {
 13 
 14     // 定义蛇的数据结构
 15     int length;  //蛇的长度;
 16     int[] snakeX = new int[600]; //蛇的x坐标
 17     int[] snakeY = new int[500];  // 蛇的y坐标
 18     String direction; // 定义方向
 19 
 20     //定义食物的坐标
 21     int foodX;
 22     int foodY;
 23     Random random= new Random();  //定义一个随机数
 24 
 25     //定义成绩
 26     int score;  //
 27 
 28 
 29 
 30     //游戏当前状态
 31     boolean isStart = false; // 定义布尔值 默认停止
 32     boolean isFail = false; // 定义布尔值 默认不失败
 33 
 34 
 35     //定时器,以毫米为单位
 36     Timer timer = new Timer(200,this);  //100毫米执行一次
 37 
 38     //构造器
 39     public GamePanel() {
 40         init();
 41         //获取焦点和键盘事件
 42         this.setFocusable(true); //获得焦点事件:鼠标激活;
 43         this.addKeyListener(this); // 获得当前类的键盘监听;
 44         timer.start(); // 游戏一开始定时器就启动
 45 
 46     }
 47 
 48     //初始化
 49     public void init(){
 50         //小蛇
 51         length = 3;
 52         snakeX[0]=150;snakeY[0]=150; //
 53         snakeX[1]=125;snakeY[1]=150;  //身体1
 54         snakeX[2]=100;snakeY[2]=150;  //身体2
 55         direction = "R";  //初始方向为右
 56         //食物
 57         foodX = 25 + 25 * random.nextInt(33);  // 随机数的边界框内 850/25-1
 58         foodY = 125 + 25 * random.nextInt(23);  // 随机数的边界框内 600/25-1
 59         score = 0;
 60     }
 61 
 62     // 画笔 画板上画
 63     //alt + insert  ==>  ctrl + o
 64     @Override
 65     protected void paintComponent(Graphics g) {  //调用画笔
 66         super.paintComponent(g);  //  清屏
 67         this.setBackground(Color.white);
 68         Data.header.paintIcon(this,g,25,25); // 头部广告栏
 69         g.fillRect(25,125,850,600);//默认游戏界面
 70 
 71         //画食物
 72         Data.food.paintIcon(this,g,foodX,foodY);
 73 
 74         //把小蛇画上去
 75         //头部
 76         if(direction.equals("R")) {
 77             Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);  //头-右
 78         }else if(direction.equals("U")) {
 79             Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);  //头-右
 80         }else if(direction.equals("D")) {
 81             Data.down.paintIcon(this, g, snakeX[0], snakeY[0]);  //头-右
 82         }else if(direction.equals("L")) {
 83             Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);  //头-右
 84         }
 85         // 身体
 86          /*  初始小蛇的身体[静态]
 87         Data.body.paintIcon(this,g,snakeX[1],snakeY[1]);  //身体
 88         Data.body.paintIcon(this,g,snakeX[2],snakeY[2]);  // 身体
 89         */
 90 
 91         // 动态小蛇的身体 0是头部,1开始为身体
 92         for (int i = 1; i <length; i++) {
 93             Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);  //动态身体
 94         }
 95 
 96         //游戏状态
 97         if (isStart ==false){
 98             g.setColor(Color.white);
 99             g.setFont(new Font("微软雅黑",Font.BOLD,32));//设置字体
100             g.drawString("按下空格 - 开始游戏",300,500);
101         }
102         if (isFail == true){
103             g.setColor(Color.red);
104             g.setFont(new Font("微软雅黑",Font.BOLD,60));//设置字体
105             g.drawString("游戏结束",350,300);
106             g.setFont(new Font("微软雅黑",Font.BOLD,32));//设置字体
107             g.drawString("按空格重新开始",350,500);
108         }
109 
110         g.setColor(Color.white);
111         g.setFont(new Font("微软雅黑",Font.BOLD,12));//设置字体
112         g.drawString("长度:"+length,680,100);
113         g.drawString("分数:"+score,750,100);
114 
115     }
116 
117     //键盘监听事件
118     @Override
119     public void keyPressed(KeyEvent e) {
120         int keyCode = e.getKeyCode();//获得键盘按键是哪一个
121         if(keyCode == KeyEvent.VK_SPACE ){
122             if (isFail){
123                 isFail =false;  //重新开始
124                 init(); //初始化
125             }else {
126                 isStart = !isStart;  //取反
127             }
128             repaint(); //重画
129         }
130         //小蛇移动 并且反向操作无效
131         if(keyCode == KeyEvent.VK_UP && direction != "D"){  //不等于向下状态时按上执行
132             direction = "U";
133         }else if (keyCode == KeyEvent.VK_DOWN && direction != "U"){
134             direction = "D";
135         }else if (keyCode == KeyEvent.VK_LEFT && direction != "R"){
136             direction = "L";
137         }else if (keyCode == KeyEvent.VK_RIGHT && direction != "L"){
138             direction = "R";
139         }
140     }
141 
142     //移动事件监听  需要设置刷新频率,1秒10次
143     @Override
144     public void actionPerformed(ActionEvent e) {
145         if(isStart == true && isFail == false){  // 如果isStart为真,小蛇动起来
146 
147             //吃食物
148             if (snakeX[0] == foodX & snakeY [0] == foodY){
149                 length++; //长度加一
150                 //分数增加10
151                 score = score+10;
152                 //食物再次随机
153                 foodX = 25 + 25 * random.nextInt(33);  // 随机数的边界框内 850/25-1
154                 foodY = 125 + 25 * random.nextInt(23);  // 随机数的边界框内 600/25-1
155             }
156 
157             //移动  头部要放到身体后,不然会被身体覆盖掉
158 
159             // 身体  后一节的身体移动到前一节身体的位置形成移动
160             for (int i = length-1; i >0 ; i--) {
161                 snakeX[i]=snakeX[i-1];
162                 snakeY[i]=snakeY[i-1];
163             }
164             //头 走向
165             if (direction.equals("R")){
166                 snakeX[0] =snakeX[0]+25;
167                 if(snakeX[0]>850){snakeX[0]=25;}  //边界判断
168             }else if (direction.equals("L")){
169                 snakeX[0] =snakeX[0]-25;
170                 if(snakeX[0]<25){snakeX[0]=850;}   //边界判断
171             }else if (direction.equals("U")){
172                 snakeY[0] =snakeY[0]-25;
173                 if(snakeY[0]<125){snakeY[0]=700;}   //边界判断
174             }else if (direction.equals("D")){
175                 snakeY[0] =snakeY[0]+25;
176                 if(snakeY[0]>700){snakeY[0]=125;}   //边界判断
177             }
178 
179             //失败判定
180             for (int i = 1; i <length; i++) {
181                 if(snakeX[0] == snakeX[i]&&snakeY[0] == snakeY[i]){
182                     isFail = true;
183                 }
184             }
185 
186             repaint(); //画一次
187         }
188         timer.start(); //移动一次
189     }
190 
191 
192     @Override
193     public void keyTyped(KeyEvent e) {
194 
195     }
196     @Override
197     public void keyReleased(KeyEvent e) {
198 
199     }
200 
201 }
复制代码

结果

 

posted @   luckylu1983  阅读(57)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
点击右上角即可分享
微信分享提示