在游戏中检查蛇是否撞到自己身上 我用C++编写了蛇,使用OpenGL和GLFW编写。我试图实现一个功能,当蛇头撞到它的身体时,游戏退出。 下面是我编写的Snake类的move()和CrashCheck()函数。 x_pos是一个浮点数组,用于存储蛇身某段的x_坐标。y_pos对y_坐标也执行相同的操作。“长度”是蛇的身体分段数,在蛇吃食物时增加(尚未实现)。x_速度和y_速度存储沿轴分段的速度。蛇永远不能同时沿着两条轴线移动;此外,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; } } } } void draw(浮动赢方) { 对于(int a=0;a=0;a--) { 如果(a>0) { 如果(x_位置[a]>=x_位置[a-1]&&x_速度[a]

在游戏中检查蛇是否撞到自己身上 我用C++编写了蛇,使用OpenGL和GLFW编写。我试图实现一个功能,当蛇头撞到它的身体时,游戏退出。 下面是我编写的Snake类的move()和CrashCheck()函数。 x_pos是一个浮点数组,用于存储蛇身某段的x_坐标。y_pos对y_坐标也执行相同的操作。“长度”是蛇的身体分段数,在蛇吃食物时增加(尚未实现)。x_速度和y_速度存储沿轴分段的速度。蛇永远不能同时沿着两条轴线移动;此外,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; } } } } void draw(浮动赢方) { 对于(int a=0;a=0;a--) { 如果(a>0) { 如果(x_位置[a]>=x_位置[a-1]&&x_速度[a],c++,opengl,glfw,C++,Opengl,Glfw,编辑: 新移动功能 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];

编辑: 新移动功能

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];
              }
        }
for(int a=0;a0)
{
如果(x_速度[a]<0和x_位置[a]>=x_位置[a-1])
{
x_位置[a]+=x_速度[a];
如果(x_位置[a]==x_位置[a-1])
{
y_速度[a]=y_速度[a-1];
x_速度[a]=0;
继续;
}
}
如果(x_速度[a]>0&&x_位置[a]0&&y_位置[a]=y_位置[a-1])
{
y_pos[a]+=y_速度[a];
if(y_pos[a]==y_pos[a-1])
{
x_速度[a]=x_速度[a-1];
y_速度[a]=0;
}
}
}
其他的
{
x_位置[0]+=x_速度[0];
y_位置[0]+=y_速度[0];
}
}

造成了一些问题。蛇打断了它。同时旋转的次数太多。只有前两个块保持运动状态

我强烈建议您使用动态容器保存蛇身体的坐标。这允许您获取蛇新位置的坐标,并在容器中搜索坐标。如果找到了那一点,蛇就撞到自己身上了

类似地,您可以为墙、块和其他不属于线路板的实体的点创建容器


另一种方法是使用网格数据结构(或矩阵),并在其中放置代表蛇体和其他障碍物的值。

如果我是你,我将存储一个
std::set
,其中包含蛇无法到达的所有无效坐标。这将包括:

  • “游乐场”的边界
  • 障碍物
  • 蛇身
然后,考虑到蛇的每一步移动的x/y速度,我会首先尝试
将位置插入
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;
    }
};
#包括
使用名称空间std;
typedef对tInvalidLocation;
结构ltSeCmp
{
布尔运算符()(tInvalidLocation s1,tInvalidLocation s2)常量
{
如果(s1.first==s2.first)返回s1.second>s2.second;
返回s1.first>s2.first;
}
};
排字装置的有效位置;
CInvalidPlaces类
{
私人:
tInvalidLocations mI