From 584728a1293a5215baaca4e7de813b2a85b8253d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 7 Jan 2016 11:22:59 +0100 Subject: Implement smooth transitions --- src/control/MapContext.ts | 54 ++++++++++++++++++++++++++++++++------------- src/model/EntityPosition.ts | 5 ++++- src/model/Position.ts | 26 ++++++++++++++++++++++ src/model/Transition.ts | 8 +++++++ src/view/MapView.ts | 30 +++++++++++++++++++++---- 5 files changed, 103 insertions(+), 20 deletions(-) create mode 100644 src/model/Transition.ts diff --git a/src/control/MapContext.ts b/src/control/MapContext.ts index df7eff6..1e417e7 100644 --- a/src/control/MapContext.ts +++ b/src/control/MapContext.ts @@ -6,6 +6,7 @@ import Entity from '../model/Entity'; import EntityPosition from '../model/EntityPosition'; import MapData from '../model/MapData'; import Position from '../model/Position'; +import Transition from '../model/Transition'; import InputHandler from '../view/InputHandler'; import MapView from '../view/MapView'; @@ -38,24 +39,47 @@ export default class MapContext { this.entities[entity.position.asString()] = entity; } + private addTransition(entity: EntityPosition, dest: Position, start: number, dur: number) { + entity.transition = new Transition(start, start+dur, entity.position, dest); + } + + private finishTransition(entity: EntityPosition) { + entity.position = entity.transition.dest; + entity.transition = null; + } + private updateState(time: number): boolean { var ret = false; - var dir = this.playerEntity.direction; - - if (this.inputHandler.keys[InputHandler.Up]) - dir = Direction.North; - else if (this.inputHandler.keys[InputHandler.Right]) - dir = Direction.East; - else if (this.inputHandler.keys[InputHandler.Down]) - dir = Direction.South; - else if (this.inputHandler.keys[InputHandler.Left]) - dir = Direction.West; - - if (this.playerEntity.direction !== dir) { + + while (true) { + var origTime = time; + + if (this.playerEntity.transition && this.playerEntity.transition.end <= time) { + origTime = this.playerEntity.transition.end; + this.finishTransition(this.playerEntity); + ret = true; + } + + if (this.playerEntity.transition) + return true; + + var dir: Direction = null; + + if (this.inputHandler.keys[InputHandler.Up]) + dir = Direction.North; + else if (this.inputHandler.keys[InputHandler.Right]) + dir = Direction.East; + else if (this.inputHandler.keys[InputHandler.Down]) + dir = Direction.South; + else if (this.inputHandler.keys[InputHandler.Left]) + dir = Direction.West; + + if (dir === null) + return ret; + this.playerEntity.direction = dir; - ret = true; + this.addTransition(this.playerEntity, this.playerEntity.position.translate(dir, 1), + origTime, 250); } - - return ret; } } diff --git a/src/model/EntityPosition.ts b/src/model/EntityPosition.ts index 815eceb..28b3837 100644 --- a/src/model/EntityPosition.ts +++ b/src/model/EntityPosition.ts @@ -1,11 +1,14 @@ 'use strict'; -import Direction from '../model/Direction'; +import Direction from './Direction'; import Entity from './Entity'; import Position from './Position'; +import Transition from './Transition'; export default class EntityPosition { + public transition: Transition = null; + constructor(public entity: Entity, public position: Position, public direction: Direction) {} } diff --git a/src/model/Position.ts b/src/model/Position.ts index 1db37af..1f9b719 100644 --- a/src/model/Position.ts +++ b/src/model/Position.ts @@ -1,9 +1,35 @@ 'use strict'; +import Direction from './Direction'; + + export default class Position { constructor(public x: number, public y: number) {} + translate(dir: Direction, amount: number): Position { + var p = new Position(this.x, this.y); + + switch (dir) { + case Direction.North: + p.y -= amount; + break; + + case Direction.East: + p.x += amount; + break; + + case Direction.South: + p.y += amount; + break; + + case Direction.West: + p.x -= amount; + } + + return p; + } + asString(): string { return `${this.x},${this.y}`; } diff --git a/src/model/Transition.ts b/src/model/Transition.ts new file mode 100644 index 0000000..0a3e69b --- /dev/null +++ b/src/model/Transition.ts @@ -0,0 +1,8 @@ +'use strict'; + + +import Position from './Position'; + +export default class Transition { + constructor(public start: number, public end: number, public orig: Position, public dest: Position) {} +}; diff --git a/src/view/MapView.ts b/src/view/MapView.ts index 1eadebb..032cd1c 100644 --- a/src/view/MapView.ts +++ b/src/view/MapView.ts @@ -92,18 +92,34 @@ export default class MapView { this.ctx.drawImage(tile, x, y); } - private drawEntity(e: EntityPosition) { + private drawEntity(e: EntityPosition, time: number): boolean { var sprite = this.entitySprites[e.entity.name]; if (!sprite) - return; + return false; + + var x: number, y: number; + + if (e.transition) { + var t = e.transition; + var d = (time - t.start) / (t.end-t.start); + + x = (1-d) * t.orig.x + d * t.dest.x; + y = (1-d) * t.orig.y + d * t.dest.y; + } + else { + x = e.position.x; + y = e.position.y; + } this.ctx.drawImage( sprite, e.direction*tileSize, 0, tileSize, tileSize, - e.position.x*tileSize, e.position.y*tileSize, + x*tileSize, y*tileSize, tileSize, tileSize ); + + return !!e.transition; } private draw(time: number) { @@ -131,9 +147,15 @@ export default class MapView { }); }); + var animate = false; + this.getEntities().forEach(e => { - this.drawEntity(e); + if (this.drawEntity(e, time)) + animate = true; }); + + if (animate) + this.redraw(); } redraw() { -- cgit v1.2.3