蛇体不跟随头部

时间:2014-12-21 23:23:13

标签: java

我正在使用Java进行蛇形游戏,我遇到的问题是蛇的身体部位不能正确地跟随头部,它与此问题相似:

Example illustration of the problem

以下是这一切发生的地方:

public class Screen extends JPanel {

    List<SnakeBody> snakeBody;

    SnakeBody snake;

    Thread thread;

    int x = 10;
    int y = 10;
    int dx = 1;
    int dy = 0;

    Boolean up = false, right = true, down = false, left = false;

    public Screen() throws InterruptedException {

        setPreferredSize(new Dimension(500, 500));
        snakeBody = new  ArrayList<SnakeBody>();
        snake = new SnakeBody();
        snake.setX(x);
        snake.setY(y);
        snakeBody.add(snake);

        SnakeBody ss = new SnakeBody();
        snakeBody.add(ss);

        setKeyBindings();
    }

    public void paint(Graphics g) {
        super.paint(g);

        g.drawRect(snakeBody.get(0).getX(), snakeBody.get(0).getY(), 10, 10);
        g.drawRect(snakeBody.get(1).getX(), snakeBody.get(1).getY(), 10, 10);
    }

    public void move() {

        if(up) {
            snakeBody.get(0).setX(x);
            snakeBody.get(0).setY(y);

            x += dx;
            y += dy;

            snakeBody.get(1).setX(x);
            snakeBody.get(1).setY(y-10);
        }

        if(right) {
            snakeBody.get(0).setX(x);
            snakeBody.get(0).setY(y);

            x += dx;
            y += dy;

            snakeBody.get(1).setX(x+10);
            snakeBody.get(1).setY(y);
        }

        if(down) {
            snakeBody.get(0).setX(x);
            snakeBody.get(0).setY(y);

            x += dx;
            y += dy;

            snakeBody.get(1).setX(snakeBody.get(0).getX());
            snakeBody.get(1).setY(snakeBody.get(0).getY()-10);
        }

        if(left) {
            snakeBody.get(0).setX(x);
            snakeBody.get(0).setY(y);

            x += dx;
            y += dy;

            snakeBody.get(1).setX(x-10);
            snakeBody.get(1).setY(y);
        }
    }

    private void setKeyBindings() {
        ActionMap actionMap = getActionMap();
        int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
        InputMap inputMap = getInputMap(condition );

        String vkLeft = "VK_LEFT";
        String vkRight = "VK_RIGHT";
        String vkUp = "VK_UP";
        String vkDown = "VK_DOWN";

        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), vkLeft);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), vkRight);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), vkUp);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), vkDown);

        actionMap.put(vkLeft, new KeyAction(vkLeft));
        actionMap.put(vkRight, new KeyAction(vkRight));
        actionMap.put(vkUp, new KeyAction(vkUp));
        actionMap.put(vkDown, new KeyAction(vkDown));
    }

    private class KeyAction extends AbstractAction {
        public KeyAction(String actionCommand) {
            putValue(ACTION_COMMAND_KEY, actionCommand);
        }

        @Override
        public void actionPerformed(ActionEvent actionEvt) {
        if(actionEvt.getActionCommand().equals("VK_UP")) {
            dx = 0;
            dy = -1;

            snakeBody.get(1).setX(snakeBody.get(0).getX());
            snakeBody.get(1).setY(snakeBody.get(0).getY());

            up = true;
            right = false;
            down = false;
            left = false;

        }

        if(actionEvt.getActionCommand().equals("VK_RIGHT")) {
            dx = 1;
            dy = 0;

            snakeBody.get(1).setX(snakeBody.get(0).getX());
            snakeBody.get(1).setY(snakeBody.get(0).getY());
            up = false;
            right = true;
            down = false;
            left = false;
        }

        if(actionEvt.getActionCommand().equals("VK_DOWN")) {
            dx = 0;
            dy = 1;

            snakeBody.get(1).setX(snakeBody.get(0).getX());
            snakeBody.get(1).setY(snakeBody.get(0).getY());

            up = false;
            right = false;
            down = true;
            left = false;
        }

        if(actionEvt.getActionCommand().equals("VK_LEFT")) {
            dx = -1;
            dy = 0;

            snakeBody.get(1).setX(snakeBody.get(0).getX());
            snakeBody.get(1).setY(snakeBody.get(0).getY());

            up = false;
            right = false;
            down = false;
            left = true;
        }
    }
}

2 个答案:

答案 0 :(得分:3)

我认为你对蛇游戏的方法很奇怪。我能想到的最好的方法是FIFO堆栈。每一步你都要在前面添加一个部分作为头部,并从尾部移除一部分......所有其他部分保持原样。当蛇咬食物时,你不会在下一步移动时删除部分。

答案 1 :(得分:2)

所有逻辑应该在你的SnakeBody课程中(这个课程应该代表整个蛇体,从头到尾)。如果你很好地分离方法,这很简单。为身体的每个元素保持一系列位置。然后在移动时,用头部偏移的位置覆盖最后一个元素的位置。 (为此,请保存一个包含数组中最后一个body元素索引的整数。)

我将如何做到这一点。