excaliburjs / Excalibur

🎮 Your friendly TypeScript 2D game engine for the web 🗡️
https://excaliburjs.com
BSD 2-Clause "Simplified" License
1.81k stars 188 forks source link

Continuous collision easeBy/easeTo action goes through colliders #2803

Open eonarheim opened 11 months ago

eonarheim commented 11 months ago

The easing implementation progressively increases the velocity if the position isn't where it should be according to the easing function, which causing the object to update over the collider eventually.

Ultimately the correct solution to this will likely be improvements to Excalibur's continuous collision system to do a shape cast or a raycast to prevent tunneling

// Given the lerp position figure out the velocity in pixels per second
this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));

Workaround

Other actions like moveTo/moveBy work with collision because they modify the velocity

OR

player.on('precollision', (evt) => {
  // if collision is mostly in the direction of intersection suspend all actions
  const dir = Math.abs(
    evt.intersection.normalize().dot(player.vel.normalize())
  );
  console.log(dir);
  if (dir > 0.5) {
    player.actions.clearActions();
  }
});

Discussed in https://github.com/excaliburjs/Excalibur/discussions/2802

Originally posted by **ikiselev1989** November 14, 2023 There is seem like issue in physic engine. I expect that active collider will collide with fixed one and will freezed but it's going through. [code](https://stackblitz.com/edit/typescript-shetwa?file=index.ts) ``` import { Engine, CollisionGroupManager, Actor, CollisionGroup, CollisionType, vec, EasingFunctions, Physics, } from 'excalibur'; const engine = new Engine({ width: 600, height: 400, }); engine.start(); engine.showDebug(true); const player = new Actor({ width: 50, height: 50, collisionType: CollisionType.Active, }); engine.add(player); const wall = new Actor({ width: 50, height: 200, pos: vec(200, 0), collisionType: CollisionType.Fixed, }); engine.add(wall); engine.input.keyboard.on('release', () => { player.pos.setTo(0, 0); player.actions.easeBy(vec(400, 0), 500, EasingFunctions.EaseInOutQuad); }); ```
github-actions[bot] commented 9 months ago

This issue hasn't had any recent activity lately and is being marked as stale automatically.