import {Trait} from "../Entity.js"; import Vec2 from "../Vec2.js"; let zeroVector = new Vec2(0, 0); export default class TPhysics extends Trait { constructor(entity) { super(entity, "physics"); this.velocity = new Vec2(); this.gravity = 40; this.groundFriction = 6; this.airFriction = 2; this.timeLastOnGround = 0; this.onGround = false; this.groundBounds = null; this.groundVelocity = null; } collideTop(bounds, velocity) { if (!this.groundBounds || bounds.top < this.groundBounds.top) { this.groundBounds = bounds; this.groundVelocity = velocity; } } collideWall(bounds, velocity) { let side = this.entity.bounds.intersectSide(bounds); if (side === "top") return this.collideTop(bounds, velocity); } collidePlatform(bounds, velocity) { let side = this.entity.bounds.intersectSide(bounds); if (side === "top") return this.collideTop(bounds, velocity); } update(dt) { // Collide if (this.entity.has("collider")) { let collider = this.entity.t.collider; this.groundBounds = null; this.groundVelocity = null; collider.entities.forEach(e => { let vel = zeroVector; if (e.has("physics")) vel = e.t.physics.velocity; if (e.has("wall")) this.collideWall(e.bounds, vel); else if (e.has("platform")) this.collidePlatform(e.bounds, vel); }); collider.structures.forEach((s, i) => { let bounds = collider.structureBounds[i]; if (s.attrs.wall) this.collideWall(bounds, zeroVector); else if (s.attrs.platform) this.collidePlatform(bounds, zeroVector); }); } this.onGround = (this.groundVelocity && this.velocity.y >= this.groundVelocity.y); if (this.onGround) { this.timeLastOnGround = this.entity.time; this.velocity.y = this.groundVelocity.y; } if (!this.onGround) this.velocity.y += this.gravity * dt; // Apply friction var fric = this.onGround ? this.groundFriction : this.airFriction; var xRatio = 1 / (1 + (dt * fric)); this.velocity.x *= xRatio; } postUpdate(dt) { // Move this.entity.bounds.pos.x += this.velocity.x * dt; this.entity.bounds.pos.y += this.velocity.y * dt; if (this.onGround) this.entity.bounds.bottom = this.groundBounds.top; } }