楼主没有看到蛇移动的本质,蛇虽然是分成很多块,但他们还是一个整体,每一块的移动都和上一块有关,所以不需要对每一块都进行判断。\x0d\x0a原理:\x0d\x0a把蛇身体的每一块看成一个对象(对象存储该块的坐标和相关信息),作为节点存储在线性链表中,再设置一个变量标志蛇的方向(通过按键可以改变)。一般人都是让每一个节点等于他指向的下一个节点,并让头节点改变位置来实现转弯和移动,这个算法复杂度太高(O(n)),实际上只要做两步操作,插入一个头节点,删除一个尾节点就可以了,新插入的头节点位置根据蛇当前的方向决定用一个数组将蛇头的行径记录下来,然后第二段的下一个方格设置为蛇头走过的方格,这样子蛇走过的路径都是前一段走过的,最后将跟着蛇头走了,比如\x0d\x0a蛇身的路径\x0d\x0a for(int i=snakeLength-1;i>0;i--){\x0d\x0arows[i]=rows[i-1];//依次将蛇前面一段走过行的路段赋值给蛇的下一段\x0d\x0acols[i]=cols[i-1];//依次将蛇前面一段走过列的路段赋值给蛇的下一段\x0d\x0a}\x0d\x0afor(int i=1;i 三个文件,楼主看好: 运行可以,但是并不能鼓吹是一个具有好的风格的代码,。 //文件一 package greedysnake_cx; public class Node{ int x=0; int y=0; int nodewidth; int nodeheight; Node(int x,int y){ this.x=x; this.y=y; } } //文件二 package greedysnake_cx; /** *实现一个greedysnake的模型,具有功能: * 1)移动,moveOn()----从director参数中获取方向信息,如果方向定义的下一个点的逻辑值是true,检查是不是food,是则将food添加到 *列表的头部,snake继续移动,不是则停止移动(撞到蛇尾巴了) * 2)加速,speedUp()----将现成的停滞时间间隔interval按照一定的比率 speedRate进行扩大 * 3)减速,speedDown()----.... * *该类实现Runnable接口, **/ //定义snake的模型 import java.util.*; import javax.swing.*; public class SnakeModel implements Runnable{ private GreedSnake gs; //给每一个矩阵点确立一个boolean值 boolean[][] matrix; private int maxX; private int maxY; //设置一个节点的列表; LinkedList nodeArray= new LinkedList(); Node food=null; int direction=UP; int score=0; //定义方向 public final static int LEFT=1; public final static int UP=2; public final static int RIGHT=3; public final static int DOWN=4; private int interval=200;//停顿时间的间隔 boolean pause=false;//定义暂停 private double speedRate=0.5;//定义速度的变更幅度 //constructor public SnakeModel(GreedSnake gs,int maxx,int maxy){ this.gs=gs; this.maxX=maxx; this.maxY=maxy; //this.matrix=null; //////////////////////////////////////////////////////////////////// //init matrix[][]; matrix=new boolean[maxX][];//***********************不初始化是不行滴 for(int i=0;i matrix[i]=new boolean[maxY];//将矩阵的每一行定义成列的集合 Arrays.fill(matrix[i], false);///使用java.util.Arrays的static方法fill,将matrix[]数组里面的元素全部定义成false //至此,矩阵里面所有的点的boolean值都是flase //for(int j=0;j //matrix[i][j]=false; //} } //////////////////////////////////////////////////////////////////// //init nodeArray int initlength=10; for(int i=0;i //确保snake出现在屏幕的中央 assure that the greedy snake appears in the center of the model //snake的长度由maxX来确定 int x=maxX/2+i; int y=maxY/2; nodeArray.addFirst(new Node(x,y)); matrix[x][y]=true; } ////////////////////////////////////////////////////////////////////// //创建食物 food=createFood(); System.out.println("some test!"); matrix[food.x][food.y]=true; }//end constructor //snake动起 public boolean moveOn(){ Node head=(Node)nodeArray.getFirst(); int x=head.x; int y=head.y; switch(direction){ case LEFT: x--;break; case UP: y--;break; case RIGHT: x++;break; case DOWN: y++;break; default: } if((x>= 0&& x< maxX)&&(y>= 0&& y< maxY)){ if(matrix[x][y]){//当蛇头转至一个bool值为true的点时 if(x==food.x&&y==food.y){//该点是食物 nodeArray.addFirst(food); //吃掉补上 food=createFood(); matrix[food.x][food.y]=true; score+=10; return true; } else//该点不是食物,(蛇尾巴) return false; } else{ nodeArray.addFirst(new Node(x,y)); matrix[x][y]=true; Node nn=(Node)nodeArray.removeLast();//移除并且返回列表中的最后一个元素 matrix[nn.x][nn.y]=false; return true; } } return false; }//end moveOn public void run(){ boolean running=true; while(running){ try{ Thread.sleep(interval); } catch(InterruptedException e){ e.printStackTrace(); } if(!pause){ if(moveOn()){ gs.repaint(); } else{ JOptionPane.showMessageDialog(null,"sorry myboy,GAME OVER!","message", JOptionPane.INFORMATION_MESSAGE); running=false; } } } /*boolean running=true; while(running){ try{ Thread.sleep(interval); } catch(InterruptedException e){ e.printStackTrace(); } if(!pause){ if(moveOn()){ gs.repaint(); } else{ JOptionPane.showMessageDialog(null,"i am sorry,you failed!","message",JOptionPane.INFORMATION_MESSAGE); break; } } }//end while running=false;//当且仅当失败退出的时候; */ } //获取当前游戏得分 public int getScore(){ return this.score; } //加速 public void speedUp(){ interval*=speedRate; } //减速 public void speedDown(){ interval/=speedRate; } //设置暂停 public void chagePause(){ pause=!pause; } //设置方向 public void chageDirection(int newdirection){ if(direction% 2!= newdirection% 2){ direction=newdirection; } } //生成食物 private Node createFood(){ /* *创建一个随机数的生成器,这个是java.util.Random类 *与java.lang.Math类中的random()方法有不一样的地方,彼方法返回一个0-1之间的随机数 **/ Random random=new Random(); int foodx=random.nextInt(maxX); int foody=random.nextInt(maxY); Node food=new Node(foodx,foody); return food; } } //文件三 package greedysnake_cx; /** *在repaint()方法中,绘画上下文对象是从canvas对象使用getContentPane()获取的!! **/ import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*; public class GreedSnake implements KeyListener{ Canvas canvas; private JLabel jlabel; private JPanel jpanel; private JFrame jframe; SnakeModel snakemodel; private final static int canvaswidth=400; private final static int canvasheight=300; private final static int nodewidth=10; private final static int nodeheight=10; //construction GreedSnake(){ jframe=new JFrame("The Greed Sanke!"); jframe.setLayout(new BorderLayout()); Container cp=jframe.getContentPane(); //在jframe面板中添加各种组件 jlabel=new JLabel("welcome"); jlabel.setText("Welcome my friend! Enjoy your self!"); cp.add(jlabel,BorderLayout.NORTH); canvas=new Canvas(); canvas.setSize(canvaswidth,canvasheight); canvas.addKeyListener(this);//给空白面板添加键盘时间监听器! cp.add(canvas,BorderLayout.CENTER); jpanel=new JPanel(); jpanel.setLayout(new BorderLayout()); JLabel label=new JLabel("Pass enter or'r' or's' to start",JLabel.CENTER); jpanel.add(label,BorderLayout.NORTH); JLabel label2=new JLabel("Pass space to pause this game!",JLabel.CENTER); jpanel.add(label2,BorderLayout.CENTER); JLabel label3=new JLabel("Pass pageUp or pageDown to up or down the speed of the snake!",JLabel.CENTER); jpanel.add(label3,BorderLayout.SOUTH); cp.add(jpanel,BorderLayout.SOUTH); //给顶层容器设置时间监听、可视化、关闭按钮的设定 jframe.addKeyListener(this); jframe.pack(); jframe.setVisible(true); jframe.setResizable(false); jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); begin(); }//end construction public void begin(){ //开启一个SnakeModel的进程,并且开始改进程 snakemodel=new SnakeModel(this,canvaswidth/nodewidth,canvasheight/nodeheight); (new Thread(snakemodel)).start(); } void repaint(){ int score=snakemodel.getScore(); jlabel.setText("您的得分是:"+score); Graphics g=canvas.getGraphics();///pay attention! g.setColor(Color.white); g.fillRect(0, 0, canvaswidth, canvasheight); g.setColor(Color.blue); LinkedList list=snakemodel.nodeArray; for(int i=0;i Node nn=(Node)list.get(i); paintingNode(g,nn); } //绘制food g.setColor(Color.green); Node foodnode=new Node(snakemodel.food.x,snakemodel.food.y); paintingNode(g,foodnode); } public void paintingNode(Graphics gg,Node n){ /* *使用Graphics的fillRect方法,填充一个矩形, *矩形的起点需要乘以一个NODE的长宽,以避免重叠 **/ gg.fillRect(n.x*nodewidth, n.y*nodeheight,nodewidth-1,nodeheight-1); } public void keyPressed(KeyEvent e){//按下某一个键时,调用此方法 int keycode=e.getKeyCode(); /* if(keycode==KeyEvent.VK_ENTER||keycode==KeyEvent.VK_R){ begin(); }*/ switch(keycode){ case KeyEvent.VK_LEFT: snakemodel.chageDirection(SnakeModel.LEFT); break; case KeyEvent.VK_UP: snakemodel.chageDirection(SnakeModel.UP); break; case KeyEvent.VK_RIGHT: snakemodel.chageDirection(SnakeModel.RIGHT); break; case KeyEvent.VK_DOWN: snakemodel.chageDirection(SnakeModel.DOWN); break; case KeyEvent.VK_PAGE_DOWN: snakemodel.speedDown(); break; case KeyEvent.VK_PAGE_UP: snakemodel.speedUp(); break; case KeyEvent.VK_ENTER: case KeyEvent.VK_R: begin(); break; case KeyEvent.VK_SPACE: case KeyEvent.VK_P: snakemodel.chagePause(); default: }//end switch }//end keyPressed public void keyReleased(KeyEvent e){//释放某一个键时,调用此方法 } public void keyTyped(KeyEvent e){//键入某一个键时,调用此方法! } //main public static void main(String[] args){ GreedSnake gs=new GreedSnake(); } } 太简单了,我都写在自己手机上了。 都不看书的,全部自己思考。 他这代码也太烂了。 //蛇是用一个二维的int数组表示 //snake[i][0]表示横轴 snake[i][1]表示纵轴 public int[][] snake= new int[91][2]; public int SnakeNum;//蛇长度 public final int SnakeSize;//大概是蛇的最长值 public int foodX;//食物横轴 public int foodY;//食物纵轴 public Random random= new Random();//随机丢食物 private void init() { SnakeNum= 5;//初始蛇长 exp= 0; for(int i= 0; i< SnakeNum; i++) { snake[i][0]= SnakeSize* 3; snake[i][1]= SnakeSize* 3; } DIR= DIR_DOWN; foodX= SnakeSize* 5;初始食物 foodY= SnakeSize* 5; } private void move(int dir) { //把头以外的部分向前一格去掉了尾那一格 for(int i= SnakeNum; i> 0; i--) { snake[i][0]= snake[i- 1][0]; snake[i][1]= snake[i- 1][1]; } //根据 dir方向做蛇头 switch(dir) { case DIR_UP: snake[0][1]= snake[0][1]- SnakeSize; break; case DIR_DOWN: snake[0][1]= snake[0][1]+ SnakeSize; break; case DIR_LEFT: snake[0][0]= snake[0][0]- SnakeSize; break; case DIR_RIGHT: snake[0][0]= snake[0][0]+ SnakeSize; break; } } private void eatFood() { //如果蛇头与食物相等所以吃掉 if(snake[0][0]== foodX&& snake[0][1]== foodY) { SnakeNum++;//蛇长加一格 exp++;//加分还是什么 one++;//加分还是什么 levelup();//加速度吧 filename= 1;//文件名?? isPlaySound= true;//声音吧 PlaySound(filename);//拨声音 makeFood();//抛食物 } } private void makeFood() { while(true) { //食物是随机的。但是不能在蛇身上和屏幕外 //并且坐标要为蛇每一格长度的整数倍 foodX= Math.abs(random.nextInt()%(SCREEN_WIDTH- SnakeSize+ 1))/ SnakeSize* SnakeSize; foodY= Math.abs(random.nextInt()%(SCREEN_HEIGHT- B_BLACK- SnakeSize+ 1))/ SnakeSize* SnakeSize; 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; } } } //判断游戏结束 private boolean isGameOver() { //如果蛇头走出了屏幕结束 if(snake[0][0]< 0|| snake[0][0]>(SCREEN_WIDTH- SnakeSize)|| snake[0][1]< 0|| snake[0][1]>(SCREEN_HEIGHT- B_BLACK- SnakeSize)) { 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; }//后面的写不下了 QQ 312627459二、求贪吃蛇java程序代码(要能运行的,有完整注释的)
三、java贪吃蛇游戏程序 问题 急!!!
上一篇:贪吃蛇小游戏要用到哪些知识
下一篇:贪吃蛇游戏的基础知识