SFML 碰撞检测,C++ -> 重置玩家位置
SFML Collision Detection, C++ -> Reset Player Position
我已经在碰撞检测上工作了好几天了,现在我真的是代码盲:/。一切正常,除了玩家位置重置。我的碰撞检测函数返回相交矩形和1,2,5或61=敌人左上角碰撞,2=敌人左下角碰撞,5=敌人右下角碰撞和,6=敌人右上角碰撞。玩家的信息是:
X=Current X Position;
Y=Current Y Position (the higher Y the lower is the Player at the Screen);
X_INIT= the next X Position of the Player;
Y_Init= the next Y Position of the Player;
Player_width= :);
Player_height= :);
碰撞是用播放器的NEXT位置检测到的。现在,如果玩家从左边(或右边)移动,他应该停在敌人面前。如果他从上面掉下来,也应该停止掉下去。如果他摔倒并向他移动,例如跳跃,他应该在左侧停下来,或者,如果他足够高,他应该降落在顶部。
sf::IntRect rect_player(player->initialpos.x, player->initialpos.y, player->size.x, player->size.y);
sf::IntRect rect_tile(pos.x, pos.y, 50, 50);
s_collision_det collision=collide(rect_player,rect_tile);
float x=player->pos.x;
float y=player->pos.y;
float xx=player->initialpos.x;
float yy=player->initialpos.y;
float sx=player->size.x;
float sy=player->size.y;
//float sy=player->size.y;
float stx=collision.colliding_rect.left;
float sty=collision.colliding_rect.top;
float stsx=collision.colliding_rect.width;
//float stsy=collision.colliding_rect.height;
if (collision.collision==1){
cout<<"im in 1++";
cout << stx<<"##"<< xx+sx;
if (y>=yy){offset_up(player,rect_tile);}
//if ((xx+sx>stx)and(sty!=y+sy)){offset_left(player,rect_tile);};
//if (x+sx>=stx and xx+sx>=stx and y > yy ){offset_down(player,rect_tile);};
}else if (collision.collision==2){
cout<<"im in 2++";
if ((x+sx<=stx or xx+sx>stx)and(sty!=y+sy)){offset_left(player,rect_tile);};
//if ((x>=stx+stsx or xx>stx+stsx) and (sty!=y+sy)){offset_right(player,rect_tile);};
//if (x+sx>=stx and xx+sx>=stx and y < yy ){offset_up(player,rect_tile);};
//if (x+sx>=stx and xx+sx>=stx and y > yy ){offset_down(player,rect_tile);};
}else if (collision.collision==5){
cout<<"im in 5++";
if ((x>=stx+stsx or xx>stx+stsx) and (sty!=y+sy)){offset_right(player,rect_tile);};
//if (x<=stx+stsx and xx<=stx+stsx and y < yy ){offset_up(player,rect_tile);};
//if (x<=stx+stsx and xx<=stx+stsx and y > yy ){offset_down(player,rect_tile);};
}else if (collision.collision==6){
cout<<"im in 6++";
if ((x>=stx+stsx or xx>stx+stsx) and (sty!=y+sy)){offset_right(player,rect_tile);};
//if (x<=stx+stsx and xx<=stx+stsx and y < yy ){offset_up(player,rect_tile);};
//if (x<=stx+stsx and xx<=stx+stsx and y > yy ){offset_down(player,rect_tile);};
}
建议的条件是我已经尝试过的,但没有奏效。我的想法有什么错误?:)谢谢你的帮助。附言:请原谅我英语中的一些语法错误,这不是我的母语。PSS:偏移功能包括:
void offset_left(character *player, sf::IntRect tile){
player->initialpos.x=tile.left-player->size.x;
player->x_speed=0;
cout<<"Offset_Left++";
};
void offset_right(character *player, sf::IntRect tile){
player->initialpos.x=tile.left+tile.width;
player->x_speed=0;
cout<<"Offset_Right++";
};
void offset_up(character *player, sf::IntRect tile){
player->initialpos.y=tile.top-player->size.y;
player->collision.bottom=1;
player->y_speed=0;
cout<<"Offset_Up++";
};
void offset_down(character *player, sf::IntRect tile){
player->initialpos.y=tile.top+tile.height;
player->y_speed=0;
cout<<"Offset_Down++";
};
一些初步建模
我假设你游戏中的所有对象(包括玩家的化身)都有一个边界矩形。
您不仅需要将碰撞检测为布尔结果,还需要确定哪些边正在碰撞(否则将无法处理顶部/侧面的情况)。
两个矩形的碰撞检测
假设一个矩形由其左上角和右下角的点定义为R(x0,y0,x1,y1),并且我们有两个矩形a和B,
A和B相交当且仅当
A.x0 <= B.x1 and
B.x0 <= A.x1 and
A.y0 <= B.y1 and
B.y0 <= A.y1
现在,这还不足以检测碰撞发生在哪一边。您必须考虑到以前的位置才能正确处理碰撞。
为此,您可以计算两个矩形的相对位置。
在一般情况下,每个轴可以有3种可能的状态(左/中/右和上/中/下)。组合这3个位置产生9种可能性(左上、右上、左上、碰撞、右下、左下、右下)。
这4种复合情况(左上、右上、左下和右下)很难处理,所以你可以简单地优先考虑一个轴(通常是X轴,所以只有当玩家的精灵完全在障碍物/敌人/其他物体上方时,才会出现"上方"answers"下方"。
最后,您应该设计一个函数,返回5个可能的值:左、右、上、下和碰撞。
此函数的伪代码如下:
position check_pos (rect a, rect b)
if (a.x1 < b.x0) return left
if (a.x0 > b.x1) return right
if (a.y1 > b.y0) return above
if (a.y0 < b.y1) return below
return collide
现在要检测碰撞,您必须考虑移动对象的当前位置和下一个位置。假设矩形a位于a0位置,速度为va,为了检查与b的碰撞,我们可以这样做:
position check_collision (a0, va, b)
a1 = a0 + va // apply speed to a
current = check_pos (a0, b)
next = check_pos (a1, b)
if (next == collide) return current
return clear
这将返回a将与b碰撞的一侧。它也可能返回"碰撞",但这意味着您没有正确处理上一个时间步骤(即,您允许两个对象继续移动,使它们保持嵌入在彼此中)。
天真的实施
由于部分或所有对象都将移动,因此将矩形定义为参考点和(宽度、高度)对更方便。
Struct Point {
int x;
int y;
Point (int x, int y) : x(x), y(y) {}
Point operator+ (const Point& p) { return Point (x+p.x, y+p.y); }
};
Struct Rectangle {
enum position { left, right, top, left, collide, clear };
Point ref;
Point size;
Rectangle (Point ref, Point size) : ref(ref), size(size) {}
Rectangle (int x, int y, int w, int h) : ref(x,y), size(w,h) {}
position check_pos (const Rectangle& rect)
{
if (ref.x+size.x < rect.ref.x ) return left;
if (ref.x > rect.ref.x+rect.size.x) return right;
if (ref.y+size.y > rect.ref.y ) return top;
if (ref.y < rect.ref.y+rect.size.y) return bottom;
return collide;
}
position check_collision (const Point velocity, const Rectangle& rect)
{
Rectangle a1 = Rectangle(ref+velocity, size);
position cur = check_pos (b);
position next = a1.check_pos (b);
if (next == collide) return cur;
return clear;
}
};
这只是我头脑中的伪C++
不要指望它是开箱即用的,但希望它能让你开始。
- 将值指定给向量(2D)的向量中的某个位置
- 使用Unreal C++获取VR耳机的世界位置/方向
- 写入位置0x0000000C时发生访问冲突
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 如何使用cudaMallocManaged在指针位置初始化对象?(C++)
- 无法获取webot::PositionSensor对象中位置传感器的值
- 非常量变量只读位置的赋值
- 如何定义更改car类中car位置的方法
- 使用迭代器时如何访问对象在向量中的位置?
- 更改.cpp程序的输入文件中数据的位置会意外更改输出
- 求最大元素位置的分治算法
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 为什么我的点没有在 OpenGL 中绘制鼠标所在的位置?
- 为什么玩家控制器"own"偏航俯仰和滚动,但角色"owns"它的位置?
- 如何根据物体位置和速度,玩家位置和向前矢量计算左耳和右耳的音量?(3D声音)
- 如何在TIC TAC TOE中检查获胜者,以及如何不让两个玩家进入同一位置
- SFML 碰撞检测,C++ -> 重置玩家位置
- OpenGL - 旋转玩家位置以面对鼠标指针
- 对将玩家移动到鼠标位置的简单公式感到困惑