diff --git a/engine/system/physics.ts b/engine/system/physics.ts index 2a45115..51c1d13 100644 --- a/engine/system/physics.ts +++ b/engine/system/physics.ts @@ -2,7 +2,7 @@ import type { Circle } from "#/engine/Circle.ts"; import type { Polygon } from "#/engine/Polygon.ts"; import { createRect, fillRect, type Rect, strokeRect } from "#/engine/Rect.ts"; import $ from "#/engine/Scene.ts"; -import { createVector, type Vector } from "#/engine/Vector.ts"; +import { createVector, getDistance, type Vector } from "#/engine/Vector.ts"; import { viewport } from "#/engine/Viewport.ts"; export enum Shape { @@ -42,8 +42,9 @@ export type Collision = { cid: string; normal: Vector; position: Vector; - depth: 0; - angle: 0; + depth: number; + angle: number; + time: number; }; export function createCollider( @@ -114,13 +115,13 @@ function sweptAABB( const thNear = Math.max(txNear, tyNear); const thFar = Math.min(txFar, tyFar); - // thMax < 0, collision is behind a frame - // thMin > 1, collision is ahead a frame + // thFar < 0, collision is behind a frame + // thNear > 1, collision is ahead a frame if (thFar < 0 || thNear > 1) { return null; } - return thNear; + return thNear; // -Infinity if velocity is 0 } function collideWithCirle( @@ -140,8 +141,10 @@ function collideWithRect( velocity: Vector, other: Collider, ) { - const th = sweptAABB(self, velocity, other); - collision.cid = th !== null ? cid : ""; + collision.cid = cid; + const inflX = other.aabb.position.x - self.aabb.width; + const inflY = other.aabb.position.y - self.aabb.height; + collision.depth = getDistance(createVector(inflX, inflY), self.aabb.position); } function collideWithPolygon( @@ -202,6 +205,7 @@ function createCollision(): Collision { position: createVector(), depth: 0, angle: 0, + time: 0, }; } @@ -228,7 +232,13 @@ export function moveAndCollide( } const other = collider.value; + const tHit = sweptAABB(self, velocity, other); + if (tHit === null) { + continue; + } + const collision = next(self.buffer); + collision.time = tHit; switch (self.shape) { case CIRCLE: { circleCollide[other.shape](collision, cid, self, velocity, other); diff --git a/game/entities/hero/entity.ts b/game/entities/hero/entity.ts index 8c1007c..6b21cfe 100644 --- a/game/entities/hero/entity.ts +++ b/game/entities/hero/entity.ts @@ -1,5 +1,6 @@ import { defineEntity } from "#/engine/Entity.ts"; import { keyboardInput } from "#/engine/Keyboard.ts"; +import { lerp } from "#/engine/lib/lerp"; import { pointer } from "#/engine/Pointer.ts"; import { createRect, fillRect, strokeRect } from "#/engine/Rect.ts"; import $ from "#/engine/Scene.ts"; @@ -36,9 +37,13 @@ const process = defineEntity("hero", { }); process((id, delta) => { - const position = $("position").get(id)!.value; + const positions = $("position"); + const position = positions.get(id)!.value; + + const colliders = $("collider"); + const collider = colliders.get(id)!.value; + const velocity = $("velocity").get(id)!.value; - const collider = $("collider").get(id)!.value; if (pointer.isDown) { position.x = pointer.position.x; @@ -53,11 +58,21 @@ process((id, delta) => { normalize(velocity); scale(velocity, speed); + let cScale = 1; const collisions = moveAndCollide(id, velocity, delta); - // console.log(collisions); + for (const collision of collisions) { + // const _collider = colliders.get(collision.cid)!.value; + // const _position = positions.get(collision.cid)!.value; + const time = collision.time; + if (time === -Infinity) { + break; + } + cScale = Math.min(0, time - 0.001); + console.log(cScale); + } - position.x += velocity.x * delta; - position.y += velocity.y * delta; + position.x += velocity.x * delta * cScale; + position.y += velocity.y * delta * cScale; velocity.x = 0; velocity.y = 0;