java實現(xiàn)貪吃蛇極速版
更新時間:2021年09月13日 16:01:44 作者:July
這篇文章主要為大家分享了java貪吃蛇極速版,貪吃蛇經(jīng)典手機游戲,既簡單又耐玩,本文用java來實現(xiàn)下貪吃蛇小游戲,感興趣的小伙伴可以參考下
本文為大家推薦了一款由java實現(xiàn)經(jīng)典小游戲:貪吃蛇,相信大家都玩過,如何實現(xiàn)的吶?
效果圖:
廢話不多說,直接奉上代碼:
1、
public class GreedSnake { public static void main(String[] args) { SnakeModel model = new SnakeModel(20,30); SnakeControl control = new SnakeControl(model); SnakeView view = new SnakeView(model,control); //添加一個觀察者,讓view成為model的觀察者 model.addObserver(view); (new Thread(model)).start(); } }
2、
package mvcTest; //SnakeControl.java import java.awt.event.KeyEvent; import java.awt.event.KeyListener; public class SnakeControl implements KeyListener{ SnakeModel model; public SnakeControl(SnakeModel model){ this.model = model; } public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (model.running){ // 運行狀態(tài)下,處理的按鍵 switch (keyCode) { case KeyEvent.VK_UP: model.changeDirection(SnakeModel.UP); break; case KeyEvent.VK_DOWN: model.changeDirection(SnakeModel.DOWN); break; case KeyEvent.VK_LEFT: model.changeDirection(SnakeModel.LEFT); break; case KeyEvent.VK_RIGHT: model.changeDirection(SnakeModel.RIGHT); break; case KeyEvent.VK_ADD: case KeyEvent.VK_PAGE_UP: model.speedUp(); break; case KeyEvent.VK_SUBTRACT: case KeyEvent.VK_PAGE_DOWN: model.speedDown(); break; case KeyEvent.VK_SPACE: case KeyEvent.VK_P: model.changePauseState(); break; default: } } // 任何情況下處理的按鍵,按鍵導(dǎo)致重新啟動游戲 if (keyCode == KeyEvent.VK_R || keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_ENTER) { model.reset(); } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } }
3、
package mvcTest; //SnakeModel.java import javax.swing.*; import java.util.Arrays; import java.util.LinkedList; import java.util.Observable; import java.util.Random; class SnakeModel extends Observable implements Runnable { boolean[][] matrix; // 指示位置上有沒蛇體或食物 LinkedList nodeArray = new LinkedList(); // 蛇體 Node food; int maxX; int maxY; int direction = 2; // 蛇運行的方向 boolean running = false; // 運行狀態(tài) int timeInterval = 200; // 時間間隔,毫秒 double speedChangeRate = 0.75; // 每次得速度變化率 boolean paused = false; // 暫停標(biāo)志 int score = 0; // 得分 int countMove = 0; // 吃到食物前移動的次數(shù) // UP and DOWN should be even // RIGHT and LEFT should be odd public static final int UP = 2; public static final int DOWN = 4; public static final int LEFT = 1; public static final int RIGHT = 3; public SnakeModel( int maxX, int maxY) { this.maxX = maxX; this.maxY = maxY; reset(); } public void reset(){ direction = SnakeModel.UP; // 蛇運行的方向 timeInterval = 200; // 時間間隔,毫秒 paused = false; // 暫停標(biāo)志 score = 0; // 得分 countMove = 0; // 吃到食物前移動的次數(shù) // initial matirx, 全部清0 matrix = new boolean[maxX][]; for (int i = 0; i < maxX; ++i) { matrix[i] = new boolean[maxY]; Arrays.fill(matrix[i], false); } // initial the snake // 初始化蛇體,如果橫向位置超過20個,長度為10,否則為橫向位置的一半 int initArrayLength = maxX > 20 ? 10 : maxX / 2; nodeArray.clear(); for (int i = 0; i < initArrayLength; ++i) { int x = maxX / 2 + i;//maxX被初始化為20 int y = maxY / 2; //maxY被初始化為30 //nodeArray[x,y]: [10,15]-[11,15]-[12,15]~~[20,15] //默認的運行方向向上,所以游戲一開始nodeArray就變?yōu)椋? // [10,14]-[10,15]-[11,15]-[12,15]~~[19,15] nodeArray.addLast(new Node(x, y)); matrix[x][y] = true; } // 創(chuàng)建食物 food = createFood(); matrix[food.x][food.y] = true; } public void changeDirection(int newDirection) { // 改變的方向不能與原來方向同向或反向 if (direction % 2 != newDirection % 2) { direction = newDirection; } } public boolean moveOn() { Node n = (Node) nodeArray.getFirst(); int x = n.x; int y = n.y; // 根據(jù)方向增減坐標(biāo)值 switch (direction) { case UP: y--; break; case DOWN: y++; break; case LEFT: x--; break; case RIGHT: x++; break; } // 如果新坐標(biāo)落在有效范圍內(nèi),則進行處理 if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) { if (matrix[x][y]) { // 如果新坐標(biāo)的點上有東西(蛇體或者食物) if (x == food.x && y == food.y) { // 吃到食物,成功 nodeArray.addFirst(food); // 從蛇頭贈長 // 分?jǐn)?shù)規(guī)則,與移動改變方向的次數(shù)和速度兩個元素有關(guān) int scoreGet = (10000 - 200 * countMove) / timeInterval; score += scoreGet > 0 ? scoreGet : 10; countMove = 0; food = createFood(); // 創(chuàng)建新的食物 matrix[food.x][food.y] = true; // 設(shè)置食物所在位置 return true; } else // 吃到蛇體自身,失敗 return false; } else { // 如果新坐標(biāo)的點上沒有東西(蛇體),移動蛇體 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; // 觸到邊線,失敗 } public void run() { running = true; while (running) { try { Thread.sleep(timeInterval); } catch (Exception e) { break; } if (!paused) { if (moveOn()) { setChanged(); // Model通知View數(shù)據(jù)已經(jīng)更新 notifyObservers(); } else { JOptionPane.showMessageDialog(null, "you failed", "Game Over", JOptionPane.INFORMATION_MESSAGE); break; } } } running = false; } private Node createFood() { int x = 0; int y = 0; // 隨機獲取一個有效區(qū)域內(nèi)的與蛇體和食物不重疊的位置 do { Random r = new Random(); x = r.nextInt(maxX); y = r.nextInt(maxY); } while (matrix[x][y]); return new Node(x, y); } public void speedUp() { timeInterval *= speedChangeRate; } public void speedDown() { timeInterval /= speedChangeRate; } public void changePauseState() { paused = !paused; } public String toString() { String result = ""; for (int i = 0; i < nodeArray.size(); ++i) { Node n = (Node) nodeArray.get(i); result += "[" + n.x + "," + n.y + "]"; } return result; } } class Node { int x; int y; Node(int x, int y) { this.x = x; this.y = y; } }
4、
package mvcTest; //SnakeView.java import javax.swing.*; import java.awt.*; import java.util.Iterator; import java.util.LinkedList; import java.util.Observable; import java.util.Observer; public class SnakeView implements Observer { SnakeControl control = null; SnakeModel model = null; JFrame mainFrame; Canvas paintCanvas; JLabel labelScore; public static final int canvasWidth = 200; public static final int canvasHeight = 300; public static final int nodeWidth = 10; public static final int nodeHeight = 10; public SnakeView(SnakeModel model, SnakeControl control) { this.model = model; this.control = control; mainFrame = new JFrame("GreedSnake"); Container cp = mainFrame.getContentPane(); // 創(chuàng)建頂部的分?jǐn)?shù)顯示 labelScore = new JLabel("Score:"); cp.add(labelScore, BorderLayout.NORTH); // 創(chuàng)建中間的游戲顯示區(qū)域 paintCanvas = new Canvas(); paintCanvas.setSize(canvasWidth + 1, canvasHeight + 1); paintCanvas.addKeyListener(control); cp.add(paintCanvas, BorderLayout.CENTER); // 創(chuàng)建底下的幫助欄 JPanel panelButtom = new JPanel(); panelButtom.setLayout(new BorderLayout()); JLabel labelHelp; labelHelp = new JLabel("PageUp, PageDown for speed;", JLabel.CENTER); panelButtom.add(labelHelp, BorderLayout.NORTH); labelHelp = new JLabel("ENTER or R or S for start;", JLabel.CENTER); panelButtom.add(labelHelp, BorderLayout.CENTER); labelHelp = new JLabel("SPACE or P for pause", JLabel.CENTER); panelButtom.add(labelHelp, BorderLayout.SOUTH); cp.add(panelButtom, BorderLayout.SOUTH); mainFrame.addKeyListener(control); mainFrame.pack(); mainFrame.setResizable(false); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainFrame.setVisible(true); } void repaint() { Graphics g = paintCanvas.getGraphics(); //draw background g.setColor(Color.WHITE); g.fillRect(0, 0, canvasWidth, canvasHeight); // draw the snake g.setColor(Color.BLACK); LinkedList na = model.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 = model.food; drawNode(g, n); updateScore(); } private void drawNode(Graphics g, Node n) { g.fillRect(n.x * nodeWidth, n.y * nodeHeight, nodeWidth - 1, nodeHeight - 1); } public void updateScore() { String s = "Score: " + model.score; labelScore.setText(s); } public void update(Observable o, Object arg) { repaint(); } }
本文的目的就是帶著大家回味經(jīng)典,但是更主要的目的就是幫助大家學(xué)習(xí)好java程序設(shè)計。
相關(guān)文章
Java通過socket客戶端保持連接服務(wù)端實現(xiàn)代碼
這篇文章主要介紹了Java通過socket客戶端保持連接服務(wù)端實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11Springboot2 集成 druid 加密數(shù)據(jù)庫密碼的配置方法
這篇文章給大家介紹Springboot2 集成 druid 加密數(shù)據(jù)庫密碼的配置方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-07-07Jmeter參數(shù)化實現(xiàn)方法及應(yīng)用實例
這篇文章主要介紹了Jmeter參數(shù)化實現(xiàn)方法及應(yīng)用實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08java將String字符串轉(zhuǎn)換為List<Long>類型實例方法
在本篇文章里小編給大家整理的是關(guān)于java將String字符串轉(zhuǎn)換為List<Long>類型實例方法,需要的朋友們可以參考下。2020-03-03