diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2018-11-08 22:03:08 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2018-11-08 22:25:53 +0100 |
commit | 5eae6f29a80cd47e268cb6eaefa96a0ab0a63e54 (patch) | |
tree | 2631f7b3a9d55adc7d07408b30aecb7b714c25be /src/controller/collision.ts | |
parent | 40339947d1a2407a6be95fad58215cdaf7d4c2c9 (diff) | |
download | rpgedit-5eae6f29a80cd47e268cb6eaefa96a0ab0a63e54.tar rpgedit-5eae6f29a80cd47e268cb6eaefa96a0ab0a63e54.zip |
Implement more flexible handling of entities and collidables
Diffstat (limited to 'src/controller/collision.ts')
-rw-r--r-- | src/controller/collision.ts | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/controller/collision.ts b/src/controller/collision.ts new file mode 100644 index 0000000..e1bd9f9 --- /dev/null +++ b/src/controller/collision.ts @@ -0,0 +1,59 @@ +import { Collision } from '../model/data/collision'; + +import { Collidable } from '../math/collision'; +import { LineSegment, Movement } from '../math/line'; +import { Point } from '../math/point'; + +import { vec2 } from 'gl-matrix'; + +export function mkCollision(collision: Collision[]): Collidable[] { + const ret: Collidable[] = []; + + for (const c of collision) { + switch (c.type) { + case 'polygon': + if (!c.vertices.length) + continue; + + let prev = c.vertices[c.vertices.length - 1]; + + for (const v of c.vertices) { + ret.push(LineSegment.fromPoints(vec2.clone(prev), vec2.clone(v))); + prev = v; + } + + for (const v of c.vertices) { + ret.push(new Point(vec2.clone(v))); + prev = v; + } + } + } + + return ret; +} + +export interface CollidableGroup { + getTranslation(): vec2|null; + getCollidables(): Collidable[]; +} + +export function collide(collision: CollidableGroup, out: vec2, move: Movement, radius: number): boolean { + const t = collision.getTranslation(); + if (t) + move = move.translate(vec2.negate(vec2.create(), t)); + + for (const c of collision.getCollidables()) { + if (!c.collide(out, move, radius)) + continue; + + if (vec2.squaredDistance(move.src, out) >= vec2.squaredDistance(move.src, move.dest)) + continue; + + if (t) + vec2.add(out, out, t); + + return true; + } + + return false; +} |