java貪吃蛇游戲編寫代碼
本文實例為大家分享了java貪吃蛇游戲展示的具體代碼,供大家參考,具體內(nèi)容如下
1、采用MVC(model、view、control)框架模式
2、包和類的關(guān)系樹形圖為:
3、源碼:
package com.huai; import Java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import com.huai.listener.SnakeListener; import com.huai.util.Constant; public class Snake { //和蛇的監(jiān)聽器有關(guān) Set<SnakeListener> snakeListener = new HashSet<SnakeListener>(); //用鏈表保存蛇的身體節(jié)點 LinkedList<Point> body = new LinkedList<Point>(); private boolean life = true; //默認速度為400ms private int speed = 400; private Point lastTail = null; private boolean pause = false; //定義各個方向 public static final int UP = 1; public static final int DOWN = -1; public static final int LEFT = 2; public static final int RIGHT = -2; int newDirection = RIGHT; int oldDirection = newDirection; public Snake(){ initial(); } public void initial(){ //先清空所有的節(jié)點 body.removeAll(body); int x = Constant.WIDTH/2; int y = Constant.HEIGHT/2; //蛇的默認長度為7 for(int i = 0; i < 7; i++){ body.add(new Point(x--, y)); } } public void setSpeed(int speed){ this.speed = speed; } public void setLife(boolean life){ this.life = life; } public boolean getLife(){ return this.life; } public boolean getPause(){ return this.pause; } public void setPause(boolean pause){ this.pause = pause; } public void move(){ //蛇移動的實現(xiàn)所采用的數(shù)據(jù)結(jié)構(gòu)為:蛇尾刪除一個節(jié)點,蛇頭增加一個節(jié)點。 System.out.println("snake move"); if(!(oldDirection + newDirection == 0)){ oldDirection = newDirection; } lastTail = body.removeLast(); int x = body.getFirst().x; int y = body.getFirst().y; switch(oldDirection){ case UP: y--; break; case DOWN: y++; break; case LEFT: x--; break; case RIGHT: x++; break; } Point point = new Point(x, y); body.addFirst(point); } //當吃到一個食物的時候,把刪掉的蛇尾節(jié)點增加回來 public void eatFood(){ System.out.println("snake eat food"); body.addLast(lastTail); } public boolean isEatItself(){ for(int i = 2; i < body.size(); i++){ if(body.getFirst().equals(body.get(i))){ return true; } } return false; } public void drawMe(Graphics g){ System.out.println("draw snake"); //循環(huán)打印蛇的各個身體節(jié)點 for(Point p:body){ if(p.equals(body.getFirst())){ //當是蛇頭的時候,就設置顏色為橘色 g.setColor(Color.orange); }else{ g.setColor(Color.pink); } g.fill3DRect(p.x * Constant.CELL_SIZE, p.y * Constant.CELL_SIZE, Constant.CELL_SIZE, Constant.CELL_SIZE, true); } } public void changeDirection(int direction){ System.out.println("snake changeDirection"); this.newDirection = direction; } //內(nèi)部類,新增一個游戲線程 public class DriveSnake implements Runnable{ @Override public void run() { while(life){ if(!pause){ //只要讓蛇不動就可以暫停游戲 move(); } //監(jiān)聽蛇每次移動的情況 for(SnakeListener listener : snakeListener){ listener.snakeMove(Snake.this); } try { Thread.sleep(speed); } catch (InterruptedException e) { e.printStackTrace(); } } } } public void startMove(){ new Thread(new DriveSnake()).start(); } //增加監(jiān)聽器的方法 public void addSnakeListener(SnakeListener listener){ if(listener != null){ snakeListener.add(listener); } } //返回蛇的第一個身體節(jié)點 public Point getHead(){ return body.getFirst(); } //返回蛇的所有身體節(jié)點 public LinkedList<Point> getSnakeBody(){ return this.body; } public boolean died(){ this.life = false; return true; } }
package com.huai; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import com.huai.util.Constant; public class Food { private int x = 0; private int y = 0; //設置食物的默認顏色為紅色 private Color color = Color.red; public void newFood(Point point){ x = point.x; y = point.y; } //判斷是否被吃到 public boolean isAte(Snake snake){ if(snake.getHead().equals(new Point(x, y))){ System.out.println("food isAte"); return true; } return false; } public void setFoodColor(Color color){ this.color = color; } public Color getFoodColor(){ return this.color; } public void drawMe(Graphics g){ System.out.println("draw food"); g.setColor(this.getFoodColor()); g.fill3DRect(x * Constant.CELL_SIZE, y * Constant.CELL_SIZE, Constant.CELL_SIZE, Constant.CELL_SIZE, true); } }
package com.huai; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.LinkedList; import java.util.Random; import com.huai.util.Constant; public class Ground { //在二維數(shù)組中,當為1,表示是磚塊 private int[][] rock = new int[Constant.WIDTH][Constant.HEIGHT]; private boolean drawLine = true; public boolean isDrawLine() { return drawLine; } public void setDrawLine(boolean drawLine) { this.drawLine = drawLine; } public Ground(){ for(int x = 0; x < Constant.WIDTH; x++){ for(int y = 0; y < Constant.HEIGHT; y++){ rock[0][y] = 1; rock[x][0] = 1; rock[Constant.WIDTH-1][y] = 1; rock[y][Constant.HEIGHT-1] = 1; } } } //打印游戲的網(wǎng)格 public void drawGrid(Graphics g){ for(int x = 2; x < Constant.WIDTH; x++){ g.drawLine(x * Constant.CELL_SIZE, 0, x*Constant.CELL_SIZE, Constant.CELL_SIZE * Constant.HEIGHT); } for(int y = 2; y < Constant.HEIGHT; y++){ g.drawLine(0, y * Constant.CELL_SIZE, Constant.WIDTH*Constant.CELL_SIZE, y*Constant.CELL_SIZE); } } public void drawMe(Graphics g){ System.out.println("draw ground"); //打印圍墻 g.setColor(Color.pink); for(int x = 0; x < Constant.WIDTH; x++){ for(int y = 0; y < Constant.HEIGHT; y++){ if(rock[x][y] == 1){ g.fill3DRect(x * Constant.WIDTH, y * Constant.HEIGHT, Constant.CELL_SIZE, Constant.CELL_SIZE, true); } } } if(isDrawLine()){ g.setColor(Color.yellow); this.drawGrid(g); } } //得到一個隨機點 public Point getRandomPoint(Snake snake, Thorn thorn){ Random random = new Random(); boolean isUnderSnakebody = false; boolean isUnderThorn = false; int x,y = 0; LinkedList<Point> snakeBody = snake.getSnakeBody(); LinkedList<Point> thorns = thorn.getThorns(); do{ x = random.nextInt(Constant.WIDTH); y = random.nextInt(Constant.HEIGHT); for(Point p:snakeBody){ if(x == p.x && y == p.y){ isUnderSnakebody = true; } } for(Point point : thorns){ if(x == point.x && y == point.y){ isUnderThorn = true; } } }while(rock[x][y] == 1 && !isUnderSnakebody && !isUnderThorn); return new Point(x, y); } public boolean isSnakeHitRock(Snake snake){ System.out.println("snack hit rock"); for(int i = 0; i < Constant.WIDTH; i++){ for(int j = 0; j < Constant.HEIGHT; j++){ if(snake.getHead().x == i && snake.getHead().y == j && rock[i][j] == 1){ return true; } } } return false; } }
package com.huai import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.LinkedList; import com.huai.util.Constant; public class Thorn { int x, y; private LinkedList<Point> thorns = new LinkedList<Point>(); //返回所有荊棘的鏈表 public LinkedList<Point> getThorns(){ return this.thorns; } public void newThorn(Point point){ x = point.x; y = point.y; thorns.add(new Point(x, y)); } public void drawMe(Graphics g){ System.out.println("draw thorns"); for(Point p: thorns){ int[] xb = {p.x*Constant.CELL_SIZE, (p.x*Constant.CELL_SIZE +Constant.CELL_SIZE/2), (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE), (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE/4*3), (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE), (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE/2), p.x*Constant.CELL_SIZE, (p.x*Constant.CELL_SIZE+Constant.CELL_SIZE/4), p.x*Constant.CELL_SIZE}; int [] yb = {p.y*Constant.CELL_SIZE, (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE/4), p.y*Constant.CELL_SIZE, (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE/2), (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE), (int)(p.y*Constant.CELL_SIZE+Constant.CELL_SIZE*0.75), (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE), (p.y*Constant.CELL_SIZE+Constant.CELL_SIZE/2), p.y*Constant.CELL_SIZE}; g.setColor(Color.darkGray); g.fillPolygon(xb, yb, 8); } } public boolean isSnakeHitThorn(Snake snake){ for(Point points : thorns){ if(snake.getHead().equals(points)){ System.out.println("hit thorn"); return true; } } return false; } }
package com.huai.listener; import com.huai.Snake; public interface SnakeListener { public void snakeMove(Snake snake); } package com.huai.util;public class Constant { public static int CELL_SIZE = 20; public static int WIDTH = 20; public static int HEIGHT = 20; }
package com.huai.view; import java.awt.Color; import java.awt.Graphics;import javax.swing.JPanel;import com.huai.Food; import com.huai.Ground; import com.huai.Snake; import com.huai.Thorn; import com.huai.util.Constant;public class GamePanel extends JPanel{ /** * */ private static final long serialVersionUID = 1L; Snake snake; Food food; Ground ground; Thorn thorn; public void display(Snake snake, Food food, Ground ground, Thorn thorn){ this.snake = snake; this.food = food; this.ground = ground; this.thorn = thorn; System.out.println("display gamePanel"); this.repaint(); } @Override protected void paintComponent(Graphics g) { if(snake != null && food != null && ground != null){ g.setColor(Color.lightGray); g.fillRect(0, 0, Constant.WIDTH*Constant.CELL_SIZE, Constant.HEIGHT*Constant.CELL_SIZE); snake.drawMe(g); food.drawMe(g); ground.drawMe(g); thorn.drawMe(g); }else{ System.out.println("snake = null || food = null || ground = null"); } } }
package com.huai.controller; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent;import com.huai.Food; import com.huai.Ground; import com.huai.Snake; import com.huai.Thorn; import com.huai.listener.SnakeListener; import com.huai.view.GamePanel;public class Controller extends KeyAdapter implements SnakeListener{ /** * 整個游戲的控制類,屬于MVC設計框架中的Controller * 其中包括控制游戲的監(jiān)聽事件和游戲邏輯 */ Snake snake; Food food; Ground ground; GamePanel gamePanel; Thorn thorn; public Controller(){} //利用構(gòu)造方法初始化對象 public Controller(Snake snake, Food food, Ground ground, GamePanel gamePanel, Thorn thorn) { super(); this.snake = snake; this.food = food; this.ground = ground; this.gamePanel = gamePanel; this.thorn = thorn; } @Override public void keyPressed(KeyEvent e) { switch(e.getKeyCode()){ case KeyEvent.VK_UP: snake.changeDirection(Snake.UP); snake.setSpeed(150); break; case KeyEvent.VK_DOWN: snake.changeDirection(Snake.DOWN); snake.setSpeed(150); break; case KeyEvent.VK_LEFT: snake.changeDirection(Snake.LEFT); snake.setSpeed(150); break; case KeyEvent.VK_RIGHT: snake.changeDirection(Snake.RIGHT); snake.setSpeed(150); break; case KeyEvent.VK_ENTER: if(!snake.getPause() && snake.getLife()){ //暫停游戲 snake.setPause(true);; }else if(!snake.getLife()){ //重新開始游戲 snake.setLife(true); snake.initial(); snake.changeDirection(Snake.UP); thorn.getThorns().removeAll(thorn.getThorns()); this.startGame(); }else{ snake.setPause(false); } break; case KeyEvent.VK_L: //當按下L按鈕時,是否顯示游戲網(wǎng)格 if(ground.isDrawLine()){ ground.setDrawLine(false); }else{ ground.setDrawLine(true); } break; } } @Override public void keyReleased(KeyEvent e) { switch(e.getKeyCode()){ case KeyEvent.VK_UP: snake.setSpeed(400); break; case KeyEvent.VK_DOWN: snake.setSpeed(400); break; case KeyEvent.VK_LEFT: snake.setSpeed(400); break; case KeyEvent.VK_RIGHT: snake.setSpeed(400); break; } } //這是實現(xiàn)SnakeListener監(jiān)聽器所Override的方法 @Override public void snakeMove(Snake snake) { //顯示snake ,food,ground,和thorn gamePanel.display(snake, food, ground, thorn); if(ground.isSnakeHitRock(snake)){ snake.died(); } if(snake.isEatItself()){ snake.died(); } if(food.isAte(snake)){ snake.eatFood(); food.newFood(ground.getRandomPoint(snake, thorn)); thorn.newThorn(ground.getRandomPoint(snake, thorn)); } if(thorn.isSnakeHitThorn(snake)){ snake.died(); } } public void startGame(){ snake.startMove();//這個將會啟動一個新的線程 food.newFood(ground.getRandomPoint(snake, thorn)); thorn.newThorn(ground.getRandomPoint(snake, thorn)); } }
package com.huai.game; import java.awt.BorderLayout; import java.awt.Color;import javax.swing.JFrame; import javax.swing.JLabel;import com.huai.Food; import com.huai.Ground; import com.huai.Snake; import com.huai.Thorn; import com.huai.controller.Controller; import com.huai.util.Constant; import com.huai.view.GamePanel;public class Game { public static void main(String args[]){ Snake snake = new Snake(); Food food = new Food(); GamePanel gamePanel = new GamePanel(); Ground ground = new Ground(); Thorn thorn = new Thorn(); Controller controller = new Controller(snake, food, ground, gamePanel, thorn); JFrame frame = new JFrame("懷哥的小小蛇兒游戲"); frame.add(gamePanel); frame.setBackground(Color.magenta); frame.setSize(Constant.WIDTH*Constant.CELL_SIZE+6, Constant.HEIGHT*Constant.CELL_SIZE+40); gamePanel.setSize(Constant.WIDTH*Constant.CELL_SIZE, Constant.HEIGHT*Constant.CELL_SIZE); frame.add(gamePanel); frame.setResizable(false);//不可改變窗口大小 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); gamePanel.addKeyListener(controller); snake.addSnakeListener(controller); frame.addKeyListener(controller); JLabel label1 = new JLabel(); label1.setBounds(0, 400, 400, 100); label1.setText(" ENTER=>>PAUSE or AGAIN; " + " L=>DRAWGRID"); label1.setForeground(Color.BLACK); frame.add(label1, BorderLayout.SOUTH); controller.startGame(); } }
更多精彩游戲,請參考專題《java經(jīng)典小游戲》
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
mybatis解決<foreach>標簽不能超過1000的問題
MyBatis是一個開源的持久層框架,它可以幫助開發(fā)者簡化數(shù)據(jù)庫操作的編寫,而foreach是MyBatis中的一個重要標簽,用于在SQL語句中進行循環(huán)操作,本文主要給大家介紹了mybatis解決<foreach>標簽不能超過1000的問題,需要的朋友可以參考下2024-05-05關(guān)于@Autowired注入依賴失敗的問題及解決
這篇文章主要介紹了關(guān)于@Autowired注入依賴失敗的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08Java傳入用戶名和密碼并自動提交表單實現(xiàn)登錄到其他系統(tǒng)的實例代碼
這篇文章主要介紹了Java傳入用戶名和密碼并自動提交表單實現(xiàn)登錄到其他系統(tǒng),非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-01-01SpringCloud?Gateway詳細分析實現(xiàn)負載均衡與熔斷和限流
這篇文章主要介紹了SpringCloud?Gateway實現(xiàn)路由轉(zhuǎn)發(fā),負載均衡,熔斷和限流,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07MAC上IntelliJ IDEA的svn無法保存密碼解決方案
今天小編就為大家分享一篇關(guān)于MAC上IntelliJ IDEA的svn無法保存密碼解決方案,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10Mybatis Order by動態(tài)參數(shù)防注入方式
這篇文章主要介紹了Mybatis Order by動態(tài)參數(shù)防注入方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04springboot構(gòu)建docker鏡像并推送到阿里云
本文主要介紹了springboot構(gòu)建docker鏡像并推送到阿里云,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05