
用java写贪吃蛇游戏需要学到什么程度
楼主没有看到蛇移动的本质,蛇虽然是分成很多块,但他们还是一个整体,每一块的移动都和上一块有关,所以不需要对每一块都进行判断。
原理:把蛇身体的每一块看成一个对象(对象存储该块的坐标和相关信息),作为节点存储在线性链表中,再设置一个变量标志蛇的方向(通过按键可以改变)。
一般人都是让每一个节点等于他指向的下一个节点,并让头节点改变位置来实现转弯和移动,这个算法复杂度太高(O(n)),实际上只要做两步操作,插入一个头节点,删除一个尾节点就可以了,新插入的头节点位置根据蛇当前的方向决定 用一个数组将蛇头的行径记录下来,然后第二段的下一个方格设置为蛇头走过的方格,这样子蛇走过的路径都是前一段走过的,最后将跟着蛇头走了,比如蛇身的路径 for(int i=snakeLength-1;i>0;i--){rows[i]=rows[i-1];\\\/\\\/依次将蛇前面一段走过行的路段赋值给蛇的下一段cols[i]=cols[i-1];\\\/\\\/依次将蛇前面一段走过列的路段赋值给蛇的下一段}for(int i=1;i 要刷新面板 用MVC方式实现的贪吃蛇游戏,共有4个类。 运行GreedSnake运行即可。 主要是观察者模式的使用,我已经添加了很多注释了。 1、\\\/* * 程序名称:贪食蛇 * 原作者:BigF * 修改者:algo * 说明:我以前也用C写过这个程序,现在看到BigF用Java写的这个,发现虽然作者自称是Java的初学者, * 但是明显编写程序的素养不错,程序结构写得很清晰,有些细微得地方也写得很简洁,一时兴起之 * 下,我认真解读了这个程序,发现数据和表现分开得很好,而我近日正在学习MVC设计模式, * 因此尝试把程序得结构改了一下,用MVC模式来实现,对源程序得改动不多。 * 我同时也为程序增加了一些自己理解得注释,希望对大家阅读有帮助。 *\\\/package mvcTest;\\\/** * @author WangYu * @version 1.0 * Description: * <\\\/pre> * Create on :Date :2005-6-13 Time:15:57:16 * LastModified: * History: *\\\/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.javaimport java.awt.event.KeyEvent;import java.awt.event.KeyListener;\\\/** * MVC中的Controler,负责接收用户的操作,并把用户操作通知Model *\\\/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、\\\/* * *\\\/package mvcTest;\\\/** * 游戏的Model类,负责所有游戏相关数据及运行 * @author WangYu * @version 1.0 * Description: * <\\\/pre> * Create on :Date :2005-6-13 Time:15:58:33 * LastModified: * History: *\\\/\\\/\\\/SnakeModel.javaimport javax.swing.*;import java.util.Arrays;import java.util.LinkedList;import java.util.Observable;import java.util.Random;\\\/** * 游戏的Model类,负责所有游戏相关数据及运行 *\\\/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; } } \\\/** * 运行一次 * @return *\\\/ 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、package mvcTest;\\\/\\\/SnakeView.javaimport javax.swing.*;import java.awt.*;import java.util.Iterator;import java.util.LinkedList;import java.util.Observable;import java.util.Observer;\\\/** * MVC模式中得Viewer,只负责对数据的显示,而不用理会游戏的控制逻辑 *\\\/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视频就有贪吃蛇 有完成后的作品 用Java编写的贪吃蛇代码下面是我用java编写的一个贪吃蛇游戏源代码.我个人是比较喜欢玩游戏的,所以学习编程二年多了,很想做个游戏程序,由于能力有限,一直没能做好,后来突然看同学在手机上玩“贪吃蛇”,故想做出来,其一是因为此游戏界面容易设计,算法也比较简单,今天我就把我程序的代码和算法介绍一下,顺便把程序界面皮肤设计说一下......程序中一个关于游戏信息的类如下,由于类的说明在程序中写的很清楚了,就不再多解释了:#includetime.h\\\/\\\/方向定义constCPointUP(CPoint(0,-1));constCPointDOWN(CPoint(0,1));constCPointLEFT(CPoint(-1,0));constCPointRIGHT(CPoint(1,0));\\\/\\\/速度快慢定义constintHIGH=75;constintNORMAL=180;constintSLOW=300;constintMAX=80;\\\/\\\/表示转向数constintLENGTH=10;classGameMsg{public:GameMsg(void):m_icon(0){InitGame();}voidInitGame(intup=VK_UP,intdown=VK_DOWN,intleft=VK_LEFT,intright=VK_RIGHT){srand((unsigned)time(NULL));m_gameSpeed=NORMAL;m_speedNum=2;m_snakeNum=4;for(inti=0;i J2ME贪吃蛇源代码——200行左右,包含详细注释 package snake;import javax.microedition.midlet.*;import javax.microedition.lcdui.*;public class SnakeMIDlet extends MIDlet {SnakeCanvas displayable = new SnakeCanvas();public SnakeMIDlet() {Display.getDisplay(this).setCurrent(displayable);}public void startApp() {}public void pauseApp() {}public void destroyApp(boolean unconditional) {}}\\\/\\\/文件名:SnakeCanvas.javapackage snake;import java.util.*;import javax.microedition.lcdui.*;\\\/*** 贪吃蛇游戏*\\\/public class SnakeCanvas extends Canvas implements Runnable{\\\/**存储贪吃蛇节点坐标,其中第二维下标为0的代表x坐标,第二维下标是1的代表y坐标*\\\/int[][] snake = new int[200][2];\\\/**已经使用的节点数量*\\\/int snakeNum;\\\/**贪吃蛇运动方向,0代表向上,1代表向下,2代表向左,3代表向右*\\\/int direction;\\\/*移动方向*\\\/\\\/**向上*\\\/private final int DIRECTION_UP = 0;\\\/**向下*\\\/private final int DIRECTION_DOWN = 1;\\\/**向左*\\\/private final int DIRECTION_LEFT = 2;\\\/**向右*\\\/private final int DIRECTION_RIGHT = 3;\\\/**游戏区域宽度*\\\/int width;\\\/**游戏区域高度*\\\/int height;\\\/**蛇身单元宽度*\\\/private final byte SNAKEWIDTH = 4;\\\/**是否处于暂停状态,true代表暂停*\\\/boolean isPaused = false;\\\/**是否处于运行状态,true代表运行*\\\/boolean isRun = true;\\\/**时间间隔*\\\/private final int SLEEP_TIME = 300;\\\/**食物的X坐标*\\\/int foodX;\\\/**食物的Y坐标*\\\/int foodY;\\\/**食物的闪烁控制*\\\/boolean b = true;\\\/**Random对象*\\\/Random random = new Random();public SnakeCanvas() {\\\/\\\/初始化init();width = this.getWidth();height = this.getHeight();\\\/\\\/启动线程new Thread(this).start();}\\\/*** 初始化开始数据*\\\/private void init(){\\\/\\\/初始化节点数量snakeNum = 7;\\\/\\\/初始化节点数据for(int i = 0;i < snakeNum;i++){snake[i][0] = 100 - SNAKEWIDTH * i;snake[i][1] = 40;}\\\/\\\/初始化移动方向direction = DIRECTION_RIGHT;\\\/\\\/初始化食物坐标foodX = 100;foodY = 100;}protected void paint(Graphics g) {\\\/\\\/清屏g.setColor(0xffffff);g.fillRect(0,0,width,height);g.setColor(0);\\\/\\\/绘制蛇身for(int i = 0;i < snakeNum;i++){g.fillRect(snake[i][0],snake[i][1],SNAKEWIDTH,SNAKEWIDTH);}\\\/\\\/绘制食物if(b){g.fillRect(foodX,foodY,SNAKEWIDTH,SNAKEWIDTH);}}private void move(int direction){\\\/\\\/蛇身移动for(int i = snakeNum - 1;i > 0;i--){snake[i][0] = snake[i - 1][0];snake[i][1] = snake[i - 1][1];}\\\/\\\/第一个单元格移动switch(direction){case DIRECTION_UP:snake[0][1] = snake[0][1] - SNAKEWIDTH;break;case DIRECTION_DOWN:snake[0][1] = snake[0][1] + SNAKEWIDTH;break;case DIRECTION_LEFT:snake[0][0] = snake[0][0] - SNAKEWIDTH;break;case DIRECTION_RIGHT:snake[0][0] = snake[0][0] + SNAKEWIDTH;break;}}\\\/*** 吃掉食物,自身增长*\\\/private void eatFood(){\\\/\\\/判别蛇头是否和食物重叠if(snake[0][0] == foodX && snake[0][1] == foodY){snakeNum++;generateFood();}}\\\/*** 产生食物* 说明:食物的坐标必须位于屏幕内,且不能和蛇身重合*\\\/private void generateFood(){while(true){foodX = Math.abs(random.nextInt() % (width - SNAKEWIDTH + 1)) \\\/ SNAKEWIDTH * SNAKEWIDTH;foodY = Math.abs(random.nextInt() % (height - SNAKEWIDTH + 1)) \\\/ SNAKEWIDTH * SNAKEWIDTH;boolean b = true;for(int i = 0;i < snakeNum;i++){if(foodX == snake[i][0] && snake[i][1] == foodY){b = false;break;}}if(b){break;}}}\\\/*** 判断游戏是否结束* 结束条件:* 1、蛇头超出边界* 2、蛇头碰到自身*\\\/private boolean isGameOver(){\\\/\\\/边界判别if(snake[0][0] < 0 || snake[0][0] > (width - SNAKEWIDTH) ||snake[0][1] < 0 || snake[0][1] > (height - SNAKEWIDTH)){return true;}\\\/\\\/碰到自身for(int i = 4;i < snakeNum;i++){if(snake[0][0] == snake[i][0] && snake[0][1] == snake[i][1]){return true;} }return false;}\\\/*** 事件处理*\\\/public void keyPressed(int keyCode){int action = this.getGameAction(keyCode);\\\/\\\/改变方向switch(action){case UP:if(direction != DIRECTION_DOWN){direction = DIRECTION_UP;}break;case DOWN:if(direction != DIRECTION_UP){direction = DIRECTION_DOWN;}break;case LEFT:if(direction != DIRECTION_RIGHT){direction = DIRECTION_LEFT;}break;case RIGHT:if(direction != DIRECTION_LEFT){direction = DIRECTION_RIGHT;}break;case FIRE:\\\/\\\/暂停和继续isPaused = !isPaused;break;}}\\\/*** 线程方法* 使用精确延时*\\\/public void run(){try{while (isRun) {\\\/\\\/开始时间long start = System.currentTimeMillis();if(!isPaused){\\\/\\\/吃食物eatFood();\\\/\\\/移动move(direction);\\\/\\\/结束游戏if(isGameOver()){break;}\\\/\\\/控制闪烁b = !b;}\\\/\\\/重新绘制repaint();long end = System.currentTimeMillis();\\\/\\\/延时if(end - start < SLEEP_TIME){Thread.sleep(SLEEP_TIME - (end - start));}}}catch(Exception e){}}} super.paint你点进去看看应该是先清空工作区域,然后下面的代码是绘制贪吃蛇和糖果去掉的话之前的蛇不会被擦掉java 贪吃蛇 给我详细注解 高分
我想求一个Java编写的贪吃蛇游戏,要有注释和流程图最好
我想写一个java写的贪吃蛇。
如何用Java写一个贪吃蛇游戏
求java贪吃蛇的编程,并有注释
java贪吃蛇的一个小问题,关于paint(Graphics g)



