java实现贪吃蛇极速版
更新时间:2021年09月13日 16:01:44 作者:July
这篇文章主要为大家分享了java贪吃蛇极速版,贪吃蛇经典手机游戏,既简单又耐玩,本文用java来实现下贪吃蛇小游戏,感兴趣的小伙伴可以参考下
本文为大家推荐了一款由java实现经典小游戏:贪吃蛇,相信大家都玩过,如何实现的呐?
效果图:
废话不多说,直接奉上代码:
1、
1 2 3 4 5 6 7 8 9 10 11 | 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、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 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){ // 运行状态下,处理的按键 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 : } } // 任何情况下处理的按键,按键导致重新启动游戏 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、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | 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 ; // 运行状态 int timeInterval = 200 ; // 时间间隔,毫秒 double speedChangeRate = 0.75 ; // 每次得速度变化率 boolean paused = false ; // 暂停标志 int score = 0 ; // 得分 int countMove = 0 ; // 吃到食物前移动的次数 // 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 ; // 暂停标志 score = 0 ; // 得分 countMove = 0 ; // 吃到食物前移动的次数 // 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就变为: // [10,14]-[10,15]-[11,15]-[12,15]~~[19,15] nodeArray.addLast( new Node(x, y)); matrix[x][y] = true ; } // 创建食物 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; // 根据方向增减坐标值 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 ; // 触到边线,失败 } public void run() { running = true ; while (running) { try { Thread.sleep(timeInterval); } catch (Exception e) { break ; } if (!paused) { if (moveOn()) { setChanged(); // Model通知View数据已经更新 notifyObservers(); } else { JOptionPane.showMessageDialog( null , "you failed" , "Game Over" , JOptionPane.INFORMATION_MESSAGE); break ; } } } running = false ; } 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); } 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、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 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(); // 创建顶部的分数显示 labelScore = new JLabel( "Score:" ); cp.add(labelScore, BorderLayout.NORTH); // 创建中间的游戏显示区域 paintCanvas = new Canvas(); paintCanvas.setSize(canvasWidth + 1 , canvasHeight + 1 ); paintCanvas.addKeyListener(control); cp.add(paintCanvas, BorderLayout.CENTER); // 创建底下的帮助栏 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(); } } |
本文的目的就是带着大家回味经典,但是更主要的目的就是帮助大家学习好java程序设计。
微信公众号搜索 “ 脚本之家 ” ,选择关注
程序猿的那些事、送书等活动等着你
相关文章
springboot + vue 实现递归生成多级菜单(实例代码)
这篇文章主要介绍了springboot + vue 实现递归生成多级菜单,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下2019-12-12maven package 打包报错 Failed to execute goal的解决
这篇文章主要介绍了maven package 打包报错 Failed to execute goal的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-11-11SpringBoot3整合SpringDoc实现在线接口文档的详细过程
这篇文章主要介绍了SpringBoot3整合SpringDoc实现在线接口文档的详细过程,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧2024-06-06
最新评论