2011-12-04 73 views
1

我正在寫一個蛇遊戲,具體來說就是一個蜈蚣遊戲。它需要我畫一條蛇,那條蛇會自動移動一行一行。蛇遊戲,如何使蛇移動?

我畫了一條蛇,它可以從左側移動到右側。然而,問題是:

我不能讓蛇變更線,如果完成第一線,我需要它改變到第二線和從右側開始。

我的代碼是這樣的:

private void move() 
{ 

    myCentipedes[0] = 
     new Centipede(Settings.centipedeStartSize, Settings.RIGHT, 
       Settings.DOWN); 
    myCentipedes[0].segments = new Point[Settings.centipedeStartSize]; 
    myCentipedes[0].segments[0] = new Point(0, 0); 

    boolean dr = true; 

    if (dr == true) { 
     if (myCentipedes[0].segments[0].x < 30) { 
      System.out.println(myCentipedes[0].segments[0].x + 
         " " + 
         myCentipedes[0].segments[0].y); 
      myCentipedes[0].segments[0] = new Point(x, 0); 
      for (int i = 1; i < 10; i++) { 
       myCentipedes[0].segments[i] = 
        new Point(myCentipedes[0].segments[i - 1].x - 1, 
          myCentipedes[0].segments[i - 1].y); 
      } 
      x++; 
     } 
    } 

    if (myCentipedes[0].segments[0].x == 29) { 
     x = 29; 
     dr = false; 
    } 

    if (dr == false) { 
     if (myCentipedes[0].segments[0].x > 0) { 
      myCentipedes[0].segments[0] = new Point(x, 1); 

      for (int i = 1; i < 10; i++) { 
       myCentipedes[0].segments[i] = 
        new Point(myCentipedes[0].segments[i - 1].x + 1, 1); 
      } 
      x--; 
     } 
    } 
} 

回答

3

在我看來,你的每一個舉動重新創建整個蜈蚣:

private void move() 
{ 

    myCentipedes[0] = 
     new Centipede(Settings.centipedeStartSize, Settings.RIGHT, 
       Settings.DOWN); 

是重新創建蜈蚣每move()故意?還是應該move()將蜈蚣從頭到尾完全放在板子上? (如果是這樣,你需要一些循環添加到這個方法。)

我假設myCentipedes[0]僅僅是爲將來的擴展,同時在板涉及兩個或兩個以上蜈蚣的佔位符。這種過度泛型的編程有時會使代碼在初始編程時更難讀寫,而且幾乎肯定無濟於事。您可以隨時重新因子move()方法上一個蜈蚣工作的move(int centipede)方法是在一個特定的蜈蚣,並且爲每一個董事會蜈蚣調用move(int)一個move()方法效果。或者,您可能會發現將移動代碼放入Centipede類更容易,並且需要刪除數組索引,然後使用類成員存儲。

boolean dr = true; 

if (dr == true) { 

dr總是等於true在這一點上。你也可以刪除變量和測試。

for (int i = 1; i < 10; i++) { 
    myCentipedes[0].segments[i] = 
     new Point(myCentipedes[0].segments[i - 1].x - 1, 
       myCentipedes[0].segments[i - 1].y); 
} 

既然你計數,你會真正從segment[0]值通過對陣列中的所有元素,每次一個複製元素。難道你不能只分配Point對象新的數組索引?從i=centipede.segments.length開始計數,它會看起來更像是這樣的:

for (int i=myCentipede[0].segments.length; i > 0; i--) { 
    myCentipede[0].segments[i] = myCentipede[0].segments[i-1]; 
} 
myCentipede[0].segments[0] = new Point(...,...); 

一些你的測試可以簡化爲:

if (myCentipedes[0].segments[0].x == 29) { 
    x = 29; 
    dr = false; 
} 

if (dr == false) { 
    if (myCentipedes[0].segments[0].x > 0) { 

如果dr == false在這一點上,你可能也有寫這樣的代替:

if (myCentipedes[0].segments[0].x == 29) { 
    x = 29; 

    if (myCentipedes[0].segments[0].x > 0) { 

但是第二個if顯然不是ne eded - 畢竟,29 > 0

當你在這裏時,用常數(Settings.centipedeStartSize)清除所有硬編碼10或找到蜈蚣的實際長度(myCentipedes[0].segments.length)。


現在,我已經批評了你目前的做法,我想提出一個不同的策略:

退一步和向下打破你的問題成更小的方法。

您已嵌入兩個for循環,一次移動蜈蚣一個片段,方法是將segment[i-1]的值分配給segment[i]。不要複製代碼,而是使用for循環的主體編寫一個新方法來向前移動蜈蚣。使每個經過該函數的新第一個元素具有Point對象。 (不要忘了做它計數下來而不是

一旦你已經碎裂開來的for循環,我認爲這將是更容易做出力所能及的變化是必要的旅行從左-right 從右到左。您可能想要使用嵌套的for循環編寫它 - 一個用於控制垂直尺寸,在其中可能包含一個或兩個新的for循環來控制水平尺寸。使這些循環與簡單的Centipede c一起工作,而不是您目前得到的複雜表達式。

分崩離析較大的功能分成更小的功能會給你一個更好的機會來測試您的隔離功能 - 測試運動手動,用簡單的試驗方法是這樣的:

move_forward(Centipede c, Point p) { 
    /* code to move forward one space to occupy `p` */ 
} 

test_right() { 
    Centipede c = new Centipede(/* ... */); 
    move_forward(c, new Point(0,0)); 
    move_forward(c, new Point(1,0)); 
    move_forward(c, new Point(2,0)); 
    move_forward(c, new Point(3,0)); 
    move_forward(c, new Point(4,0)); 
    move_forward(c, new Point(5,0)); 
    /* ... */ 
} 

慢慢來,在你編寫它們時測試每種方法,我認爲你會發現這是一個比目前看起來更容易的問題。

+0

+1偉大的意見 – millhouse

+0

我可以有你的電子郵件地址,我認爲這應該會更好,如果我給你我的代碼,並直接與你溝通。 – leohu

+0

我的電子郵件地址並不難從我的個人資料中找到 - 但請注意,我一次忽略了我的電腦數週。在堆棧上提出問題可能是獲得答案的更好方法 - 尤其是因爲您可以通過這種方式獲得更多種類的答案,並且可以對答案進行批判,反駁和改進。 :) – sarnold