我正在用一个简单的基于图块的平台程序在C ++中实现一些非常基础的平台物理。我一直在严格按照算法(https://gamedev.stackexchange.com/questions/18302/2d-platformer-collisions)进行操作,但是仍然出现奇怪的毛刺,玩家在瓷砖上弹跳。我不确定到底发生了什么。该代码在C ++中使用SDL
void Player::update(vector< vector<Tile> > map) {
vector<Tile> collidingTiles;
x += xVel;
y += yVel;
boundingBox = Rect(x,y,16,16);
for(int iy=0;iy<MAPH;iy++) {
for(int ix=0;ix<MAPW;ix++) {
if (map[ix][iy].solid == true) {
if (boundingBox.collide(map[ix][iy].boundingBox)) {
collidingTiles.push_back(map[ix][iy]); // store all colliding tiles, will be used later
Rect intersectingRect = map[ix][iy].boundingBox; // copy the intersecting rect
float xOffset = x-intersectingRect.x; // calculate x-axis offset
float yOffset = y-intersectingRect.y; //calculate y-axis offset
if (abs(xOffset) < abs(yOffset)) {
x += xOffset;
}
else if (abs(xOffset) > abs(yOffset)) {
y += yOffset;
}
boundingBox = Rect(x,y,16,16); // reset bounding box
yVel = 0;
}
}
}
}
if (collidingTiles.size() == 0) {
yVel += gravity;
}
};
最佳答案
if (abs(xOffset) < abs(yOffset)) {
x += xOffset;
}
else if (abs(xOffset) > abs(yOffset)) {
y += yOffset;
}
yVel = 0;
在此代码中,如果
abs(xOffset) == abs(yOffset)
,则什么也没有发生,这意味着玩家可以对角输入实心磁贴。如果必须选择算法,则删除第二项测试应解决此问题并修改y
:另外,我想知道如果发生水平碰撞,您是否真的要重置垂直速度。这也意味着如果碰撞是水平的,重力仍然应该施加(否则,墙壁和天花板会发粘)。
int gravityApplies = true;//fix 2a
...
if (abs(xOffset) < abs(yOffset)) {
x += xOffset;
xVel = 0; //fix 2
}
else { //fix 1
y += yOffset;
yVel = 0; //fix 2
if( yOfsset < 0 ){ // fix 2a
gravityApplies = false;
}
}
...
if (gravityApplies) { //fix 2a
yVel += gravity;
}
如果要弹性碰撞,请使用
yVel = -yVel
而不是yVel = 0
(另一方向类似)。您甚至可以执行yVel = yVel * rest
,其中rest
的范围从-1
到0
(-0.8
是一个不错的选择)以获得半弹性碰撞。关于c++ - 平台物理反弹故障C++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14660558/