5.小蛇吃食物长大
- 有个食物的坐标,食物的坐标是随机的
- 写食物的初始化数据
- 把食物画在面板上
- 在事件监听里面,判断食物的状态
1 package com.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 //游戏的面板 12 public class GamePanel extends JPanel implements KeyListener, ActionListener { 13 14 //定义蛇的数据结构 15 int length; //蛇的长度 16 int[] snakeX = new int[600]; //蛇的x坐标 25*25 17 int[] snakeY = new int[500]; //蛇的Y坐标 25*25 18 String fx; 19 20 //食物的坐标 21 int foodx; 22 int foody; 23 Random random = new Random(); 24 25 //游戏当前的状态:开始、停止 26 boolean isStart = false; //默认是不开始 27 28 //定时器 以毫秒为单位 1000ms = 1s 29 Timer timer = new Timer(100, this);//100ms执行一次 30 31 //构造器 32 public GamePanel() { 33 init(); 34 //获得焦点和键盘事件 35 this.setFocusable(true);//获得焦点事件 36 this.addKeyListener(this);//获得键盘监听事件:写的当前这个类,所以是this如果是其他类的话,去new一个监听器 37 timer.start();//游戏一开始,就让定时器启动 38 } 39 40 //初始化方法 41 public void init() { 42 length = 3; 43 snakeX[0] = 100;snakeY[0] = 100;//脑袋的坐标 44 snakeX[1] = 75 ;snakeY[1] = 100;//第一个身体的坐标 45 snakeX[2] = 50 ;snakeY[2] = 100;//第二个身体的坐标 46 fx = "R";//初始方向向右 47 48 //把食物随机分配在界面上 49 foodx = 25 + 25 * random.nextInt(34); 50 foody = 75 + 25 * random.nextInt(24); 51 } 52 53 //绘制面板,我们游戏中的所有东西,都是用这个画笔来画。 Ctrl+O,画组件 54 @Override 55 protected void paintComponent(Graphics g) { 56 super.paintComponent(g);//清屏的作用,不用会闪烁 57 //绘制静态的面板 58 this.setBackground(Color.WHITE); 59 Data.header.paintIcon(this, g, 25, 11);//头部广告栏画上去 60 g.fillRect(25, 75, 850, 600);//默认游戏界面 61 62 //把小蛇画上去 63 if (fx.equals("R")) { 64 Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);//蛇头初始化向右,需要通过方向来判断 65 } else if (fx.equals("L")) { 66 Data.left.paintIcon(this, g, snakeX[0], snakeY[0]); 67 } else if (fx.equals("U")) { 68 Data.up.paintIcon(this, g, snakeX[0], snakeY[0]); 69 } else if (fx.equals("D")) { 70 Data.down.paintIcon(this, g, snakeX[0], snakeY[0]); 71 } 72 73 for (int i = 1; i < length; i++) { 74 Data.body.paintIcon(this, g, snakeX[i], snakeY[i]);//蛇的身体 75 } 76 77 //画食物 78 Data.food.paintIcon(this,g,foodx,foody); 79 80 81 //游戏状态 82 if (isStart == false) { 83 g.setColor(Color.white); 84 g.setFont(new Font("楷体", Font.BOLD, 40)); 85 g.drawString("按下空格开始游戏", 300, 300); 86 } 87 } 88 89 90 //键盘监听事件 91 @Override 92 public void keyPressed(KeyEvent e) { 93 int keyCode = e.getKeyCode();//获得键盘按键是哪一个 94 if (keyCode == KeyEvent.VK_SPACE) {//如果按下的是空格键 95 isStart = !isStart;//取反 96 repaint();//重新绘制,因为值已经变化了 97 } 98 //小蛇移动 99 if (keyCode == KeyEvent.VK_UP) { 100 fx = "U"; 101 } else if (keyCode == KeyEvent.VK_DOWN) { 102 fx = "D"; 103 } else if (keyCode == KeyEvent.VK_LEFT) { 104 fx = "L"; 105 } else if (keyCode == KeyEvent.VK_RIGHT) { 106 fx = "R"; 107 } 108 } 109 110 //事件监听---需要通过固定的时间来刷新,1s=10次 111 @Override 112 public void actionPerformed(ActionEvent e) { 113 if (isStart) {//如果游戏是开始状态,就让小蛇动起来! 114 115 //吃食物 116 if(snakeX[0] == foodx && snakeY[0] == foody){ 117 length++;//长度 + 1 118 //再次随机食物 119 foodx = 25 + 25 * random.nextInt(34); 120 foody = 75 + 25 * random.nextInt(24); 121 } 122 123 //移动 124 for (int i = length - 1; i > 0; i--) {//后一节移到前一节的位置 snake[1] = snake [0]; 125 snakeX[i] = snakeX[i - 1]; 126 snakeY[i] = snakeY[i - 1]; 127 } 128 129 //走向 130 if (fx.equals("R")) { 131 snakeX[0] = snakeX[0] + 25; 132 if (snakeX[0] > 850) { snakeX[0] = 25; }//边界判断 133 } else if (fx.equals("L")) { 134 snakeX[0] = snakeX[0] - 25; 135 if (snakeX[0] < 25) { snakeX[0] = 850; }//边界判断 136 } else if (fx.equals("U")) { 137 snakeY[0] = snakeY[0] - 25; 138 if (snakeY[0] < 75) { snakeY[0] = 650; }//边界判断 139 } else if (fx.equals("D")) { 140 snakeY[0] = snakeY[0] + 25; 141 if (snakeY[0] > 650) { snakeY[0] = 75; }//边界判断 142 } 143 144 repaint();//重画页面 145 } 146 timer.start(); 147 } 148 149 @Override 150 public void keyReleased(KeyEvent e) { 151 } 152 153 @Override 154 public void keyTyped(KeyEvent e) { 155 } 156 }
测试效果:
存在问题:
- 会出现一个重叠上去的感觉,因为画的话两个是在同一个界面上,我们是判断这两个点相同的时候,才给它干掉的.他有个闪烁的问题。
- 脑袋能在自己身体里边走,来回穿梭,这个也不行.所以应该做一件事情,把失败判定上去。