2011-08-05 77 views
0

我正在用C++編寫Snake,使用OpenGL和GLFW。我試圖在遊戲退出時實現一個功能,當蛇頭撞到它的身體時。 這是我寫的Snake類的move()和CrashCheck()函數。 x_pos是一個浮點數組,用於存儲蛇體的一段的x_coordinate。 y_pos和y_coordinate一樣。長度是蛇體段的數量,當蛇吃食物時增加(尚未實施)。 x_speed和y_speed存儲沿軸的線段速度。蛇不能同時沿着兩個軸移動;另外,float MAX_S = 0.00075;。我也包含了我的draw()函數。 Fix_Snake_x和Fix_Snake_y是重新對齊蛇的分段的函數(因爲它們保持分離並對遊戲造成嚴重破壞)。我知道這是修正問題的一種愚蠢的方法,所以如果您可以在move()函數中提出修復建議,那將會很有幫助。檢查Snake是否在遊戲中自爆

void draw(float win_aspect) 
    { 
    for(int a = 0; a < length; a++) 
     { 
     Fix_Snake_y(); 
     glBegin(GL_QUADS); 
     glColor3f(1.0,0.0,0.0); 
     glVertex2f(x_pos[a],y_pos[a]); 
     glVertex2f((x_pos[a]+0.05),y_pos[a]); 
     glVertex2f((x_pos[a]+0.05),y_pos[a]-0.05); 
     glVertex2f(x_pos[a],y_pos[a] - 0.05); 
     glEnd(); 
     Fix_Snake_x(); 
     } 
    } 

void move() 
    { 
     for(int a = length ; a >= 0; a--) 
     { 
      if(a > 0) 
      { 
       if(x_pos[a] >= x_pos[a-1] && x_speed[a] < 0) 
       { 
        x_pos[a] += -MAX_S; 
        Fix_Snake_y(); 
        Fix_Snake_x(); 
        if(x_pos[a] <= x_pos[a - 1]) 
        { 
        x_speed [a] = 0; 
        if(y_pos[a] <= y_pos[a-1]) 
        { 
          y_speed[a] = MAX_S; 
        } 
        else 
        { 
          y_speed[a] = -MAX_S; 
        } 
        } 
       } 
       if(x_pos[a] <= x_pos[a-1] && x_speed[a] > 0) 
       { 
        x_pos[a] += MAX_S; 
        Fix_Snake_y(); 
        Fix_Snake_x(); 
        if(x_pos[a] >= x_pos[a - 1]) 
        { 
         x_speed [a] = 0; 
         if(y_pos[a] <= y_pos[a-1]) 
         { 
          y_speed[a] = MAX_S; 
         } 
         else 
         { 
          y_speed[a] = -MAX_S; 
         } 
        } 
       } 
       if(y_pos[a] <= y_pos[a-1] && y_speed[a] > 0) 
       { 
        y_pos[a] += MAX_S; 
        Fix_Snake_y(); 
        Fix_Snake_x(); 
        if(y_pos[a] >= y_pos[a-1]) 
        { 
         y_speed[a] = 0; 
         if(x_pos[a] >= x_pos[a-1]) 
         { 
          x_speed[a] = -MAX_S; 
         } 
         if(x_pos[a] <= x_pos[a-1]) 
         { 
          x_speed[a] = MAX_S; 
         } 
        } 
       } 
       if(y_pos[a] >= y_pos[a-1] && y_speed[a] < 0) 
       { 
        y_pos[a] += -MAX_S; 
        Fix_Snake_y(); 
        Fix_Snake_x(); 
        if(y_pos[a] <= y_pos[a-1]) 
        { 
         y_speed[a] = 0; 
         if(x_pos[a] >= x_pos[a-1]) 
         { 
          x_speed[a] = -MAX_S; 
         } 
         if(x_pos[a] <= x_pos[a-1]) 
         { 
          x_speed[a] = MAX_S; 
         } 
        } 
       } 
     } 


      if(a == 0) 
       { 
        x_pos[0] += x_speed[0]; 
        y_pos[0] += y_speed[0]; 
        Fix_Snake_y(); 
        Fix_Snake_x(); 
       } 
      CrashCheck(); 
      } 
     } 
     void CrashCheck() 
     { 
     for(int a = 1; a < length; a++) 
      { 
      if(y_speed[0] > 0 && y_speed[a] == 0) 
       { 
       if(x_pos[0] < x_pos[a] && x_pos[0] < x_pos[a] + 0.05) 
        { 
        if(y_pos[0] < y_pos[a] && y_pos[0] > y_pos[a] - 0.05) 
         { 
         exit(0); 
         } 
        } 
       } 
      else if(y_speed[0] < 0 && y_speed[a] == 0) 
       { 
       if(x_pos[0] > x_pos[a] && x_pos[0] < x_pos[a] + 0.05) 
        { 
        if(y_pos[0] < y_pos[a] && y_pos[0] > y_pos[a] - 0.05) 
         { 
         exit(0); 
         } 
        } 
       } 
      } 
     } 
