/** *@author:calm_down2010 *1介绍:贪吃蛇是一款经典的游戏,本着游戏的精神,今天无聊蛋疼没事做,就写了这个东东的简单版本当练手用,以备日后复习 *2运行环境(软、硬件环境:装有jre的机器上都可运行) *3算法设计的思想:1窗口用继承自Frame的类来写,用一个内部类(该类是个线程)来实现不断重画屏幕 * 2蛇和食物类用一个list来存储(用一个个小方块来模拟)其中蛇的移动式move(last),add(first)来实现 * 3蛇的生死是通过自身蛇头坐标与边界坐标作比较并且蛇头方块与其余方块作碰撞检测来实现的 *4算法的流程图(忽略) *5算法设计分析(忽略) *6源代码(如下) *7运行结果分析(测试正常) *8收获及体会 (对面向对象思想及对代码调控更深接触,更重要的是培养了程序化思维解决问题,整个思路过程我觉得是最好的经历) */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dialog; import java.awt.Frame; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Image; import java.awt.Label; import java.awt.Panel; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.List; //import javax.swing.JOptionPane; public class TestSnake extends Frame { Snake snake = new Snake(this); Food food = new Food(); List<Food> foods = new ArrayList<Food>(); Image gOffScreen; public int sleepTime = 500; public int score = 0; // public static JOptionPane jop=new JOptionPane(); public void launchFrame() { foods.add(food); setSize(300,400); setVisible(true); setBackground(Color.GREEN); setTitle("Snake"); setResizable(false); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); new Thread(new SnakeMonitor()).start(); this.addKeyListener(new KeyMonitor()); } //当失败的时候弹出对话框提示信息 public void createDialog() { final Dialog dialog = new Dialog(this,"提示信息",true); dialog.setSize(200, 100); dialog.setLayout(new GridLayout(2,1)); dialog.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); //提示信息 Panel topPanel = new Panel(); Label label = new Label("oh yean,你输了,重新再来!"); topPanel.add(label,BorderLayout.CENTER); dialog.add(topPanel); dialog.setVisible(true); } public void paint(Graphics g) { snake.draw(g); for(Food f : foods) { f.draw(g); } g.setColor(Color.ORANGE); g.drawString("您的得分是:" + score, 20, 50); if(snake.isLive == false) // jop.showMessageDialog(this,"you failed,try again!"); createDialog(); } public void update(Graphics g) { if(gOffScreen == null) { gOffScreen = this.createImage(300,400); } Graphics gOff = gOffScreen.getGraphics(); Color c = gOff.getColor(); gOff.setColor(Color.GREEN); gOff.fillRect(0, 0,300,400); paint(gOff); gOff.setColor(c); g.drawImage(gOffScreen, 0, 0, null); } public static void main(String[] args) { new TestSnake().launchFrame(); } private class KeyMonitor extends KeyAdapter { public void keyPressed(KeyEvent e) { snake.keyPressed(e); } } public class SnakeMonitor implements Runnable { public void run() { while(snake.isLive) { repaint(); try { Thread.sleep(sleepTime); } catch (InterruptedException e) { e.printStackTrace(); } } } } } import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; public class Snake { TestSnake ts; private int x = 150;//蛇头横坐标 private int y = 200;//蛇头纵坐标 private int distance = 1; //方块之间间隙 public static final int DIA = 10; //方块边长 private List<Rectangle> rs = new ArrayList<Rectangle>(); public static final int SPEED = 10; //蛇移动速度 public boolean isLive = true; private int round = 0; private Direction snakeDir = Direction.EAST; private enum Direction {EAST,WEST,SOUTH,NORTH} public Snake(TestSnake ts) { this. ts = ts; rs.add(new Rectangle(x,y,DIA,DIA)); rs.add(new Rectangle(x+DIA+distance,y,DIA,DIA)); rs.add(new Rectangle(x+DIA+distance+DIA+distance,y,DIA,DIA)); } public void draw(Graphics g) { Color c = g.getColor(); g.setColor(Color.BLACK); for(Rectangle r : rs) { g.fillRect(r.x,r.y,10,10); } move(); } public void move() { switch (snakeDir) { case WEST: Rectangle rFirst = rs.get(0); rs.add(0, new Rectangle(rFirst.x-SPEED-distance,rFirst.y,DIA,DIA)); rs.remove(rs.size()-1); if(eatFood(ts.foods.get(0))) { ts.foods.add(new Food()); Rectangle rLast = rs.get(rs.size()-1); if(rLast.y == rFirst.y) rs.add(new Rectangle(rLast.x+SPEED+distance,rLast.y,DIA,DIA)); if(rLast.y < rFirst.y) rs.add(new Rectangle(rLast.x,rLast.y-SPEED-distance,DIA,DIA)); if(rLast.y > rFirst.y) rs.add(new Rectangle(rLast.x,rLast.y+SPEED+distance,DIA,DIA)); } //处理边界 if(rs.get(0).x<=-18) isLive = false; for(int i = 1; i<rs.size()-1; i++) { if(rs.get(i).intersects(rs.get(0))) isLive = false; } break; case EAST: Rectangle r2 = rs.get(0); rs.add(0, new Rectangle(r2.x+SPEED+distance,r2.y,DIA,DIA)); rs.remove(rs.size()-1); if(eatFood(ts.foods.get(0))) { ts.foods.add(new Food()); Rectangle rLast = rs.get(rs.size()-1); if(rLast.y == r2.y) rs.add(new Rectangle(rLast.x+SPEED+distance,rLast.y,DIA,DIA)); if(rLast.y < r2.y) rs.add(new Rectangle(rLast.x,rLast.y-SPEED-distance,DIA,DIA)); if(rLast.y > r2.y) rs.add(new Rectangle(rLast.x,rLast.y+SPEED+distance,DIA,DIA)); } //处理边界 if(rs.get(0).x >= 307) isLive = false; for(int i = 1; i<rs.size()-1; i++) { if(rs.get(i).intersects(rs.get(0))) isLive = false; } break; case NORTH: Rectangle r3 = rs.get(0); rs.add(0, new Rectangle(r3.x,r3.y-SPEED-distance,DIA,DIA)); rs.remove(rs.size()-1); if(eatFood(ts.foods.get(0))) { ts.foods.add(new Food()); Rectangle rLast = rs.get(rs.size()-1); if(rLast.y == r3.y) rs.add(new Rectangle(rLast.x+SPEED+distance,rLast.y,DIA,DIA)); if(rLast.y < r3.y) rs.add(new Rectangle(rLast.x,rLast.y-SPEED-distance,DIA,DIA)); if(rLast.y > r3.y) rs.add(new Rectangle(rLast.x,rLast.y+SPEED+distance,DIA,DIA)); } //处理边界 if(rs.get(0).y <= 5) isLive = false; for(int i = 1; i<rs.size()-1; i++) { if(rs.get(i).intersects(rs.get(0))) isLive = false; } break; case SOUTH: Rectangle r4 = rs.get(0); rs.add(0, new Rectangle(r4.x,r4.y+SPEED+distance,DIA,DIA)); rs.remove(rs.size()-1); if(eatFood(ts.foods.get(0))) { ts.foods.add(new Food()); Rectangle rLast = rs.get(rs.size()-1); if(rLast.y == r4.y) rs.add(new Rectangle(rLast.x+SPEED+distance,rLast.y,DIA,DIA)); if(rLast.y < r4.y) rs.add(new Rectangle(rLast.x,rLast.y-SPEED-distance,DIA,DIA)); if(rLast.y > r4.y) rs.add(new Rectangle(rLast.x,rLast.y+SPEED+distance,DIA,DIA)); } //处理边界 if(rs.get(0).y >= 400) isLive = false; for(int i = 1; i<rs.size()-1; i++) { if(rs.get(i).intersects(rs.get(0))) isLive = false; } break; default: break; } } public boolean eatFood(Food f) { if(rs.get(0).intersects(new Rectangle(f.getX(),f.getY(),10,10))) { ts.foods.remove(f); round++; if(round % 3 == 0) ts.sleepTime -=20; ts.score += 10; return true; } else return false; } public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); switch (keyCode) { case KeyEvent.VK_LEFT: if(snakeDir != Direction.EAST) snakeDir = Direction.WEST; break; case KeyEvent.VK_RIGHT: if(snakeDir != Direction.WEST) snakeDir = Direction.EAST; break; case KeyEvent.VK_UP: if(snakeDir != Direction.SOUTH) snakeDir = Direction.NORTH; break; case KeyEvent.VK_DOWN: if(snakeDir != Direction.NORTH) snakeDir = Direction.SOUTH; break; default: break; } } } import java.awt.Color; import java.awt.Graphics; import java.util.Random; public class Food { private int x; private int y; public static Random r = new Random(); public Food() { init(); } public void init() { x = r.nextInt(230); y = r.nextInt(350); } public void draw(Graphics g) { Color c = g.getColor(); g.setColor(Color.MAGENTA); g.fillRect(x, y, 10, 10); } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } } 这个版本写的朴素了一些,自己需要界面和功能完善的话有时间自己加