贪吃蛇java代码

时间:2024.3.31

往链点点通共享资源,了解更多请登录www.WL566.com

 


用mvc方式实现的贪吃蛇游戏,共有4个类。运行greedsnake运行即可。主要是观察者模式的使用, 已经添加了很多注释了。
1、
/*
* 程序名称:贪食蛇
* 原作者:bigf
* 修改者:algo
* 说明: 以前也用c写过这个程序,现在看到bigf用java写的这个,发现虽然作者自称是java的初学者,
*      但是明显编写程序的素养不错,程序结构写得很清晰,有些细微得地方也写得很简洁,一时兴起之
*      下, 认真解读了这个程序,发现数据和表现分开得很好,而 近日正在学习mvc设计模式,
*      因此尝试把程序得结构改了一下,用mvc模式来实现,对源程序得改动不多。
*       同时也为程序增加了一些自己理解得注释,希望对大家阅读有帮助。
*/

package mvctest;

/**
* @author wangyu
* @version 1.0
* description:
* </pre>
* create on :date :20##-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.java
import 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 :20##-6-13  time:15:58:33
* lastmodified:
* history:
*/
//snakemodel.java
import 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.java
import 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程序设计课程设计报告题目姓名学号专业班级指导教师日期贪吃蛇游戏赵鹏飞陈瑞李烨20xx9606407320xx9606407720xx9606407220xx96064016软...

贪吃蛇---java课程设计

武汉理工大学课程设计课程名称JAVA课程设计题目贪吃蛇程序设计专业电子商务班级学号姓名成绩指导教师月课程设计任务书设计题目设计目的1巩固和加深课堂所学知识2学习掌握一般的软件的设计方法和查阅运用资料的能力3掌握...

Java程序设计报告《贪吃蛇》

Java程序设计课程设计报告题目贪吃蛇游戏的设计与实现指导老师沈泽刚专业计算机科学与技术班级103姓名梁潇一课程设计目的贪吃蛇游戏一款非常经典的手机游戏因为它比较简单有趣无论老少都比较适合目的是更好地了解和掌握...

java课程设计贪吃蛇游戏设计

前言Java最初被命名为Oak目标设定在家用电器等小型系统的编程语言来解决诸如电视机电话闹钟烤面包机等家用电器的控制和通讯问题由于这些智能化家电的市场需求没有预期的高Sun放弃了该项计划就在Oak几近失败之时随...

java贪吃蛇游戏的设计论文

大连交通大学计算机工程实践摘要近年来Java作为一种新的编程语言以其简单性可移植性和平台无关性等优点得到了广泛地应用特别是Java与万维网的完美结合使其成为网络编程和嵌入式编程领域的首选编程语言JBuilder...

面向对象课程设计--基于java的贪吃蛇游戏的设计与开发

面向对象课程设计1需求分析11游戏开发的可行性游戏开发至今已经有30多年在这个短暂的时期里随着硬件水平的提高游戏开发新技术层出不穷经典游戏比比皆是游戏这个名称一直就存在于每个人的日常生活中如猜拳游戏猜谜游戏大地...

贪吃蛇java课程设计

课程设计说明书NO1沈阳大学课程设计说明书NO2沈阳大学课程设计说明书NO3沈阳大学课程设计说明书NO4沈阳大学课程设计说明书NO5沈阳大学课程设计说明书NO6沈阳大学课程设计说明书NO7沈阳大学课程设计说明书...

贪吃蛇Java课程设计

目录1设计任务与要求111设计任务112具体要求12软件主要模块流程图23总体方案与说明331总体方案332系统模块3321游戏界面设计3322贪吃蛇蛇身及运动设置5323游戏控制设置34程序设计441Game...

Java贪吃蛇游戏设计课程设计

华东交通大学理工学院课程设计报告书所属课程名称JAVA课程设计题目贪吃蛇游戏设计分院专业班级学号指导教师华东交通大学理工学院课程设计论文任务书专业班级姓名一课程设计论文题目贪吃蛇游戏设计二课程设计论文工作自20...

java课程设计贪吃蛇

枣庄学院信息科学与工程学院课程设计任务书题目java设计贪吃蛇游戏学号20xx12310141姓名张丛磊年级20xx级32专业计算机科学技术课程java指导教师刘梦林职称完成时间20xx1225课程设计任务书及...

java贪吃蛇报告

1设计要求与任务11设计要求1学习android基础理论熟悉Java和Android开发包学习xml文件编写熟悉Android手机系统设计中的有关资料熟悉使用eclipse软件工具和ADT插件了解MVC模式和设...

java课程设计贪吃蛇

华北科技学院课程设计说明书面向对象程序设计Java班级B09114姓名成晓晓设计题目贪吃蛇设计时间至指导教师评语评阅成绩评阅教师课程设计说明书1课程设计的目的首先Java是一种易学易懂的通用程序设计语言由于它具...

java贪吃蛇设计报告(13篇)