void Fix_Snake_x() 
    { 
    for(int a = 1; a<length; a++) 
     { 
     if(a > 0) 
      { 
      if(x_pos[a] <= x_pos[a-1] - 0.05) 
       { 
       x_pos[a] = x_pos[a-1] - 0.05; 
       } 
      if(x_pos[a] >= x_pos[a -1] + 0.05) 
       { 
       x_pos[a] = x_pos[a-1] + 0.05; 
       } 
      } 
     } 
    } 
    void Fix_Snake_y() 
    { 
    for(int a = 1; a < length; a++) 
      { 
      if(a > 0) 
       { 
       if(y_pos[a] <= y_pos[a-1] - 0.05) 
        { 
        y_pos[a] = y_pos[a-1] - 0.05; 
        } 
       if(y_pos[a] >= y_pos[a-1] + 0.05) 
        { 
        y_pos[a] = y_pos[a-1] + 0.05; 
        } 
       } 
      } 
    } 

編輯: 新的移動功能

for(int a = 0; a < length; a++) 
     { 
      if(a > 0) 
       { 
       if(x_speed[a] < 0 && x_pos[a] >= x_pos[a-1]) 
        { 
        x_pos[a] += x_speed[a]; 
        if(x_pos[a] == x_pos[a-1]) 
         { 
         y_speed[a] = y_speed[a-1]; 
         x_speed[a] = 0; 
         continue; 
         } 
        } 
       if(x_speed[a] > 0 && x_pos[a] <= x_pos[a-1]) 
        { 
        x_pos[a] += x_speed[a]; 
        if(x_pos[a] == x_pos[a-1]) 
         { 
         y_speed[a] = y_speed[a-1]; 
         x_speed[a] = 0; 
         continue; 
         } 
        } 
       if(y_speed[a] > 0 && y_pos[a] <= y_pos[a-1]) 
        { 
        y_pos[a] += y_speed[a]; 
        if(y_pos[a] == y_pos[a-1]) 
         { 
         x_speed[a] = x_speed[a-1]; 
         y_speed[a] = 0; 
         } 
        } 
       if(y_speed[a] < 0 && y_pos[a] >= y_pos[a-1]) 
        { 
        y_pos[a] += y_speed[a]; 
        if(y_pos[a] == y_pos[a-1]) 
         { 
         x_speed[a] = x_speed[a-1]; 
         y_speed[a] = 0; 
         } 
        } 
       } 
      else 
       { 
       x_pos[0] += x_speed[0]; 
       y_pos[0] += y_speed[0]; 
       } 
     } 

造成了一些問題。蛇打破它,有太多同時轉彎。只有前兩個塊保持運動

+0

那麼,你的問題,「我的代碼中導致蛇體的問題在哪裏?分開嗎?「 – razlebe

+0

屬於gamedev.stackexchange.com – Puppy

回答

0

如果我是你的話,我會存儲一個std::set,其中包含蛇無法進入的所有無效座標。這將包括:

  • 的 「操場」
  • 障礙的邊界
  • 蛇的身體

那麼對於蛇的每一個舉動,考慮到X/Y速度(S)我會首先嚐試InsertLocation轉換成CInvalidPlaces,如果返回true那麼我可以在那裏跳躍,如果false那麼蛇正要撞牆,邊界或它自己的身體和「遊戲」就可以完成。下面是該代碼:

#include <set> 
using namespace std; 

typedef pair<int,int> tInvalidLocation; 

struct ltSeCmp 
{ 
    bool operator()(tInvalidLocation s1, tInvalidLocation s2) const 
    { 
     if (s1.first == s2.first) return s1.second > s2.second; 
     return s1.first > s2.first; 
    } 
}; 

typedef set<tInvalidLocation, ltSeCmp> tInvalidLocations; 

class CInvalidPlaces 
{ 
private: 
    tInvalidLocations mInvalid; //this set will hold all the invalid locations for the snake to go to 
public: 
    bool InsertLocation(tInvalidLocation iLoc) 
    { 
     if (mInvalid.find(iLoc) != mInvalid.end()) return false; //check if the location is already in the set 
     //we survived.. it's safe to go there :) 
     mInvalid.insert(iLoc); 
     return true; 
    } 
    bool RemoveLocation(tInvalidLocation iLoc) 
    { 
     if (mInvalid.find(iLoc)== mInvalid.end()) return false; 
     mInvalid.insert(iLoc); 
     return true; 
    } 
}; 

你將不得不額外做的是:

  • 最初加入的利潤,所有的障礙,只是因爲他們是從哪裏蛇的所有位置蛇開始
  • 修改的移動程序,這樣,當蛇移動時,它也有從CInvalidPlaces刪除它使用尾巴RemoveLocation
  • 您實現「放大」的蛇,你還必須增加後CInvalidPlaces額外的部分。

如果需要,您可以在以下地方找到一個stl::set額外信息:

HTH,
JP

0

我強烈建議您使用動態容器來保存蛇體的座標。這使您可以獲取蛇新位置的座標並在容器中搜索座標。如果找到了這個點,那蛇就會陷入其中。

類似地,您可以擁有容器,用於牆壁和塊以及不屬於董事會一部分的其他實體。

另一種方法是使用網格數據結構(或矩陣),並在其中放置代表蛇體和其他障礙物的值。

+0

容器是動態的。它存儲了蛇體的當前位置。搜索方法是一個好主意,但問題是搜索確切的座標永遠不會給出精確的匹配。也許我試着嘗試塊的中心座標匹配? – viraj

+0

@viraj,您無法獲得完全匹配的主要問題是您沒有分開模型和視圖。如果你使用了網格,那麼這條蛇就可以進入或不進入。浮點座標只能用於顯示蛇,而不能用於遊戲邏輯。這也可以幫助你解決問題。 –

+0

@viraj:網格不應該有浮點值。歸一化到某個整數值。正如卡爾所說,你需要一些將網格映射(繪製)到屏幕上的功能。 –