无聊写了个贪吃蛇的游戏,炼炼手,
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);
}
}