贪吃蛇
来源:互联网 发布:js验证表单 编辑:程序博客网 时间:2024/03/29 06:50
无聊写了个贪吃蛇的游戏,炼炼手,
SnakeFrame.JAVA
package feifei;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;public class SnakeFrame extends Frame { private static final int WIDTH = 800; private static final int HEIGHT = 600; private static SnakeFrame snakeFrame; private void init() { this.setSize(SnakeFrame.WIDTH, SnakeFrame.HEIGHT); this.setLocation(100, 100); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); } private SnakeFrame() { init(); } public static SnakeFrame getMe() { if (snakeFrame == null) { snakeFrame = new SnakeFrame(); } return snakeFrame; } public static void main(String[] args) { SnakeFrame snakeFrame = SnakeFrame.getMe(); final SnakeCanvas canvas = new SnakeCanvas(); snakeFrame.setLayout(new FlowLayout(FlowLayout.LEADING)); snakeFrame.add(canvas); snakeFrame.setVisible(true); Button startBtn = new Button("start"); startBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { canvas.start(); } }); snakeFrame.add(startBtn); }}
SnakeCanvas.java
package feifei;import java.awt.*;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.image.BufferStrategy;import java.util.Observable;import java.util.Observer;public class SnakeCanvas extends Canvas implements Observer, KeyListener { private static final int UP = 38; private static final int DOWN = 40; private static final int LEFT = 37; private static final int RIGHT = 39; public static int WIDTH = 500; public static int HEIGHT = 500; public static Color BG_COLOR = Color.BLACK; private Stone stone; private Snake snake; private Food food; public SnakeCanvas() { setSize(WIDTH, HEIGHT); setVisible(true); addKeyListener(this); init(); } public void start() { requestFocus(); init(); if (getBufferStrategy() == null) { createBufferStrategy(2); //只有canvas创建显示里,才能调用该方法,创建缓冲,不然会报错 } snake.start(); } public void init() { snake = new Snake(); stone = new Stone(snake); food = new Food(snake, stone); snake.addObserver(this); snake.addObserver(food); snake.addObserver(stone); } @Override public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.setColor(BG_COLOR); g2d.fillRect(0, 0, WIDTH, HEIGHT); stone.drawMe(g2d); snake.drawMe(g2d); food.drawMe(g2d); } public void update() { BufferStrategy strategy = getBufferStrategy(); Graphics2D g2d = (Graphics2D) strategy.getDrawGraphics(); g2d.setColor(BG_COLOR); g2d.fillRect(0, 0, WIDTH, HEIGHT); stone.drawMe(g2d); snake.drawMe(g2d); food.drawMe(g2d); if (!strategy.contentsLost()) { strategy.show(); } g2d.dispose(); } @Override public void update(Observable o, Object arg) { update(); } @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case SnakeCanvas.UP: if (snake.getCurDirection() == Snake.Direction.DOWN) return; snake.setCurDirection(Snake.Direction.UP); snake.move(0, -Point.HEIGHT); break; case SnakeCanvas.DOWN: if (snake.getCurDirection() == Snake.Direction.UP) return; snake.setCurDirection(Snake.Direction.DOWN); snake.move(0, Point.HEIGHT); break; case SnakeCanvas.LEFT: if (snake.getCurDirection() == Snake.Direction.RIGHT) return; snake.setCurDirection(Snake.Direction.LEFT); snake.move(-Point.WIDTH, 0); break; case SnakeCanvas.RIGHT: if (snake.getCurDirection() == Snake.Direction.LEFT) return; snake.setCurDirection(Snake.Direction.RIGHT); snake.move(Point.WIDTH, 0); break; default: return; } update(); } @Override public void keyTyped(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { }}
Snake.java
package feifei;import java.awt.*;import java.util.LinkedList;import java.util.Observable;public class Snake extends Observable implements Runnable { public static Color SNAKE_HEAD_COLOR = Color.RED; public static Color SNAKE_BODY_COLOR = Color.WHITE; public enum Direction {UP, DOWN, LEFT, RIGHT}; private Direction curDirection; private LinkedList<Point> snakeList; private Point head; private boolean autoMove; private int delay; private boolean hitStone; private boolean hasEated; private int foodCount; public Snake() { init(); } public void init() { curDirection = Direction.RIGHT; snakeList = new LinkedList<Point>(); head = new Point(); int lX = SnakeCanvas.WIDTH / Point.WIDTH / 2; int lY = SnakeCanvas.HEIGHT / Point.HEIGHT / 2; head.setLocation(lX * Point.WIDTH, lY * Point.HEIGHT); snakeList.add(head); delay = 100; autoMove = true; hitStone = false; hasEated = false; foodCount = 0; } public void start() { init(); Thread thread = new Thread(this); thread.start(); } public void over() { autoMove = false; } public synchronized void drawMe(Graphics2D g2d) { /* synchronized (snakeList) {*/ for (Point node : snakeList) { if (node.equals(head)) { g2d.setColor(SNAKE_HEAD_COLOR); } else { g2d.setColor(SNAKE_BODY_COLOR); } node.drawMe(g2d); } /* }*/ } public synchronized void move(int x, int y) { /* synchronized (snakeList) {*/ if (snakeList == null || snakeList.size() == 0) { return; } int _x = head.getX() + x; int _y = head.getY() + y; head = new Point(); head.setLocation(_x, _y); snakeList.addFirst(head); if (!hasEated) { snakeList.removeLast(); } else { eatFood(); } /* }*/ setChanged(); notifyObservers(); if (hitStone || eatSelf()) over(); } private void eatFood() { hasEated = false; foodCount++; if(foodCount > 2){ foodCount=0; if(delay > 50){ delay-=20; } } } private boolean eatSelf() { synchronized (snakeList) { int eqHeadCount = eqHeadCount(); if(eqHeadCount > 1) return true; } return false; } private int eqHeadCount() { int headCount = 0; for (Point node : snakeList) { if (node.equals(head)) { headCount++; if (headCount > 1) break; } } return headCount; } private void autoMove() { int x = 0; int y = 0; switch (curDirection) { case UP: y = -Point.HEIGHT; break; case DOWN: y = Point.HEIGHT; break; case LEFT: x = -Point.WIDTH; break; case RIGHT: x = Point.WIDTH; break; } move(x, y); } @Override public void run() { while (autoMove) { autoMove(); try { Thread.sleep(delay); } catch (Exception e) { e.printStackTrace(); } } } public Direction getCurDirection() { return curDirection; } public void setCurDirection(Direction curDirection) { this.curDirection = curDirection; } public LinkedList<Point> getSnakeList() { return snakeList; } public void setHitStone(boolean hitStone) { this.hitStone = hitStone; } public Point getHead() { return head; } public void setHasEated(boolean hasEated) { this.hasEated = hasEated; }}
Food.java
package feifei;import java.awt.*;import java.util.Observable;import java.util.Observer;import java.util.Random;/** * Created with IntelliJ IDEA. * User: pc * Date: 13-4-12 * Time: 下午3:57 * To change this template use File | Settings | File Templates. */public class Food implements Observer { private Point foodNode; private Snake snake; private Stone stone; private Random random; public Food(Snake snake, Stone stone) { this.snake = snake; this.stone = stone; init(); } public Food() { init(); } private void init() { random = new Random(); foodNode = new Point(); newFood(); } private void newFood() { int x = SnakeCanvas.WIDTH / Point.WIDTH; int y = SnakeCanvas.HEIGHT / Point.HEIGHT; foodNode.setLocation(random.nextInt(x) * Point.WIDTH, random.nextInt(y) * Point.HEIGHT); for (Point node : snake.getSnakeList()) { if (node.equals(foodNode)) { newFood(); break; } } for (Point node : stone.getStoneList()) { if (node.equals(foodNode)) { newFood(); break; } } } public void drawMe(Graphics2D g2d) { g2d.setColor(Color.GREEN); foodNode.drawMe(g2d); } @Override public void update(Observable observable, Object arg) { Snake snake = (Snake) observable; if (foodNode.equals(snake.getHead())) { snake.setHasEated(true); newFood(); } }}
Stone.java
package feifei;import java.awt.*;import java.util.*;import java.util.List;public class Stone implements Observer { public static Color STONE_COLOR = Color.LIGHT_GRAY; private List<Point> stoneList; private Random random; Snake snake; public Stone(Snake snake) { random = new Random(); this.snake = snake; init(); } public void init() { stoneList = new LinkedList<Point>(); /*墙*/ buildWall(); // fillStones(); } private void fillStones() { for(int i = 0; i < 20; i++){ Point stone = newStone(); if (stone == null) continue; stoneList.add(stone); } } private Point newStone() { int x = SnakeCanvas.WIDTH / Point.WIDTH; int y = SnakeCanvas.HEIGHT / Point.HEIGHT; Point stone = new Point(); stone.setLocation(random.nextInt(x) * Point.WIDTH, random.nextInt(y) * Point.HEIGHT); for (Point node : snake.getSnakeList()) { if (node.equals(stone)) { return newStone(); } } for (Point node : getStoneList()) { if (node.equals(stone)) { return newStone(); } } return stone; } private void buildWall() { int wallWCount = SnakeCanvas.WIDTH / Point.WIDTH; int wallHCount = SnakeCanvas.HEIGHT / Point.HEIGHT; for (int i = 0; i < wallHCount; i++) { for (int j = 0; j < wallWCount; j++) { boolean validRow = (i != 0 && i != wallHCount - 1); boolean validCell = (j > 0 && j < wallWCount - 1); if (validRow && validCell) { continue; } Point node = new Point(); node.setLocation(j * Point.WIDTH, i * Point.HEIGHT); stoneList.add(node); } } } public void drawMe(Graphics2D g2d) { g2d.setColor(STONE_COLOR); for (Point node : stoneList) { node.drawMe(g2d); } } public List<Point> getStoneList() { return stoneList; } @Override public void update(Observable observable, Object o) { Snake snake = (Snake) observable; for (Point node : stoneList) { if (node.equals(snake.getHead())) { snake.setHitStone(true); break; } } }}
Point.java
package feifei;import java.awt.*;public class Point { public static int WIDTH = 10; public static int HEIGHT = 10; private int x; private int y; public Point() { } public Point(Point point) { this.setLocation(point.getX(), point.getY()); } public int getX() { return x; } public int getY() { return y; } public void setLocation(int x, int y) { this.x = x; this.y = y; } public void move(int x, int y) { this.x = x; this.y = y; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Point point = (Point) o; if (x != point.x) return false; if (y != point.y) return false; return true; } @Override public int hashCode() { int result = x; result = 31 * result + y; return result; } public void drawMe(Graphics2D g2d) { g2d.fill3DRect(getX(), getY(), Point.WIDTH, Point.HEIGHT, true); }}