Java 蛇身不随头

Java 蛇身不随头,java,Java,我正在用Java开发一款蛇游戏,我遇到的问题是蛇的身体部位没有正确地跟随头部,这与这个问题类似: 这就是一切发生的地方: public class Screen extends JPanel { List<SnakeBody> snakeBody; SnakeBody snake; Thread thread; int x = 10; int y = 10; int dx = 1; int dy = 0; B

我正在用Java开发一款蛇游戏,我遇到的问题是蛇的身体部位没有正确地跟随头部,这与这个问题类似:

这就是一切发生的地方:

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;
        }
    }
}
公共类屏幕扩展了JPanel{
列出蛇体;
蛇体蛇;
螺纹;
int x=10;
int y=10;
int dx=1;
int-dy=0;
布尔向上=假,右=真,向下=假,左=假;
public Screen()抛出InterruptedException{
setPreferredSize(新尺寸(500500));
snakeBody=新的ArrayList();
snake=新蛇身();
蛇。setX(x);
赛蒂(y);
蛇体。添加(蛇);
蛇身ss=新蛇身();
蛇体。添加(ss);
setKeyBindings();
}
公共空间涂料(图g){
超级油漆(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));
}
公开作废动议(){
如果(向上){
蛇体.get(0.setX(x);
蛇体。get(0)。setY(y);
x+=dx;
y+=dy;
蛇体。获取(1)。设置x(x);
蛇体。get(1)。setY(y-10);
}
如果(右){
蛇体.get(0.setX(x);
蛇体。get(0)。setY(y);
x+=dx;
y+=dy;
蛇体。获取(1)。设置x(x+10);
蛇体。get(1)。setY(y);
}
如果(向下){
蛇体.get(0.setX(x);
蛇体。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);
}
如果(左){
蛇体.get(0.setX(x);
蛇体。get(0)。setY(y);
x+=dx;
y+=dy;
蛇体。get(1)。setX(x-10);
蛇体。get(1)。setY(y);
}
}
私有void setKeyBindings(){
ActionMap ActionMap=getActionMap();
int condition=JComponent.WHEN在聚焦窗口中;
InputMap InputMap=getInputMap(条件);
字符串vkLeft=“VK_LEFT”;
字符串vkRight=“VK_RIGHT”;
字符串vkUp=“VK_UP”;
字符串vkDown=“VK_DOWN”;
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_左,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,newkeyaction(vkLeft));
put(vkRight,newkeyaction(vkRight));
put(vkUp,newkeyaction(vkUp));
put(vkDown,newkeyaction(vkDown));
}
私有类KeyAction扩展了AbstractAction{
公钥操作(字符串操作命令){
putValue(操作\命令\键,操作命令);
}
@凌驾
已执行的公共无效操作(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());
向上=真;
右=假;
向下=假;
左=假;
}
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());
向上=错误;
右=真;
向下=假;
左=假;
}
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());
向上=错误;
右=假;
向下=真;
左=假;
}
if(actionEvt.getActionCommand().equals(“VK_左”)){
dx=-1;
dy=0;
snakeBody.get(1.setX)(snakeBody.get(0.getX());
snakeBody.get(1.setY)(snakeBody.get(0.getY());
向上=错误;
右=假;
向下=假;
左=真;
}
}
}

所有的逻辑都应该在你的
蛇身类中(这个类应该从头部到尾部代表整个蛇身)。如果对方法进行了很好的分离,这是非常简单的。为主体的每个元素保留一个位置数组。然后在移动时,使用移动增量的头部偏移位置覆盖最后一个元素的位置。(为此,请保留数组中最后一个主体元素的索引的整数)


我就是这样做的。

所有的逻辑都应该在你的
蛇身
类中(这个类应该代表整个蛇身,从头到尾)。如果对方法进行了很好的分离,这是非常简单的。为主体的每个元素保留一个位置数组。然后在移动时,使用移动增量的头部偏移位置覆盖最后一个元素的位置。(为此,请保留数组中最后一个主体元素的索引的整数)


这就是我要做的。

我认为你玩蛇游戏的方法很奇怪。我能想到的最好的方法是FIFO堆栈。在每一步中,你在前面添加一个部分,即头部,然后从尾部移除一个部分……所有其他部分都保持原样。当蛇咬食物时,你就不会在下一步删除任何部分。

我认为你玩蛇游戏的方法很奇怪。我能想到的最好的方法是FIFO堆栈。在每一步中,你在前面添加一个部分,即头部,然后删除一个