設計遊戲圖紙java
畫出900*700的白色窗口框架
在窗口上添加畫布dom
在畫布上添加標題ide
在畫布上添加黑色遊戲區函數
放置靜態的蛇:一個頭、兩個身體this
加上開始提示:按空格鍵開始遊戲spa
讓蛇動起來:監聽Timer事件,平移數據設計
實現遊戲暫停rest
實現轉向功能code
添加食物
吃掉食物
添加死亡條件
實現「從新開始」功能
添加分數和長度
圖片下載地址 連接:https://pan.baidu.com/s/1jH6xnXc 密碼:hqze
1 package snake; 2 3 import javax.swing.JFrame; 4 import javax.swing.JPanel; 5 6 public class Snake { 7 8 public static void main(String[] args) { 9 10 JFrame frame = new JFrame(); // 建立一個遊戲界面的框架 11 frame.setBounds(10, 10, 900, 720); // 設置框架的大小 12 frame.setResizable(false); // 設置框架大小爲不能改變 13 // 點擊關閉按鈕 關閉遊戲界面 14 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 15 16 SnakePanel panel = new SnakePanel(); //添加畫布 17 frame.add(panel); // 剛添加時畫布是空的看不到 18 19 frame.setVisible(true); // 容許顯示遊戲界面 20 } 21 22 }
1 package snake; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics; 6 import java.awt.event.ActionEvent; 7 import java.awt.event.ActionListener; 8 import java.awt.event.KeyEvent; 9 import java.awt.event.KeyListener; 10 import java.util.Random; 11 12 import javax.swing.ImageIcon; 13 import javax.swing.JPanel; 14 import javax.swing.Timer; 15 16 public class SnakePanel extends JPanel implements KeyListener,ActionListener{ 17 18 // 定義七個圖片變量,表明七張圖片 19 ImageIcon up = new ImageIcon("up.png"); // 向上的蛇頭 20 ImageIcon down = new ImageIcon("down.png"); // 向下的蛇頭 21 ImageIcon left = new ImageIcon("left.png"); // 向左的蛇頭 22 ImageIcon right = new ImageIcon("right.png"); // 向右的蛇頭 23 ImageIcon food = new ImageIcon("food.png"); // 食物 24 ImageIcon body = new ImageIcon("body.png"); // 蛇的身體 25 ImageIcon title = new ImageIcon("title.jpg"); // 遊戲界面的主題 26 27 // 蛇的每一部分 28 int[] snakex = new int [750]; 29 int[] snakey = new int [750]; 30 31 // 隨機生成食物 32 Random rand = new Random(); 33 int foodx = rand.nextInt(34)*25+25; //此處的數值根據本身設計的遊戲界面的大小來肯定 34 int foody = rand.nextInt(24)*25+75; 35 36 // 設置遊戲的默認屬性 37 int len = 3; 38 int score = 0; 39 String direction = "R"; // U上 D下 L左 R右 40 41 boolean isStarted = false; // 判斷遊戲是否開始 42 boolean isFailed = false; // 判斷遊戲是否結束 43 44 Timer timer = new Timer(100,this); // 每100毫秒調用一次ActionPerformed 45 46 47 public SnakePanel() { // 建造畫布的構造函數 48 this.setFocusable(true); // 獲取焦點 49 this.addKeyListener(this); // 監聽鍵盤事件 50 setup(); 51 timer.start(); 52 } 53 54 public void paint(Graphics g) { // Graphics 畫筆 55 56 this.setBackground(Color.BLACK); // 設置畫布背景顏色 57 title.paintIcon(this, g, 25, 11);// 放置主題圖片 58 g.fillRect(25, 75, 850, 650); // 用畫筆設置遊戲方框 59 60 // 畫蛇頭(注意判斷蛇頭的方向) 61 if (direction.equals("R")) 62 right.paintIcon(this, g, snakex[0], snakey[0]); 63 else if (direction.equals("L")) 64 left.paintIcon(this, g, snakex[0], snakey[0]); 65 else if (direction.equals("U")) 66 up.paintIcon(this, g, snakex[0], snakey[0]); 67 else if (direction.equals("D")) 68 down.paintIcon(this, g, snakex[0], snakey[0]); 69 70 // 畫蛇的身體 71 for(int i = 1; i < len; i ++) 72 body.paintIcon(this, g, snakex[i], snakey[i]); 73 74 // 判斷若是遊戲沒開始顯示。。。 75 if (!isStarted){ 76 g.setColor(Color.WHITE); 77 g.setFont(new Font("arial",Font.BOLD, 30)); 78 g.drawString("Press Space to start / pause", 200, 300); 79 } 80 81 // 判斷若是遊戲結束顯示。。。 82 if (isFailed){ 83 g.setColor(Color.WHITE); 84 g.setFont(new Font("arial",Font.BOLD, 30)); 85 g.drawString("Game Over ! Press space to restart", 200, 300); 86 } 87 88 // 顯示食物 89 food.paintIcon(this, g, foodx, foody); 90 91 // 設置分數和蛇的長度 92 g.setColor(Color.WHITE); 93 g.setFont(new Font("arial",Font.PLAIN,15)); 94 g.drawString("Score : "+score, 650, 37); 95 g.drawString("Len :"+len, 650, 57); 96 } 97 98 public void setup() { // 遊戲初始化 99 isStarted = false; 100 isFailed = false; 101 len = 3; 102 score = 0; 103 snakex[0] = 100; snakex[1] = 75; snakex[2] = 50; 104 snakey[0] = 100; snakey[1] = 100; snakey[2] = 100; 105 } 106 107 @Override 108 public void keyPressed(KeyEvent e) { 109 110 //實現鍵盤響應 111 int KeyCode = e.getKeyCode(); 112 if (KeyCode == KeyEvent.VK_SPACE){ // 敲擊空格現實/消除提示信息 113 if (isFailed){ 114 // isStarted = false; // 能夠將這兩行放入setup中 115 // isFailed = false; 116 setup(); 117 }else 118 isStarted = !isStarted; 119 } else if (KeyCode == KeyEvent.VK_UP && direction != "D") 120 direction = "U"; 121 else if (KeyCode == KeyEvent.VK_DOWN && direction != "U" ) 122 direction = "D"; 123 else if (KeyCode == KeyEvent.VK_RIGHT && direction != "L") 124 direction = "R"; 125 else if (KeyCode == KeyEvent.VK_LEFT && direction != "R") 126 direction = "L"; 127 } 128 129 @Override 130 public void actionPerformed(ActionEvent e) { 131 // 1. 再定義一個鬧鐘 132 timer.start(); 133 134 // 2. 移動數據 135 if (isStarted && !isFailed){ 136 // 移動身體 137 for (int i = len; i>0; i--){ 138 snakex[i] = snakex[i-1]; 139 snakey[i] = snakey[i-1]; 140 } 141 // 移動頭 142 if (direction.equals("R")){ 143 snakex[0] = snakex[0] + 25; 144 if(snakex[0] > 850) snakex[0] = 25; 145 }else if (direction.equals("L")){ 146 snakex[0] = snakex[0] - 25; 147 if(snakex[0] < 25) snakex[0] = 850; 148 }else if (direction.equals("U")){ 149 snakey[0] = snakey[0] - 25; 150 if (snakey[0] < 75) snakey[0] = 650; 151 }else if (direction.equals("D")){ 152 snakey[0] = snakey[0] + 25; 153 if (snakey[0] > 650) snakey[0] = 75; 154 } 155 156 if (snakex[0] == foodx && snakey[0] == foody){ // 吃食物 157 len ++; 158 score ++; 159 foodx = rand.nextInt(34)*25+25; 160 foody = rand.nextInt(24)*25+75; 161 } 162 163 for (int i = 1; i < len; i ++){ // 若是蛇頭碰到本身的身體遊戲結束 164 if (snakex[0] == snakex[i] && snakey[0] == snakey[i]){ 165 isFailed = true; 166 } 167 } 168 169 } 170 // 3. repaint() 171 repaint(); 172 } 173 174 @Override 175 public void keyTyped(KeyEvent e) { 176 177 } 178 179 @Override 180 public void keyReleased(KeyEvent e) { 181 182 } 183 }