在简单的Java.swing游戏中无法处理运动错误

时间:2017-06-04 13:31:11

标签: java swing actionlistener game-physics

移动我正在创建的游戏时出现问题,除了一件事情之外,一切都正常工作,根据计时器延迟重新绘制电路板,当我在电路板重绘之前进行多次移动时,那里是一个机会,我的蛇会相互堕落。我无法处理这个,我不知道如何避免它,我正在考虑在按钮之间设置延迟,但这是不可能的,因为游戏适用于两个玩家。我正试图解决这个问题,因为蛇回溯到自己的位置,但尚未找到解决方案。任何帮助将不胜感激。

几张代表问题的照片:

正常游戏玩法:
enter image description here

当我垃圾按钮时:
enter image description here

移动方法:

    private void move()
{

    for (int z = dots; z > 0; z--)
    {
        p1x[z] = p1x[(z - 1)];
        p1y[z] = p1y[(z - 1)];
        p2x[z] = p2x[(z - 1)];
        p2y[z] = p2y[(z - 1)];
    }

    if (p1LeftDirection)
    {
        p1x[0] -= DOT_SIZE;
    }

    if (p1RightDirection)
    {
        p1x[0] += DOT_SIZE;
    }

    if (p1UpDirection)
    {
        p1y[0] -= DOT_SIZE;
    }

    if (p1DownDirection)
    {
        p1y[0] += DOT_SIZE;
    }

    if (p2LeftDirection)
    {
        p2x[0] -= DOT_SIZE;
    }

    if (p2RightDirection)
    {
        p2x[0] += DOT_SIZE;
    }

    if (p2UpDirection)
    {
        p2y[0] -= DOT_SIZE;
    }

    if (p2DownDirection)
    {
        p2y[0] += DOT_SIZE;
    }
    dots++;
}

绘图方法:

private void doDrawing(Graphics g)
{
    if (inGame)
    {
        for (int z = 0; z < dots; z++)
        {
            if (z == 0)
            {
                g.drawImage(p1Head, p1x[z], p1y[z], this);
                g.drawImage(p2Head, p2x[z], p2y[z], this);
            }
            else
            {
                g.drawImage(p1Body, p1x[z], p1y[z], this);
                g.drawImage(p2Body, p2x[z], p2y[z], this);
            }
        }

        for (int i = 0; i < B_WIDTH; i += 25)
        {
            g.drawImage(brick, 0, i, this);
            g.drawImage(brick, i, 0, this);
        }
        for (int i = 0; i < B_WIDTH; i += 25)
        {
            g.drawImage(brick, B_WIDTH - DOT_SIZE, i, this);
            g.drawImage(brick, i, B_HEIGHT - DOT_SIZE, this);
        }

        Toolkit.getDefaultToolkit().sync();
    }
    else
    {
        gameOver(g);
    }
}

我的KeyAdapter:

public class KeyboardSettings extends KeyAdapter
{

    @Override
    public void keyPressed(KeyEvent e)
    {
        int key = e.getKeyCode();

        if ((key == KeyEvent.VK_LEFT) && (!p1RightDirection))
        {
            ImageIcon p1HeadLoader = new ImageIcon("src/main/resources/images/p1leftmouth.png");
            p1Head = p1HeadLoader.getImage();
            p1LeftDirection = true;
            p1UpDirection = false;
            p1DownDirection = false;
        }

        if ((key == KeyEvent.VK_RIGHT) && (!p1LeftDirection))
        {
            ImageIcon p1HeadLoader = new ImageIcon("src/main/resources/images/p1rightmouth.png");
            p1Head = p1HeadLoader.getImage();
            p1RightDirection = true;
            p1UpDirection = false;
            p1DownDirection = false;
        }

        if ((key == KeyEvent.VK_UP) && (!p1DownDirection))
        {
            ImageIcon p1HeadLoader = new ImageIcon("src/main/resources/images/p1upmouth.png");
            p1Head = p1HeadLoader.getImage();
            p1UpDirection = true;
            p1RightDirection = false;
            p1LeftDirection = false;
        }

        if ((key == KeyEvent.VK_DOWN) && (!p1UpDirection))
        {
            ImageIcon p1HeadLoader = new ImageIcon("src/main/resources/images/p1downmouth.png");
            p1Head = p1HeadLoader.getImage();
            p1DownDirection = true;
            p1RightDirection = false;
            p1LeftDirection = false;
        }

        if ((key == KeyEvent.VK_A) && (!p2RightDirection))
        {
            ImageIcon p2HeadLoader = new ImageIcon("src/main/resources/images/p2leftmouth.png");
            p2Head = p2HeadLoader.getImage();
            p2LeftDirection = true;
            p2UpDirection = false;
            p2DownDirection = false;
        }

        if ((key == KeyEvent.VK_D) && (!p2LeftDirection))
        {
            ImageIcon p2HeadLoader = new ImageIcon("src/main/resources/images/p2rightmouth.png");
            p2Head = p2HeadLoader.getImage();
            p2RightDirection = true;
            p2UpDirection = false;
            p2DownDirection = false;
        }

        if ((key == KeyEvent.VK_W) && (!p2DownDirection))
        {
            ImageIcon p2HeadLoader = new ImageIcon("src/main/resources/images/p2upmouth.png");
            p2Head = p2HeadLoader.getImage();
            p2UpDirection = true;
            p2RightDirection = false;
            p2LeftDirection = false;
        }

        if ((key == KeyEvent.VK_S) && (!p2UpDirection))
        {
            ImageIcon p2HeadLoader = new ImageIcon("src/main/resources/images/p2downmouth.png");
            p2Head = p2HeadLoader.getImage();
            p2DownDirection = true;
            p2RightDirection = false;
            p2LeftDirection = false;
        }
    }
}

