2011-08-05 13 views
0

私はOpenGLとGLFWを使ってC++でSnakeを書いています。私はヘビの頭が体にクラッシュすると、ゲームが終了する場所を実装しようとしています。 ここに、私が書いた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()関数で修正を提案できれば、それは役に立ちます。スネークがゲーム内で叩かれるのを確認してください。

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

新しい移動機能。ヘビはそれを壊すので、同時に多くのターンがある。最初の2つのブロックだけが動いています

+0

は、だからあなたはあります質問、 "蛇の身体を引き起こす私のコードのどこに問題がありますか?別の? " – razlebe

+0

は、gamedev.stackexchange.comに属します – Puppy

答えて

0

私があなただったら、スネークが行けない無効な座標をすべてstd::setで保存します。つまり含まれる:

  • 蛇の各移動のためにそして "遊び場"
  • 障害
  • 蛇の身体

の境界線を、X/Yの速度(S)を考慮します私は最初にInsertLocationCInvalidPlacesにしようとしていましたが、その場合は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:グリッドは浮動小数点値を持つべきではありません。ある積分値に正規化する。 Karl氏によると、グリッドを画面にマッピング(描画)する機能が必要です。 –

関連する問題