2017-06-04 36 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+對你來說 –