1 个答案:

答案 0 :(得分:2)

我遇到了完全相同的问题。我尝试了不同的内置方法,但它们对我不起作用。但这就是我用我的方法绕过问题的方法:

private void move()
{

for (int z = dots; z > 0; z--)
{
    p1x[z] = p1x[(z - 1)];
    p1y[z] = p1y[(z - 1)];
    p2x[z] = p2x[(z - 1)];
    p2y[z] = p2y[(z - 1)];
}

if (p1LeftDirection)
{
    p1x[0] -= DOT_SIZE;
    if(p1x[0] == p1x[2])
    {
        p1x[0] += 2*DOT_SIZE;
        rotateCorr();
    }
    else if(p1x[0] == p1x[1])
    {
        p1x[0] += DOT_SIZE;
        rotateCorr();
    }
}

if (p1RightDirection)
{
    p1x[0] += DOT_SIZE;
    if(p1x[0] == p1x[2])
    {
        p1x[0] -= 2*DOT_SIZE;
        rotateCorr();
    }
    else if(p1x[0] == p1x[1])
    {
        p1x[0] -= DOT_SIZE;
        rotateCorr();
    }
}

if (p1UpDirection)
{
    p1y[0] -= DOT_SIZE;
    if(p1y[0] == p1y[2])
    {
        p1y[0] += 2*DOT_SIZE;
        rotateCorr();
    }
    else if(p1y[0] == p1y[1])
    {
        p1y[0] += DOT_SIZE;
        rotateCorr();

    }
}

if (p1DownDirection)
{
    p1y[0] += DOT_SIZE;
    if(p1y[0] == p1y[2])
    {
        p1y[0] -= 2*DOT_SIZE;
        rotateCorr();
    }
    else if(p1y[0] == p1y[1])
    {
        p1y[0] -= DOT_SIZE;
        rotateCorr();
    }
}

if (p2LeftDirection)
{
    p2x[0] -= DOT_SIZE;
    if(p2x[0] == p2x[2])
    {
        p2x[0] += 2*DOT_SIZE;
        rotateCorr();
    }
    else if(p2x[0] == p2x[1])
    {
        p2x[0] += DOT_SIZE;
        rotateCorr();
    }
}

if (p2RightDirection)
{
    p2x[0] += DOT_SIZE;
    if(p2x[0] == p2x[2])
    {
        p2x[0] -= 2*DOT_SIZE;
        rotateCorr();
    }
    else if(p2x[0] == p2x[1])
    {
        p2x[0] -= DOT_SIZE;
        rotateCorr();
    }
}

if (p2UpDirection)
{
    p2y[0] -= DOT_SIZE;
    if(p2y[0] == p2y[2])
    {
        p2y[0] += 2*DOT_SIZE;
        rotateCorr();
    }
    else if(p2y[0] == p2y[1])
    {
        p2y[0] += DOT_SIZE;
        rotateCorr();
    }
}

if (p2DownDirection)
{
    p2y[0] += DOT_SIZE;
    if(p2y[0] == p2y[2])
    {
        p2y[0] -= 2*DOT_SIZE;
        rotateCorr();
    }
    else if(p2y[0] == p2y[1])
    {
        p2y[0] -= DOT_SIZE;
        rotateCorr();
    }
}
dots++;
}

我确切地知道你遇到的故障,所以这对你有用。

基本上,如果按下多个按钮,蛇会自行回溯,因为首先它会注册该键有效,但随后会移动以执行无效键。因此,即使逻辑上它使没有FRIKKIN SENSE ,蛇也会回溯。

这段代码只是告诉它如果蛇回溯(如果头部与身体的第一部分或第二部分重合),则蛇头应该回到其初始位置,并恢复其初始方向。

附加代码

正确旋转头部:

private void rotateCorr()
{
    if(p1x[0] = p1x[1] - DOT_SIZE)
    {
          // Your code to rotate p1 head to face the left
    }
    if(p1x[0] = p1x[1] + DOT_SIZE)
    {
          // Your code to rotate p1 head to face the right
    }
    if(p1y[0] = p1y[1] - DOT_SIZE)
    {
          // Your code to rotate p1 head to face the top
    }
    if(p1y[0] = p1y[1] + DOT_SIZE)
    {
          // Your code to rotate p1 head to face the bottom
    }

    // Now, for p2 snake:

    if(p2x[0] = p2x[1] - DOT_SIZE)
    {
          // Your code to rotate p2 head to face the left
    }
    if(p2x[0] = p2x[1] + DOT_SIZE)
    {
          // Your code to rotate p2 head to face the right
    }
    if(p2y[0] = p2y[1] - DOT_SIZE)
    {
          // Your code to rotate p2 head to face the top
    }
    if(p2y[0] = p2y[1] + DOT_SIZE)
    {
          // Your code to rotate p2 head to face the bottom
    }
}

如果头部位于第二部分上方,则将其旋转至面向顶部等