java贪吃蛇极速版
程序员文章站
2024-03-07 20:10:09
本文为大家推荐了一款由java实现经典小游戏:贪吃蛇,相信大家都玩过,如何实现的呐?
效果图:
废话不多说,直接奉上代码:
1、
public cl...
本文为大家推荐了一款由java实现经典小游戏:贪吃蛇,相信大家都玩过,如何实现的呐?
效果图:
废话不多说,直接奉上代码:
1、
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; 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; //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、
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程序设计。
上一篇: Android中图片的三级缓存机制
下一篇: java编写的简单移动方块小游戏代码