Browse Source

do huge movements in steps instead of at once

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
9817aae87d
2 changed files with 31 additions and 10 deletions
  1. 4
    0
      libswan/include/swan/Vector2.h
  2. 27
    10
      libswan/src/traits/BodyTrait.cc

+ 4
- 0
libswan/include/swan/Vector2.h View File

@@ -23,6 +23,10 @@ struct Vector2 {
return (T)std::sqrt((double)(this->x * this->x + this->y * this->y));
}

constexpr Vector2<T> sign() {
return Vector2<T>(x > 0 ? 1 : -1, y > 0 ? 1 : -1);
}

constexpr operator std::pair<T, T>() const {
return std::pair<T, T>(x, y);
}

+ 27
- 10
libswan/src/traits/BodyTrait.cc View File

@@ -57,6 +57,14 @@ void PhysicsBody::collideY(WorldPlane &plane) {
on_ground_ = false;

for (int x = (int)floor(bounds.left() + epsilon); x <= (int)floor(bounds.right() - epsilon); ++x) {
int ty = (int)floor(bounds.top() + epsilon);
Tile &top = plane.getTile({ x, ty });
if (top.is_solid_) {
bounds.pos.y = (float)ty + 1.0;
collided = true;
break;
}

int by = (int)floor(bounds.bottom() - epsilon);
Tile &bottom = plane.getTile({ x, by });
if (bottom.is_solid_) {
@@ -65,14 +73,6 @@ void PhysicsBody::collideY(WorldPlane &plane) {
on_ground_ = true;
break;
}

int ty = (int)floor(bounds.top() + epsilon);
Tile &top = plane.getTile({ x, ty });
if (top.is_solid_) {
bounds.pos.y = (float)ty + 1.0;
collided = true;
break;
}
}

if (collided) {
@@ -92,9 +92,26 @@ void PhysicsBody::update(WorldPlane &plane, float dt) {
vel_ += (force_ / mass_) * dt;
force_ = { 0, 0 };

pos_.x += vel_.x * dt;
Vec2 dist = vel_ * dt;
Vec2 dir = dist.sign();
Vec2 step = dir * 0.4;

// Move in increments of at most 'step', on the X axis
while (abs(dist.x) > abs(step.x)) {
pos_.x += step.x;
collideX(plane);
dist.x -= step.x;
}
pos_.x += dist.x;
collideX(plane);
pos_.y += vel_.y * dt;

// Move in increments of at most 'step', on the Y axis
while (abs(dist.y) > abs(step.y)) {
pos_.y += step.y;
collideY(plane);
dist.y -= step.y;
}
pos_.y += dist.y;
collideY(plane);
}


Loading…
Cancel
Save