Java寫的小游戲貪吃蛇代碼
import java.awt.; import java.awt.event.; import javax.swing.; import java.util.;//Main Class
public class GreedSnake extends KeyAdapter {
JFrame mainFrame; Canvas paintCanvas; JLabel labelScore;// 計分牌 SnakeModel snakeModel = null;// 蛇 public static final int DEFAULT_WIDTH = 500; public static final int DEFAULT_HEIGHT = 300; public static final int nodeWidth = 10; public static final int nodeHeight = 10; // GreedSnake():初始化游戲界面 public GreedSnake() { // 設置界面元素 mainFrame = new JFrame("貪吃蛇游戲"); Container cp = mainFrame.getContentPane(); labelScore = new JLabel("所得分數為:", JLabel.CENTER); cp.add(labelScore, BorderLayout.NORTH); paintCanvas = new Canvas(); paintCanvas.setSize(DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1); paintCanvas.addKeyListener(this); cp.add(paintCanvas, BorderLayout.CENTER); JPanel panelButtom = new JPanel(); panelButtom.setLayout(new BorderLayout()); JLabel labelHelp;// 幫助信息 labelHelp = new JLabel("按 PageUP 或 PageDown 鍵改變速度", JLabel.CENTER); panelButtom.add(labelHelp, BorderLayout.NORTH); labelHelp = new JLabel("按 Enter 或 S 鍵重新開始游戲", JLabel.CENTER); panelButtom.add(labelHelp, BorderLayout.CENTER); labelHelp = new JLabel("按 SPACE 鍵或 P 鍵暫停游戲", JLabel.CENTER); panelButtom.add(labelHelp, BorderLayout.SOUTH); cp.add(panelButtom, BorderLayout.SOUTH); mainFrame.addKeyListener(this); mainFrame.pack(); mainFrame.setResizable(false);// 設置窗口大小不能變化 mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainFrame.setVisible(true); begin(); } // keyPressed():按鍵檢測 public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (snakeModel.running) switch (keyCode) { case KeyEvent.VK_UP: snakeModel.changeDirection(SnakeModel.UP); break; case KeyEvent.VK_DOWN: snakeModel.changeDirection(SnakeModel.DOWN); break; case KeyEvent.VK_LEFT: snakeModel.changeDirection(SnakeModel.LEFT); break; case KeyEvent.VK_RIGHT: snakeModel.changeDirection(SnakeModel.RIGHT); break; case KeyEvent.VK_ADD: case KeyEvent.VK_PAGE_UP: snakeModel.speedUp();// 加速 break; case KeyEvent.VK_SUBTRACT: case KeyEvent.VK_PAGE_DOWN: snakeModel.speedDown();// 減速 break; case KeyEvent.VK_SPACE: case KeyEvent.VK_P: snakeModel.changePauseState();// 暫停或繼續 break; default: } // 重新開始 if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_ENTER) { snakeModel.running = false; begin(); } } // repaint():繪制游戲界面(包括蛇和食物) void repaint() { Graphics g = paintCanvas.getGraphics(); // draw background g.setColor(Color.LIGHT_GRAY); g.fillRect(0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT); // draw the snake g.setColor(Color.BLACK); LinkedList na = snakeModel.nodeArray; Iterator it = na.iterator(); while (it.hasNext()) { Node n = (Node) it.next(); drawNode(g, n); } // draw the food g.setColor(Color.RED); Node n = snakeModel.food; drawNode(g, n); updateScore(); } // drawNode():繪畫某一結點(蛇身或食物) private void drawNode(Graphics g, Node n) { g.fillRect(n.x * nodeWidth, n.y * nodeHeight, nodeWidth - 1, nodeHeight - 1); } // updateScore():改變計分牌 public void updateScore() { String s = "所得分數為: " + snakeModel.score; labelScore.setText(s); } // begin():游戲開始,放置貪吃蛇 void begin() { if (snakeModel == null || !snakeModel.running) { snakeModel = new SnakeModel(this, DEFAULT_WIDTH / nodeWidth, DEFAULT_HEIGHT / nodeHeight); (new Thread(snakeModel)).start(); } } // main():主函數 public static void main(String[] args) { GreedSnake gs = new GreedSnake(); }
}
// Node:結點類
class Node { int x;
int y; Node(int x, int y) { this.x = x; this.y = y; }
}
// SnakeModel:貪吃蛇模型
class SnakeModel implements Runnable {
GreedSnake gs; boolean[][] matrix;// 界面數據保存在數組里 LinkedList nodeArray = new LinkedList(); Node food; int maxX;// 最大寬度 int maxY;// 最大長度 int direction = 2;// 方向 boolean running = false; int timeInterval = 200;// 間隔時間(速度) double speedChangeRate = 0.75;// 速度改變程度 boolean paused = false;// 游戲狀態 int score = 0; int countMove = 0; // UP和DOWN是偶數,RIGHT和LEFT是奇數 public static final int UP = 2; public static final int DOWN = 4; public static final int LEFT = 1; public static final int RIGHT = 3; // GreedModel():初始化界面 public SnakeModel(GreedSnake gs, int maxX, int maxY) { this.gs = gs; this.maxX = maxX; this.maxY = maxY; matrix = new boolean[maxX][]; for (int i = 0; i < maxX; ++i) { matrix[i] = new boolean[maxY]; Arrays.fill(matrix[i], false);// 沒有蛇和食物的地區置false } // 初始化貪吃蛇 int initArrayLength = maxX > 20 ? 10 : maxX / 2; for (int i = 0; i < initArrayLength; ++i) { int x = maxX / 2 + i; int y = maxY / 2; nodeArray.addLast(new Node(x, y)); matrix[x][y] = true;// 蛇身處置true } food = createFood(); matrix[food.x][food.y] = true;// 食物處置true } // changeDirection():改變運動方向 public void changeDirection(int newDirection) { if (direction % 2 != newDirection % 2) {// 避免沖突 direction = newDirection; } } // moveOn():貪吃蛇運動函數 public boolean moveOn() { Node n = (Node) nodeArray.getFirst(); int x = n.x; int y = n.y; switch (direction) { case UP: y--; break; case DOWN: y++; break; case LEFT: x--; break; case RIGHT: x++; break; } if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) { if (matrix[x][y]) {// 吃到食物或者撞到身體 if (x == food.x && y == food.y) {// 吃到食物 nodeArray.addFirst(food);// 在頭部加上一結點 // 計分規則與移動長度和速度有關 int scoreGet = (10000 - 200 * countMove) / timeInterval; score += scoreGet > 0 ? scoreGet : 10; countMove = 0; food = createFood(); matrix[food.x][food.y] = true; return true; } else return false;// 撞到身體 } else {// 什么都沒有碰到 nodeArray.addFirst(new Node(x, y));// 加上頭部 matrix[x][y] = true; n = (Node) nodeArray.removeLast();// 去掉尾部 matrix[n.x][n.y] = false; countMove++; return true; } } return false;// 越界(撞到墻壁) } /* 發了一份貪吃蛇游戲的代碼,誰能幫我解釋一下,貪吃蛇程序的運行過程,運行步驟 */ // run():貪吃蛇運動線程 public void run() { running = true; while (running) { try { Thread.sleep(timeInterval); } catch (Exception e) { break; } if (!paused) { if (moveOn()) {// 未結束 gs.repaint(); } else {// 游戲結束 JOptionPane.showMessageDialog(null, "GAME OVER", "Game Over", JOptionPane.INFORMATION_MESSAGE); break; } } } running = false; } // createFood():生成食物及放置地點 private Node createFood() { int x = 0; int y = 0; do { Random r = new Random(); x = r.nextInt(maxX); y = r.nextInt(maxY); } while (matrix[x][y]); return new Node(x, y); } // speedUp():加快蛇運動速度 public void speedUp() { timeInterval *= speedChangeRate; } // speedDown():放慢蛇運動速度 public void speedDown() { timeInterval /= speedChangeRate; } // changePauseState(): 改變游戲狀態(暫停或繼續) public void changePauseState() { paused = !paused; }
}</pre>
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!