GUI编程——贪吃蛇游戏实战

 

游戏开始界面

 1 package com.kuang.snake;
 2 
 3 import javax.swing.*;
 4 
 5 public class StartGame {
 6     public static void main(String[] args) {
 7         JFrame frame=new JFrame();
 8 
 9         frame.setBounds(5,5,700,550);
10         frame.setResizable(false);
11         frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
12 
13         //正常游戏界面都应该在上面!
14         frame.add(new GamePanel());
15         frame.setVisible(true);
16     }
17 }

 

数据中心

 1 package com.kuang.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 
14     public static URL upURL=Data.class.getResource("statics/up.png");
15     public static URL downURL=Data.class.getResource("statics/down.png");
16     public static URL leftURL=Data.class.getResource("statics/left.png");
17     public static URL rightURL=Data.class.getResource("statics/right.png");
18     public static ImageIcon up=new ImageIcon(upURL);
19     public static ImageIcon down=new ImageIcon(downURL);
20     public static ImageIcon left=new ImageIcon(leftURL);
21     public static ImageIcon right=new ImageIcon(rightURL);
22 ;
23     public static URL bodyURL=Data.class.getResource("statics/body.png");
24     public static ImageIcon body=new ImageIcon(bodyURL);
25 
26     public static URL foodURL=Data.class.getResource("statics/food.png");
27     public static ImageIcon food=new ImageIcon(foodURL);
28 }

 

