Skip to content

Commit

Permalink
fix: [#1638] Re-tool easeTo actions to use velocity (#1640)
Browse files Browse the repository at this point in the history
Closes #1638 

## Changes:

- Calculate the equivalent velocity needed to lerp instead of directly setting position
- Added tests
  • Loading branch information
eonarheim authored Sep 12, 2020
1 parent 13abcb6 commit 8947c58
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed

- Fixed Animation flicker bug when switching to an animation ([#1636](https://github.com/excaliburjs/Excalibur/issues/1636))
- Fixed `ex.Actor.easeTo` actions, they now use velocity to move Actors ([#1638](https://github.com/excaliburjs/Excalibur/issues/1638))

<!--------------------------------- DO NOT EDIT BELOW THIS LINE --------------------------------->
<!--------------------------------- DO NOT EDIT BELOW THIS LINE --------------------------------->
Expand Down
12 changes: 8 additions & 4 deletions src/engine/Actions/Action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export class EaseTo implements Action {
this._initialized = true;
}

// Need to update lerp time first, otherwise the first update will always be zero
this._currentLerpTime += delta;
let newX = this.actor.pos.x;
let newY = this.actor.pos.y;
if (this._currentLerpTime < this._lerpDuration) {
Expand All @@ -64,13 +66,13 @@ export class EaseTo implements Action {
} else {
newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);
}
this.actor.pos.x = newX;
this.actor.pos.y = newY;

this._currentLerpTime += delta;
// Given the lerp position figure out the velocity in pixels per second
this.actor.vel.x = (newX - this.actor.pos.x) / (delta / 1000);
this.actor.vel.y = (newY - this.actor.pos.y) / (delta / 1000);
} else {
this.actor.pos.x = this._lerpEnd.x;
this.actor.pos.y = this._lerpEnd.y;
this.actor.vel = Vector.Zero;
//this._lerpStart = null;
//this._lerpEnd = null;
//this._currentLerpTime = 0;
Expand All @@ -84,6 +86,8 @@ export class EaseTo implements Action {
this._initialized = false;
}
public stop(): void {
this.actor.vel.y = 0;
this.actor.vel.x = 0;
this._stopped = true;
}
}
Expand Down
39 changes: 39 additions & 0 deletions src/spec/ActionSpec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as ex from '@excalibur';
import { TestUtils } from './util/TestUtils';
import { ExcaliburMatchers } from 'excalibur-jasmine';

describe('Action', () => {
let actor: ex.Actor;
Expand All @@ -8,6 +9,7 @@ describe('Action', () => {
let scene: ex.Scene;

beforeEach(() => {
jasmine.addMatchers(ExcaliburMatchers);
engine = TestUtils.engine({ width: 100, height: 100 });

actor = new ex.Actor();
Expand Down Expand Up @@ -200,6 +202,43 @@ describe('Action', () => {
});
});

describe('easeTo', () => {
it('can be eased to a location given an easing function', () => {
expect(actor.pos).toBeVector(ex.vec(0, 0));

actor.actions.easeTo(100, 0, 1000, ex.EasingFunctions.EaseInOutCubic);

actor.update(engine, 500);
expect(actor.pos).toBeVector(ex.vec(50, 0));
expect(actor.vel).toBeVector(ex.vec(100, 0));

actor.update(engine, 500);
expect(actor.pos).toBeVector(ex.vec(100, 0));
expect(actor.vel).toBeVector(ex.vec(0, 0));

actor.update(engine, 500);
expect(actor.pos).toBeVector(ex.vec(100, 0));
expect(actor.vel).toBeVector(ex.vec(0, 0));
});

it('can be stopped', () => {
expect(actor.pos).toBeVector(ex.vec(0, 0));

actor.actions.easeTo(100, 0, 1000, ex.EasingFunctions.EaseInOutCubic);

actor.update(engine, 500);
expect(actor.pos).toBeVector(ex.vec(50, 0));
expect(actor.vel).toBeVector(ex.vec(100, 0));

actor.actions.clearActions();

// actor should not move and should have zero velocity after stopping
actor.update(engine, 500);
expect(actor.pos).toBeVector(ex.vec(50, 0));
expect(actor.vel).toBeVector(ex.vec(0, 0));
});
});

describe('repeat', () => {
it('can repeat previous actions', () => {
expect(actor.pos.x).toBe(0);
Expand Down

0 comments on commit 8947c58

Please sign in to comment.