日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

java實(shí)現(xiàn)貪吃蛇小游戲

瀏覽:168日期:2022-08-28 08:57:58

本文實(shí)例為大家分享了java實(shí)現(xiàn)貪吃蛇小游戲的具體代碼,供大家參考,具體內(nèi)容如下

java實(shí)現(xiàn)貪吃蛇小游戲

這是MVC模式的完整Java項(xiàng)目,編譯運(yùn)行SnakeApp.java即可開始游戲。

可擴(kuò)展功能:

1、積分功能:可以創(chuàng)建得分規(guī)則的類(模型類的一部分), 在GameController的run()方法中計(jì)算得分2、變速功能:比如加速功能,減速功能,可以在GameController的keyPressed()方法中針對(duì)特定的按鍵設(shè)置每一次移動(dòng)之間的時(shí)間間隔,將Thread.sleep(Settings.DEFAULT_MOVE_INTERVAL);替換為動(dòng)態(tài)的時(shí)間間隔即可3、更漂亮的游戲界面:修改GameView中的drawXXX方法,比如可以將食物渲染為一張圖片,Graphics有drawImage方法

View

SnakeApp.java

/* * 屬于View,用來(lái)根據(jù)相應(yīng)的類展示出對(duì)應(yīng)的游戲主界面,也是接收控制信息的第一線。 */public class SnakeApp { public void init() { //創(chuàng)建游戲窗體 JFrame window = new JFrame('一只長(zhǎng)不大的蛇'); //初始化500X500的棋盤,用來(lái)維持各種游戲元素的狀態(tài),游戲的主要邏輯部分 Grid grid = new Grid(50*Settings.DEFAULT_NODE_SIZE,50*Settings.DEFAULT_NODE_SIZE); //傳入grid參數(shù),新建界面元素對(duì)象 GameView gameView = new GameView(grid);//繪制游戲元素的對(duì)象 //初始化面板 gameView.initCanvas(); //根據(jù)棋盤信息建立控制器對(duì)象 GameController gameController = new GameController(grid); //設(shè)置窗口大小 window.setPreferredSize(new Dimension(526,548)); //往窗口中添加元素,面板對(duì)象被加入到窗口時(shí),自動(dòng)調(diào)用其中的paintComponent方法。 window.add(gameView.getCanvas(),BorderLayout.CENTER); //畫出蛇和棋盤和食物 GameView.draw(); //注冊(cè)窗口監(jiān)聽器 window.addKeyListener((KeyListener)gameController); //啟動(dòng)線程 new Thread(gameController).start(); //窗口關(guān)閉的行為 window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //設(shè)置窗口大小不可變化 window.setResizable(false); //渲染和顯示窗口 window.pack(); window.setVisible(true); } //可以忽略,以后每個(gè)類中都有這么一個(gè)測(cè)試模塊 public static void main(String[] args) { SnakeApp snakeApp = new SnakeApp(); snakeApp.init(); }}

GameView.java

/* * 屬于View,用于繪制地圖、蛇、食物*/ /* Graphics 相當(dāng)于一個(gè)畫筆。對(duì)象封裝了 Java 支持的基本呈現(xiàn)操作所需的狀態(tài)信息。此狀態(tài)信息包括以下屬性: 要在其上繪制的 Component 對(duì)象。 呈現(xiàn)和剪貼坐標(biāo)的轉(zhuǎn)換原點(diǎn)。 當(dāng)前剪貼區(qū)。 當(dāng)前顏色。 當(dāng)前字體。 當(dāng)前邏輯像素操作函數(shù)(XOR 或 Paint)。 當(dāng)前 XOR 交替顏色*//* java.awt.Component的repaint()方法 作用:更新組件。 如果此組件不是輕量級(jí)組件,則為了響應(yīng)對(duì) repaint 的調(diào)用,AWT 調(diào)用 update 方法。可以假定未清除背景。 Component 的 update 方法調(diào)用此組件的 paint 方法來(lái)重繪此組件。為響應(yīng)對(duì) repaint 的調(diào)用而需要其他工作的子類通常重寫此方法。重寫此方法的 Component 子類應(yīng)該調(diào)用 super.update(g),或者直接從其 update 方法中調(diào)用 paint(g)。 圖形上下文的原點(diǎn),即它的(0,0)坐標(biāo)點(diǎn)是此組件的左上角。圖形上下文的剪貼區(qū)域是此組件的邊界矩形。 */public class GameView { private final Grid grid; private static JPanel canvas;//畫板,用于在這上面制作畫面,然后返回。 public GameView(Grid grid) { this.grid = grid; } //重新繪制游戲界面元素,不斷重新調(diào)用paintComponent方法覆蓋原本的面板。 public static void draw() { canvas.repaint(); } //獲取畫板對(duì)象的接口 public JPanel getCanvas() { return canvas; } //對(duì)畫板進(jìn)行初始化 public void initCanvas() { canvas = new JPanel() { //指向一個(gè)方法被覆蓋的新面板子類對(duì)象 //paintComponent()繪制此容器中的每個(gè)組件,Swing會(huì)在合適的時(shí)機(jī)去調(diào)用這個(gè)方法,展示出合適的界面,這就是典型的回調(diào)(callback)的概念。 public void paintComponent(Graphics graphics) { super.paintComponent(graphics); //這里必須調(diào)用一下父類 也就是 container的重繪方法,否則表現(xiàn)為之前的繪圖不會(huì)覆蓋 drawGridBackground(graphics);//畫出背景網(wǎng)格線 drawSnake(graphics, grid.getSnake());//畫蛇 drawFood(graphics, grid.getFood());//畫食物 } }; } //畫蛇 public void drawSnake(Graphics graphics, Snake snake) { for(Iterator<Node> i = snake.body.iterator();i.hasNext();) { Node bodyNode = (Node)i.next(); drawSquare(graphics, bodyNode,Color.BLUE); } } //畫食物 public void drawFood(Graphics graphics, Node food) { drawCircle(graphics,food,Color.ORANGE); } //畫格子背景,方便定位Snake運(yùn)動(dòng)軌跡,橫豎各以10為單位的50個(gè)線。 public void drawGridBackground(Graphics graphics) { graphics.setColor(Color.GRAY); canvas.setBackground(Color.BLACK); for(int i=0 ; i < 50 ; i++) { graphics.drawLine(0, i*Settings.DEFAULT_NODE_SIZE, this.grid.getWidth(), i*Settings.DEFAULT_NODE_SIZE); } for(int i=0 ; i <50 ; i++) { graphics.drawLine(i*Settings.DEFAULT_NODE_SIZE, 0, i*Settings.DEFAULT_NODE_SIZE , this.grid.getHeight()); } graphics.setColor(Color.red); graphics.fillRect(0, 0, this.grid.width, Settings.DEFAULT_NODE_SIZE); graphics.fillRect(0, 0, Settings.DEFAULT_NODE_SIZE, this.grid.height); graphics.fillRect(this.grid.width, 0, Settings.DEFAULT_NODE_SIZE,this.grid.height); graphics.fillRect(0, this.grid.height, this.grid.width+10,Settings.DEFAULT_NODE_SIZE); } /* * public abstract void drawLine(int x1,int y1,int x2,int y2) 在此圖形上下文的坐標(biāo)系中,使用當(dāng)前顏色在點(diǎn) (x1, y1) 和 (x2, y2) 之間畫一條線。 參數(shù): x1 - 第一個(gè)點(diǎn)的 x 坐標(biāo)。 y1 - 第一個(gè)點(diǎn)的 y 坐標(biāo)。 x2 - 第二個(gè)點(diǎn)的 x 坐標(biāo)。 y2 - 第二個(gè)點(diǎn)的 y 坐標(biāo)。 */ //提供直接出現(xiàn)游戲結(jié)束的選項(xiàng)框的功能。 public static void showGameOverMessage() { JOptionPane.showMessageDialog(null,'游戲結(jié)束','短暫的蛇生到此結(jié)束', JOptionPane.INFORMATION_MESSAGE); } //畫圖形的具體方法:private void drawSquare(Graphics graphics, Node squareArea, Color color) { graphics.setColor(color); int size = Settings.DEFAULT_NODE_SIZE; graphics.fillRect(squareArea.getX(), squareArea.getY(), size - 1, size - 1);}private void drawCircle(Graphics graphics, Node squareArea, Color color) { graphics.setColor(color); int size = Settings.DEFAULT_NODE_SIZE; graphics.fillOval(squareArea.getX(), squareArea.getY(), size, size);}}

Controller

GameController

/* * 接收窗體SnakeApp傳遞過(guò)來(lái)的有意義的事件,然后傳遞給Grid,讓Grid即時(shí)的更新狀態(tài)。 * 同時(shí)根據(jù)最新狀態(tài)渲染出游戲界面讓SnakeApp顯示 * */public class GameController implements KeyListener, Runnable{ private Grid grid; private boolean running; public GameController(Grid grid){ this.grid = grid; this.running = true; } @Override public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); switch(keyCode) { case KeyEvent.VK_UP: grid.changeDirection(Direction.UP); break; case KeyEvent.VK_DOWN: grid.changeDirection(Direction.DOWN); break; case KeyEvent.VK_LEFT: grid.changeDirection(Direction.LEFT); break; case KeyEvent.VK_RIGHT: grid.changeDirection(Direction.RIGHT); break; } isOver(grid.nextRound()); GameView.draw(); } private void isOver(boolean flag) { if(!flag) {//如果下一步更新棋盤時(shí),出現(xiàn)游戲結(jié)束返回值(如果flag為假)則 this.running = false; GameView.showGameOverMessage(); System.exit(0); } } @Override /*run()函數(shù)中的核心邏輯是典型的控制器(Controller)邏輯: 修改模型(Model):調(diào)用Grid的方法使游戲進(jìn)入下一步 更新視圖(View):調(diào)用GameView的方法刷新頁(yè)面*/ public void run() { while(running) { try { Thread.sleep(Settings.DEFAULT_MOVE_INTERVAL); isOver(grid.nextRound()); GameView.draw(); } catch (InterruptedException e) { break; } // 進(jìn)入游戲下一步 // 如果結(jié)束,則退出游戲 // 如果繼續(xù),則繪制新的游戲頁(yè)面 } running = false; } @Override public void keyTyped(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { }}

Model

Grid

/* * 隨機(jī)生成食物,維持貪吃蛇的狀態(tài),根據(jù)SnakeApp中的用戶交互來(lái)控制游戲狀態(tài)。 */public class Grid { private Snake snake; int width; int height; Node food; private Direction snakeDirection =Direction.LEFT; public Grid(int length, int high) { super(); this.width = length; this.height = high; initSnake(); food = creatFood(); } //在棋盤上初始化一個(gè)蛇 private void initSnake() { snake = new Snake(); int x = width/2; int y = height/2; for(int i = 0;i<5;i++) { snake.addTail(new Node(x, y)); x = x+Settings.DEFAULT_NODE_SIZE; } } //棋盤上隨機(jī)制造食物的功能。 //一直循環(huán)獲取隨機(jī)值,直到三個(gè)條件都不滿足。 private Node creatFood() { int x,y; do { x =(int)(Math.random()*100)+10; y =(int)(Math.random()*100)+10; System.out.println(x); System.out.println(y); System.out.println(this.width); System.out.println(this.height); }while(x>=this.width-10 || y>=this.height-10 || snake.hasNode(new Node(x,y))); food = new Node(x,y); return food; } //提供下一步更新棋盤的功能,移動(dòng)后更新游戲和蛇的狀態(tài)。 public boolean nextRound() { Node trail = snake.move(snakeDirection); Node snakeHead = snake.getBody().removeFirst();//將頭部暫時(shí)去掉,拿出來(lái)判斷是否身體和頭部有重合的點(diǎn) if(snakeHead.getX()<=width-10 && snakeHead.getX()>=10 && snakeHead.getY()<=height-10 && snakeHead.getY()>=10 && !snake.hasNode(snakeHead)) {//判斷吃到自己和撞到邊界 if(snakeHead.equals(food)) { //原本頭部是食物的話,將move操作刪除的尾部添加回來(lái) snake.addTail(trail); food = creatFood(); } snake.getBody().addFirst(snakeHead); return true;//更新棋盤狀態(tài)并返回游戲是否結(jié)束的標(biāo)志 } return false; } public Node getFood() { return food; } public Snake getSnake() { return snake; } public int getWidth() { return width; } public int getHeight() { return height; } //提供一個(gè)更改貪吃蛇前進(jìn)方向的方法 public void changeDirection(Direction newDirection){ snakeDirection = newDirection; }}

Snake

/* * 蛇類,實(shí)現(xiàn)了自身數(shù)據(jù)結(jié)構(gòu),以及移動(dòng)的功能 */public class Snake implements Cloneable{ public LinkedList<Node> body = new LinkedList<>(); public Node move(Direction direction) { //根據(jù)方向更新貪吃蛇的body //返回移動(dòng)之前的尾部Node(為了吃到時(shí)候后增加尾部長(zhǎng)度做準(zhǔn)備) Node n;//臨時(shí)存儲(chǔ)新頭部移動(dòng)方向的結(jié)點(diǎn) switch (direction) { case UP: n = new Node(this.getHead().getX(),this.getHead().getY()-Settings.DEFAULT_NODE_SIZE); break; case DOWN: n = new Node(this.getHead().getX(),this.getHead().getY()+Settings.DEFAULT_NODE_SIZE); break; case RIGHT: n = new Node(this.getHead().getX()+Settings.DEFAULT_NODE_SIZE,this.getHead().getY()); break; default: n = new Node(this.getHead().getX()-Settings.DEFAULT_NODE_SIZE,this.getHead().getY()); } Node temp = this.body.getLast(); this.body.addFirst(n); this.body.removeLast(); return temp; } public Node getHead() { return body.getFirst(); } public Node getTail() { return body.getLast(); } public Node addTail(Node area) { this.body.addLast(area); return area; } public LinkedList<Node> getBody(){ return body; } //判斷參數(shù)結(jié)點(diǎn)是否在蛇身上 public boolean hasNode(Node node) { Iterator<Node> it = body.iterator(); Node n = new Node(0,0); while(it.hasNext()) { n = it.next(); if(n.getX() == node.getX() && n.getY() == node.getY()) { return true; } } return false; }}

Direction

/* * 用來(lái)控制蛇的移動(dòng)方向 */public enum Direction { UP(0), DOWN(1), LEFT(2), RIGHT(3); //調(diào)用構(gòu)造方法對(duì)方向枚舉實(shí)例進(jìn)行代碼初始化 //成員變量 private final int directionCode; //成員方法 public int directionCode() { return directionCode; } Direction(int directionCode){ this.directionCode = directionCode; }}

Node

public class Node { private int x; private int y; public Node(int x, int y) { this.x = ((int)(x/10))*10; this.y = ((int)(y/10))*10; }//使用這種方法可以使得節(jié)點(diǎn)坐標(biāo)不會(huì)出現(xiàn)個(gè)位數(shù) public int getX() { return x; } public int getY() { return y; } @Override //判斷兩個(gè)Node是否相同 public boolean equals(Object n) { Node temp; if(n instanceof Node) { temp = (Node)n; if(temp.getX()==this.getX() && temp.getY()==this.getY()) return true; } return false; }}

Settings

public class Settings { public static int DEFAULT_NODE_SIZE = 10;//每一個(gè)節(jié)點(diǎn)方塊的單位 public static int DEFAULT_MOVE_INTERVAL = 200;//蛇移動(dòng)時(shí)間間隔}

更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:

C++經(jīng)典小游戲匯總

python經(jīng)典小游戲匯總

python俄羅斯方塊游戲集合

JavaScript經(jīng)典游戲 玩不停

javascript經(jīng)典小游戲匯總

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
女生影院久久| 中文字幕日韩高清在线| 日韩国产91| 亚洲影院天堂中文av色| 中文在线日韩| 日本va欧美va欧美va精品| 日韩国产精品久久久久久亚洲| 久久国产日韩欧美精品| 麻豆91在线播放| se01亚洲视频 | 岛国av免费在线观看| 麻豆91精品视频| 四虎国产精品免费观看| 久久久久久美女精品| 老司机精品久久| 国产精品夜夜夜| 成人自拍av| 免费一区二区视频| 国产精品美女在线观看直播| 日韩在线看片| 亚洲欧美日本国产| 国产一区二区三区日韩精品| 欧美精选一区二区三区| 天堂久久av| 狠狠久久伊人中文字幕| 日韩一区电影| 麻豆精品91| 国产精品久久久久久久久久白浆 | 免费在线视频一区| 久久一区精品| 国产一区白浆| 麻豆精品蜜桃视频网站| 亚洲性色av| 亚洲字幕久久| 四季av一区二区凹凸精品| 国产亚洲午夜| 精品国产美女a久久9999| 亚洲婷婷免费| 欧美日韩一区二区高清| 亚洲成人二区| 国产精品日本一区二区三区在线| 欧美亚洲在线日韩| 国产丝袜一区| 蜜桃一区二区三区| 国产精品jk白丝蜜臀av小说| 欧美特黄视频| 日韩av二区| 日韩精品中文字幕一区二区| 青青久久av| 国产欧美69| 在线综合视频| 首页国产精品| 日本视频中文字幕一区二区三区| 日韩久久电影| 国产精品白浆| 亚洲精品女人| 久久九九电影| 久久男人av| 亚洲一区二区三区久久久| 97精品国产福利一区二区三区| 日韩国产欧美在线视频| 欧美精品一区二区三区精品| 久久精品国产免费| 日本一区福利在线| 99pao成人国产永久免费视频 | 国产欧美亚洲一区| 狠狠爱成人网| 日韩中文首页| 欧美韩日一区| 免费在线日韩av| 日本午夜免费一区二区| 欧美~级网站不卡| 国产+成+人+亚洲欧洲在线| 欧美日韩视频免费看| 免费在线成人网| 亚洲在线观看| 欧美日韩国产在线观看网站 | 日本午夜精品一区二区三区电影| 六月婷婷一区| 国产精品av一区二区| 国产粉嫩在线观看| 美女视频网站久久| 国产精品片aa在线观看| 日韩av网站在线免费观看| 亚洲免费毛片| 亚洲精品影视| 亚洲一区二区三区中文字幕在线观看| 亚洲激情不卡| 精品在线播放| 99国产精品免费视频观看| 国产在线看片免费视频在线观看| 国产精品调教视频| 国产精品久久久久久妇女| 国产欧美三级| 国产精品一区二区精品| 国产日韩一区二区三区在线播放| 热久久久久久| 国产精品久久久久久久久久妞妞| 国产精品一线| 国产精品1区| 激情中国色综合| 亚洲国产成人二区| 日韩中文影院| 夜久久久久久| 亚洲精选91| 清纯唯美亚洲综合一区| 国产精品午夜一区二区三区| 精品伊人久久久| 久久久久久自在自线| 91视频久久| 99久久婷婷这里只有精品| 欧美久久精品一级c片| 亚洲精品综合| 久久精品国产99国产精品| 久久男人av资源站| 欧美不卡高清| 另类激情亚洲| 国产乱子精品一区二区在线观看 | 国产福利一区二区三区在线播放| 久久精品毛片| 国产91欧美| 中国女人久久久| 日本精品国产| 免费在线欧美黄色| 久久男人天堂| 日韩一级精品| 国产毛片精品| 欧美日韩尤物久久| 蜜臀久久99精品久久久画质超高清| 青青伊人久久| 波多视频一区| 免费日韩一区二区| 国产精品夜夜夜| 影视先锋久久| 日本亚洲最大的色成网站www| 精品国产a一区二区三区v免费| 久久久蜜桃一区二区人| 亚洲精品视频一二三区| 久久超级碰碰| 欧美日韩视频| 国产精品视频一区二区三区| 亚洲天堂1区| 青青草视频一区| 久久免费国产| 日本成人在线网站| 99成人在线视频| 欧美精品影院| 亚洲天堂黄色| 欧美精品不卡| 99pao成人国产永久免费视频| 久久99免费视频| aⅴ色国产欧美| 97精品一区| 蜜臀av性久久久久蜜臀aⅴ四虎| 精品色999| 亚洲乱码视频| 久久九九电影| 国产精品一区2区3区| 亚洲大全视频| 免费日韩成人| 亚洲不卡视频| 日韩欧美一区二区三区免费看| 日韩中文字幕| 国产综合婷婷| 久久这里只有| 亚洲精品极品| 黄页网站一区| 日产精品一区| 国产精品天天看天天狠| 喷白浆一区二区| 99久久亚洲精品| 粉嫩av一区二区三区四区五区 | 一本综合精品| 99久久婷婷| 日本一二区不卡| 国产精品欧美三级在线观看| 日韩精品一卡二卡三卡四卡无卡| 久久中文字幕二区| 精品国产一区二区三区噜噜噜| 日本不卡一区二区| 国产亚洲在线| 欧美日韩国产高清电影| 91亚洲成人| 国产精品s色| 日本午夜精品久久久| 亚洲影视一区| 蜜乳av另类精品一区二区| 91精品一区二区三区综合在线爱| 精品久久99| 精品视频一区二区三区在线观看| 日韩中文字幕| 亚洲人成亚洲精品| 日韩视频一区二区三区在线播放免费观看| 中文字幕在线官网| 成人三级高清视频在线看| 久久精品五月| 久久久精品国产**网站| 日韩av一区二区三区| 日韩福利视频一区| 天堂va在线高清一区|