读书人

贪吃蛇的小有关问题

发布时间: 2011-12-07 22:35:48 作者: rapoo

贪吃蛇的小问题
我写了一个贪吃蛇程序,但是在画窗口里显示出来的移动不对(在没有吃到东西是自动增加),下面是我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;    }} 



[解决办法]
我没调试哇 但是我感觉如果是一直加Node的话就应该是这个东西的判断有问题

Java code
if (head.getRect().intersects(egg.getRect()){}
[解决办法]
再提一句哇

我个人觉得这种格子游戏用碰撞检测不好哇 格子游戏不是每个格子都有坐标嘛

用坐标检测岂不是更好哇 而且逻辑也清楚 而且一般来说 游戏的碰撞检测都是有自己公司开发的API的

[解决办法]
高手,下班学习看看
[解决办法]
不知道问题出在哪,不过有两个地方不妥:

Java code
for (Node n = head; n!= tail; n = n.nextNode) { //这里的循环条件应该是n!=null吧,尾节点也应该画出来的            n.draw(g);}
[解决办法]
学习一下
[解决办法]
贪食蛇可以看一下传智播客的视频教程 自己研究下该注意的问题和算法 好过让别人看那么复杂的代码

读书人网 >J2SE开发

热点推荐