C++ 使用向量和多重贴图在特定瓷砖和精灵之间创建边界框碰撞
我生成了一组随机的x和y坐标值,并将它们存储到多重映射中,然后将x坐标值列表复制到向量x,将y坐标值列表复制到向量y,然后在函数中迭代传递它们C++ 使用向量和多重贴图在特定瓷砖和精灵之间创建边界框碰撞,c++,sdl,game-physics,sdl-2,C++,Sdl,Game Physics,Sdl 2,我生成了一组随机的x和y坐标值,并将它们存储到多重映射中,然后将x坐标值列表复制到向量x,将y坐标值列表复制到向量y,然后在函数中迭代传递它们 bool Sprite::collisionExists( int x, int y, SDL_Rect b ) 我将它传递到mycheckCollisions函数中的if语句中,如下所示 collisionExists( x[k],y[l],sprite) 其中,sprite是我在该函数中创建的SDL_Rect类型 我创建了一个填充了岩石的平铺
bool Sprite::collisionExists( int x, int y, SDL_Rect b )
我将它传递到mycheckCollisions函数中的if语句中,如下所示
collisionExists( x[k],y[l],sprite)
其中,sprite是我在该函数中创建的SDL_Rect类型
我创建了一个填充了岩石的平铺贴图,我希望精灵在贴图中四处移动,但如果下一个平铺中有岩石,则无法前进
我面临的问题是,当我创建一个向量并比较每个值时,我似乎无法检测到任何冲突,而在之前,当它仅使用两个图像进行测试时,代码工作得非常好
下面是我随机插入平铺贴图的x和y坐标值的代码
//randomly set positions of the rocks
void setRandomRockPositions()
{
for(int i=0;i<40;i++)
{
int x,y;
int minX=3;
int maxX=8;
x=roll(minX,maxX);
int minY=1;
int maxY=9;
y=roll(minY,maxY);
//if x and y are not the location for the house tile, add a rock
if((x!=9 && y!=5))
{
rocks.insert(std::pair<int, int>(x, y));
}
}
}
一些变量和常量声明
//Screen attributes
const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 728;
// Scaling the tiles to be 80x80
const int TILE_SIZE = 80;
std::multimap<int, int> rocks;
static const int SPRITE_WIDTH = 104;
static const int SPRITE_HEIGHT = 96;
检测精灵与岩石碰撞的代码
bool Sprite::checkCollisions()
{
SDL_Rect sprite;
sprite.x= mPosX;
sprite.y=mPosY;
sprite.w=SPRITE_WIDTH;
sprite.h=SPRITE_HEIGHT;
std::vector<int> x(rocks.size());
std::vector<int> y(rocks.size());
std::multimap<int,int>::iterator it=rocks.begin();
while(it!=rocks.end())
{
for(int i=0;i<rocks.size();i++)
{
x[i]= (*it).first;
++it;
}
}
std::multimap<int,int>::iterator it2=rocks.begin();
while(it2!=rocks.end())
{
for(int j=0;j<rocks.size();j++)
{
y[j]=(*it2).second;
++it2;
}
}
for(int k=0;k<rocks.size();k++)
{
for(int l=0; l<rocks.size();l++)
{
if(collisionExists( x[k],y[l],sprite))
{
return true;
std::cout<<"Collision Detected!"<<std::endl;
}
}
}
return false;
}
基本碰撞检测码
bool Sprite::collisionExists( int x, int y, SDL_Rect b )
{
//The sides of the rectangles
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;
//Calculate the sides of rect A
leftA = x;
rightA = x + SPRITE_WIDTH;
topA = y;
bottomA = y + SPRITE_HEIGHT;
//Calculate the sides of rect B
leftB = b.x;
rightB = b.x + b.w;
topB = b.y;
bottomB = b.y + b.h;
//If any of the sides from A are outside of B
if( bottomA <= topB)//-50 )
{
return false;
}
if( topA >= bottomB)//-50 )
{
return false;
}
if( rightA <= leftB)//+50 )
{
return false;
}
if( leftA >= rightB)//-50 )
{
return false;
}
//If none of the sides from A are outside B
return true;
}
我认为我的问题在于checkCollisions函数,因为控制台上从未显示检测到的输出冲突。我已经尝试了许多不同的循环,并将它们从地图存储到向量,但我仍然不明白为什么碰撞检测停止工作
我认为我的问题在于checkCollisions函数,因为控制台上从未显示检测到的输出冲突
这可能是因为checkCollisions在显示检测到的碰撞之前返回!消息将返回线向下移动一步,它可能会按预期工作:
if(collisionExists( x[k],y[l],sprite))
{
std::cout << "Collision Detected!" << std::endl;
return true;
}
如果您真的想使用每个x和每个y,您至少可以在单个循环中填充单独的向量:
for( const auto & coords : rocks ) {
x.push_back( coords.first );
y.push_back( corrds.second );
}
警告:所有代码仅在浏览器中编写-未编译且未测试 我现在意识到的解决方案其实非常简单。我必须将x和y的每个元素乘以瓷砖的大小 碰撞存在x[k]*瓷砖大小,y[l]*瓷砖大小,精灵
我将x和y坐标传递给函数,这是我的一个基本错误。是的,你是对的,不知为什么我完全没有注意到,但现在,在交换了两行代码后,我的控制台收到4条消息,在我开始移动播放器之前检测到碰撞,我仍然在岩石中移动,因此可能存在一些逻辑错误,我还看不到。而且,我不知道我能做到这一点。rocks是一个多重映射,我想我只能通过迭代器访问它。我不知道我可以通过引用和点表示法来实现。实际上我不知道“const auto”,以前我把它称为引用和点表示法,但我做了一些搜索,现在它更有意义了。虽然我仍然不明白为什么您使用了“const auto&coords”,并且没有通过迭代器访问“multimap rocks”。for elem:container是C++11中新增的一个范围,您可以添加辅助属性,如const,or&for引用。编写const&elem:container而不是container\u type::const\u迭代器iter=container.begin;iter!=容器端++iter清楚地表明,您希望对容器中的每一个元素都做些什么,但不改变其中任何一个。
for( const auto & coords : rocks ) {
x.push_back( coords.first );
y.push_back( corrds.second );
}