贪吃蛇

无聊写了个贪吃蛇的游戏,炼炼手,



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);
    }

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值