Платформа физики прыгающего глюка Stack Overflow

Я реализую некоторые базовые физики платформера в 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;
}
};

1

Решение

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 хороший выбор), чтобы получить полуэластичные столкновения.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]