游戏面板

  1 package com.kuang.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 //游戏面板
 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 fx="R";
 19 
 20     //食物的坐标
 21     int foodx;
 22     int foody;
 23     Random random=new Random();
 24 
 25     int score;   //成绩
 26 
 27     //游戏当前的状态:开始,停止
 28     boolean isStart=false;  //默认是不开始
 29 
 30     boolean isFail=false;  //游戏失败状态
 31 
 32     //定时器   以毫秒以单位
 33     Timer timer=new Timer(100,this);  //100毫秒执行1次!
 34 
 35 
 36     //构造器
 37     public GamePanel(){
 38         init();
 39         //获得焦点和键盘事件
 40         this.setFocusable(true);   //获得焦点事件
 41         this.addKeyListener(this);  //获得键盘监听事件
 42         timer.start();  //游戏一开始定时器就启动
 43     }
 44 
 45     //初始化方法
 46     public void init(){
 47         length=3;
 48         snakeX[0]=90; snakeY[0]=70;  //脑袋的坐标
 49         snakeX[1]=65; snakeY[1]=70;  //第一个身体的坐标
 50         snakeX[2]=40; snakeY[2]=70;  //第二个身体的坐标
 51         fx="R";  //初始方向向右
 52 
 53         //把食物随机分布到界面上
 54         foodx=25+25*random.nextInt(26);
 55         foody=75+25*random.nextInt(18);
 56 
 57         score=0;    //成绩初始为0
 58     }
 59 
 60     //绘制面板,我们游戏中所有东西都是由这个画笔来画
 61     @Override
 62     protected void paintComponent(Graphics g){
 63         super.paintComponent(g);   //清屏
 64         //绘制静态面板
 65         this.setBackground(Color.WHITE);
 66         Data.header.paintIcon(this,g,15,1);  //头部广告栏
 67         g.fillRect(20,55,650,450);  //默认的游戏界面
 68 
 69         //画积分
 70         g.setColor(Color.WHITE);
 71         g.setFont(new Font("微软雅黑",Font.BOLD,18));
 72         g.drawString("长度"+length,200,25);
 73         g.drawString("分数"+score,200,45);
 74 
 75         //画食物
 76         Data.food.paintIcon(this,g,foodx,foody);
 77 
 78         //把小蛇画上去
 79         if (fx.equals("R")){
 80             Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);  //蛇头初始化向右,需要通过方向来判断
 81         }else if(fx.equals("L")){
 82             Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);  //蛇头初始化向左,需要通过方向来判断
 83         }else if(fx.equals("U")){
 84             Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);  //蛇头初始化向上,需要通过方向来判断
 85         }else if(fx.equals("D")){
 86             Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);  //蛇头初始化向下,需要通过方向来判断
 87         }
 88 
 89 
 90         for (int i=1;i<=length;i++){
 91             Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);  //第一个身体的坐标
 92         }
 93 
 94 
 95         //游戏状态
 96         if (isStart==false){
 97             g.setColor(Color.WHITE);
 98             g.setFont(new Font("微软雅黑",Font.BOLD,30));  //设置字体
 99             g.drawString("按下空格开始游戏",250,250);
100         }
101 
102         if (isFail){
103             g.setColor(Color.RED);
104             g.setFont(new Font("微软雅黑",Font.BOLD,30));  //设置字体
105             g.drawString("失败,按下空格重新开始",250,250);
106         }
107     }
108 
109 
110     //键盘监听事件
111     @Override
112     public void keyPressed(KeyEvent e){
113         int keyCode=e.getKeyCode();  //获得键盘按键是哪一个
114         if (keyCode== KeyEvent.VK_SPACE){  //如果按下的是空格键
115             if (isFail){
116                 //重新开始
117                 isFail=false;
118                 init();
119             }else {
120                 isStart=!isStart;  //取反
121             }
122             repaint();
123         }
124         //小蛇移动
125         if (keyCode==KeyEvent.VK_UP){
126             fx="U";
127         }else if (keyCode==KeyEvent.VK_DOWN) {
128             fx="D";
129         }else if (keyCode==KeyEvent.VK_LEFT){
130             fx="L";
131         }else if (keyCode==KeyEvent.VK_RIGHT){
132             fx="R";
133         }
134     }
135 
136     //事件监听---需要通过固定事件来刷新
137     @Override
138     public void actionPerformed(ActionEvent e) {
139         if (isStart && isFail==false){    //如果游戏是开始状态,就让小蛇动起来!
140 
141             //吃食物
142             if (snakeX[0]==foodx && snakeY[0]==foody){
143                 //长度 + 1;
144                 length++;
145                 //分数加10
146                 score=score+10;
147                 //再次随机食物
148                 foodx=25+25*random.nextInt(26);
149                 foody=75+25*random.nextInt(18);
150             }
151 
152             //移动
153             for (int i=length-1;i>0;i--){   //后一节移到前一节的位置 snakeX[1]=snakeX[0];
154                 snakeX[i]=snakeX[i-1];
155                 snakeY[i]=snakeY[i-1];
156             }
157 
158             //走向
159             if (fx.equals("R")) {
160                 snakeX[0] = snakeX[0] + 25;
161                 if (snakeX[0]>650){ snakeX[0]=25; }  //边界判断 , 超过游戏界面边框回到最初点
162             }else if (fx.equals("L")){
163                 snakeX[0] = snakeX[0] - 25;
164                 if (snakeX[0]<25){ snakeX[0]=650; }  //边界判断
165             }else if (fx.equals("U")){
166                 snakeY[0] = snakeY[0] - 25;
167                 if (snakeY[0]<75){ snakeY[0]=450;}  //边界判断
168             }else if (fx.equals("D")){
169                 snakeY[0] = snakeY[0] + 25;
170                 if (snakeY[0]>450){ snakeY[0]=75;}  //边界判断
171             }
172 
173             //失败判断,撞到自己就算失败
174             for (int i=1;i<length;i++) {
175                 if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
176                     isFail = true;
177                 }
178             }
179 
180             repaint();  //重画页面
181         }
182         timer.start();  //定时器开启!
183     }
184 
185     @Override
186     public void keyReleased(KeyEvent e) { }
187     @Override
188     public void keyTyped(KeyEvent e){ }
189 
190 
191 }

 

posted @ 2021-04-22 18:22  cengxuyuan  阅读(81)  评论(0)    收藏  举报