日期:2014-05-20  浏览次数:20741 次

贪吃蛇的小问题
我写了一个贪吃蛇程序,但是在画窗口里显示出来的移动不对(在没有吃到东西是自动增加),下面是我Snake类的代码,里面包含,draw()方法和内部类Node表示蛇的每一节(这样所不是很清楚,我把全部代码都发过来了):
Java code

package snakeGame;

import java.util.Random;

public class AddEggs implements Runnable {
    private Random r = new Random();

    Yard y;

    public AddEggs(Yard y) {
        this.y = y;
    }

    public void run() {
        while (true) {
            int count = r.nextInt(3) + 1;
            if (y.eggs.size() == 0) {
                try {
                    for (int i = 0; i < count; i++) {
                        Egg egg = new Egg(r.nextInt(Yard.COLS), r.nextInt(Yard.ROWS-2)+2);
                        y.eggs.add(egg);                        
                    }
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}



package snakeGame;

public enum Direction {
    U, D, L, R
}



package snakeGame;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

public class Egg {
    private int cols,rows;
    private int w = Yard.BLOCK_SIZE;
    private int h = Yard.BLOCK_SIZE;
    private boolean live = true;
    
    public Egg(int cols,int rows){
        this.cols = cols;
        this.rows = rows;
    }
    
    public void draw(Graphics g) {
        if(!live)return;
        Color c = g.getColor();
        g.setColor(Color.MAGENTA);
        g.fillOval(Yard.BLOCK_SIZE*cols, Yard.BLOCK_SIZE*rows, w, h);
        g.setColor(c);
    }
    
    public Rectangle getRect() {
        return new Rectangle(Yard.BLOCK_SIZE*cols, Yard.BLOCK_SIZE*rows);
    }

    public boolean isLive() {
        return live;
    }

    public void setLive(boolean live) {
        this.live = live;
    }
}




package snakeGame;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.List;

/**
 * 类,蛇
 * 
 * @author hejie
 */
public class Snake {
    // 蛇头节点
    Node head = null;

    // 蛇尾节点
    Node tail = null;

    // 蛇的长度
    private int size;

    private Node node = new Node(15, 20, Direction.R);

    private Yard y;

    public Snake(Yard y) {
        head = node;
        tail = node;
        this.y = y;
        this.size = 1;
    }

    public void draw(Graphics g) {
        if (size == 0)
            return;
        move();

        for (Node n = head; n!= tail; n = n.nextNode) {
            n.draw(g);
        }

    }

    // 把一个节点加到蛇尾
    public void addNodeTail() {
        Node node = null;
        switch (tail.dir) {
        case U:
            node = new Node(tail.cols, tail.rows + 1, tail.dir);
            break;
        case D:
            node = new Node(tail.cols, tail.rows - 1, tail.dir);
            break;
        case L:
            node = new Node(tail.cols + 1, tail.rows, tail.dir);
            break;
        case R:
            node = new Node(tail.cols - 1, tail.rows, tail.dir);
            break;
        }
        
        tail.nextNode = node;
        node.frontNode = tail;
        tail = node;
        size++;
    }

    // 把一个节点加到蛇头
    public void addNodeHead() {
        Node node = null;
        switch (head.dir) {
        case U:
            node = new Node(head.cols, head.rows - 1, head.dir);
            break;
        case D:
            node = new Node(head.cols, head.rows + 1, head.dir);
            break;
        case L:
            node = new Node(head.cols - 1, head.rows, head.dir);
            break;
        case R:
            node = new Node(head.cols + 1, head.rows, head.dir);
            break;
        }
        
        node.nextNode = head;
        head.frontNode = node;
        head = node;
        size++;
    }

    private void deletTail() {
        if (size == 0)
            return;
        tail = tail.frontNode;
        tail.nextNode = null;
        size--;
    }

    public void keyPressed(KeyEvent ke) {
        int keyCode = ke.getKeyCode();
        if (keyCode == ke.VK_UP || keyCode == ke.VK_W) {
            if (head.dir != Direction.D)
                head.dir = Direction.U;
        } else if (keyCode == ke.VK_DOWN || keyCode == ke.VK_S) {
            if (head.dir != Direction.U)
                head.dir = Direction.D;
        } else if (keyCode == ke.VK_LEFT || keyCode == ke.VK_A) {
            if (head.dir != Direction.R)
                head.dir = Direction.L;
        } else if (keyCode == ke.VK_RIGHT || keyCode == ke.VK_D) {
            if (head.dir != Direction.L)
                head.dir = Direction.R;
        }
    }

    private void move() {
        addNodeHead();
        deletTail();
        checkDead();
    }

    public void eatEgg(List<Egg> eggs) {
        Egg egg;
        for (int i = 0; i < eggs.size(); i++) {
            egg = eggs.get(i);
            if (head.getRect().intersects(egg.getRect())) {
                this.addNodeHead();
                egg.setLive(false);
            }
        }
    }
    
    private void checkDead() {
        if(head.rows < 0 || head.cols < 2 || head.rows > Yard.ROWS || head.cols > Yard.COLS)  {
            y.stop();
        }
        
        for(Node n = head.nextNode; n != null; n = n.nextNode) {
            if(head.rows == n.rows && head.cols == n.cols) {
                y.stop();
            }
        }
    }

    /**
     * 构成蛇的节点
     * 
     * @author hejie
     */
    private class Node {
        // 节点的起始位置
        int cols, rows;

        // 节点宽度、高度
        int w = Yard.BLOCK_SIZE, h = Yard.BLOCK_SIZE;

        // 节点方向
        Direction dir = Direction.U;

        // 下一个节点
        private Node nextNode = null;

        private Node frontNode = null;

        Node(int cols, int rows, Direction dir) {
            this.cols = cols;
            this.rows = rows;
            this.dir = dir;
        }

        // 画出本节点
        public void draw(Graphics g) {
            Color c = g.getColor();
            g.setColor(Color.BLACK);
            g.fillRect(Yard.BLOCK_SIZE * cols, Yard.BLOCK_SIZE * rows, w, h);
            g.setColor(c);
        }

        public Rectangle getRect() {
            return new Rectangle(Yard.BLOCK_SIZE * cols, Yard.BLOCK_SIZE * rows);
        }

    }

}



package snakeGame;

import java.awt.Frame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
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;

public class Yard extends Frame{
    
    public static final int ROWS = 40;
    public static final int COLS = 60;
    public static final int BLOCK_SIZE = 10;
    
    private boolean flag = true;
    Snake snake = new Snake(this);
    Image image = null;
    public List<Egg> eggs = new ArrayList<Egg>();
    
    public Yard(){
        super("贪吃蛇");
        this.setBackground(Color.LIGHT_GRAY);
        this.setBounds(200, 100, COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);
        this.addKeyListener(new KeyMonitor());
        this.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }            
        });
            
        this.setVisible(true);
        new Thread(new RepaintSnake()).start();
        new Thread(new AddEggs(this)).start();
        //System.out.println(eggs.size());
    }
    
    public void update(Graphics g) {
        if(image==null){
            image = this.createImage(COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);
        }
        
        Graphics gImage = image.getGraphics();
        Color c = gImage.getColor();
        gImage.setColor(Color.LIGHT_GRAY);
        gImage.fillRect(0, 0, COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);
        gImage.setColor(c);
        paint(gImage);
        g.drawImage(image, 0, 0, null);
        
    }

    public void paint(Graphics g) {
        Color c = g.getColor();
        g.setColor(Color.BLUE);
        /*g.setColor(Color.LIGHT_GRAY);
        g.fillRect(0, 0, ROWS*BLOCK_SIZE, COLS*BLOCK_SIZE);*/
        //竖线
        for(int i=1;i<=COLS;i++){
            g.drawLine(BLOCK_SIZE*i, 0, BLOCK_SIZE*i, BLOCK_SIZE*ROWS);
        }
        //横线
        for(int i=1;i<=ROWS;i++){
            g.drawLine(0, BLOCK_SIZE*i, BLOCK_SIZE*COLS, BLOCK_SIZE*i);
        }
        
        g.setColor(c);

        
        for(int i=0;i<eggs.size();i++){
            eggs.get(i).draw(g);
        }
        snake.draw(g);
        
        snake.eatEgg(eggs);
        
    }



    public static void main(String[] args) {
        new Yard();

    }
    
    private class RepaintSnake implements Runnable{

        public void run() {
            while(flag){
                repaint();
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
        }
        
    }
    
    private class KeyMonitor extends KeyAdapter {
        public void keyPressed(KeyEvent ke){
            snake.keyPressed(ke);
        }
    }

    public void stop() {
        flag = false;
    }
}