2017-06-04 75 views
0

我在创建游戏时遇到问题,除了一件事情之外,一切都按照定时器延迟重绘当我在棋盘重绘之前做了一次以上的动作时,我的蛇就有可能陷入彼此之中。我无法处理这个问题,但我不知道如何避免这种情况,我正考虑在按钮之间设置一个延迟,但这是不可能的,因为这个游戏是针对两个玩家的。我试图阻止蛇自己回来。有人能帮我解决问题吗?谢谢。无法处理简单的Java.swing游戏中的移动错误

代表问题几张照片:

普通游戏:
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; 
     } 
    } 
} 
+0

我不不知道你的错误的来源,甚至你的错误是什么(你是否试图防止蛇自己回来?),但我看到的一个巨大的问题是,你正在阅读和重新读你的图像数百在您的KeyAdapater内的时间 - 为什么在地球上 做这个?为什么不读**一次图像**并将它们存储在变量中以便重复使用? –

+0

是的,我试图阻止蛇自己回来。随着图片你有权利,我会解决这个问题,我只是在编程。 – x3non

+0

那么你的问题不是GUI问题,而你提出的GUI解决方案将会失败,而是一个逻辑问题 - 如何防止蛇自身重叠。为了解决这个问题,你将不得不在事情的逻辑方面工作 - 测试蛇向下移动到哪里,并在允许它发生之前检查它是否是有效的位置。 –

回答

3

我有完全相同的问题。我尝试了不同的内置方法,但它们不适合我。但这是我如何绕过我的方法的问题:

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++; 
} 

我完全知道你遇到的故障,所以这应该适合你。

基本上,如果按下多个按钮,蛇会自行回溯,因为它首先会注册该密钥有效,但随后会移动以执行无效密钥。所以,即使在逻辑上它使得蛇回退。

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

附加代码

要旋转正确的头:

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 
    } 
} 

如果头是第二部分的上方,其旋转以面向顶部,等等

+0

因为我做了同样的蛇游戏,并面临同样的故障。甚至有一个包含ArrayList的解决方案,但似乎也没有效果。 –

+0

好的,所以现在我编辑它也包含一个解释。 –

+0

谢谢。 1+对你来说 –