Add moveAndSlide
This commit is contained in:
+30
-10
@@ -2,7 +2,14 @@ import type { Circle } from "#/engine/Circle.ts";
|
|||||||
import type { Polygon } from "#/engine/Polygon.ts";
|
import type { Polygon } from "#/engine/Polygon.ts";
|
||||||
import { createRect, fillRect, type Rect, strokeRect } from "#/engine/Rect.ts";
|
import { createRect, fillRect, type Rect, strokeRect } from "#/engine/Rect.ts";
|
||||||
import $ from "#/engine/Scene.ts";
|
import $ from "#/engine/Scene.ts";
|
||||||
import { createVector, getDistance, type Vector } from "#/engine/Vector.ts";
|
import {
|
||||||
|
createVector,
|
||||||
|
getDistance,
|
||||||
|
getDotProduct,
|
||||||
|
invScale,
|
||||||
|
setUnitNormal,
|
||||||
|
type Vector,
|
||||||
|
} from "#/engine/Vector.ts";
|
||||||
import { viewport } from "#/engine/Viewport.ts";
|
import { viewport } from "#/engine/Viewport.ts";
|
||||||
|
|
||||||
export enum Shape {
|
export enum Shape {
|
||||||
@@ -41,9 +48,6 @@ export type Collider = {
|
|||||||
export type Collision = {
|
export type Collision = {
|
||||||
cid: string;
|
cid: string;
|
||||||
normal: Vector;
|
normal: Vector;
|
||||||
position: Vector;
|
|
||||||
depth: number;
|
|
||||||
angle: number;
|
|
||||||
time: number;
|
time: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -149,9 +153,15 @@ function collideWithRect(
|
|||||||
other: Collider,
|
other: Collider,
|
||||||
) {
|
) {
|
||||||
collision.cid = cid;
|
collision.cid = cid;
|
||||||
const inflX = other.aabb.position.x - self.aabb.width;
|
const x = self.aabb.position.x - other.aabb.position.x;
|
||||||
const inflY = other.aabb.position.y - self.aabb.height;
|
const y = self.aabb.position.y - other.aabb.position.y;
|
||||||
collision.depth = getDistance(createVector(inflX, inflY), self.aabb.position);
|
if (Math.abs(x) > Math.abs(y)) {
|
||||||
|
collision.normal.y = 0;
|
||||||
|
collision.normal.x = x > 0 ? 1 : -1;
|
||||||
|
} else {
|
||||||
|
collision.normal.x = 0;
|
||||||
|
collision.normal.y = y > 0 ? 1 : -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function collideWithPolygon(
|
function collideWithPolygon(
|
||||||
@@ -209,9 +219,6 @@ function createCollision(): Collision {
|
|||||||
return {
|
return {
|
||||||
cid: "",
|
cid: "",
|
||||||
normal: createVector(),
|
normal: createVector(),
|
||||||
position: createVector(),
|
|
||||||
depth: 0,
|
|
||||||
angle: 0,
|
|
||||||
time: 0,
|
time: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -268,3 +275,16 @@ export function moveAndCollide(
|
|||||||
|
|
||||||
return slice;
|
return slice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function moveAndSlide(
|
||||||
|
id: string,
|
||||||
|
velocity: Vector,
|
||||||
|
delta: number,
|
||||||
|
): void {
|
||||||
|
const collisions = moveAndCollide(id, velocity, delta);
|
||||||
|
for (const collision of collisions) {
|
||||||
|
const dot = getDotProduct(velocity, collision.normal);
|
||||||
|
velocity.x -= collision.normal.x * dot;
|
||||||
|
velocity.y -= collision.normal.y * dot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,10 +14,12 @@ import {
|
|||||||
type Collision,
|
type Collision,
|
||||||
createCollider,
|
createCollider,
|
||||||
moveAndCollide,
|
moveAndCollide,
|
||||||
|
moveAndSlide,
|
||||||
Shape,
|
Shape,
|
||||||
} from "#/engine/system/physics.ts";
|
} from "#/engine/system/physics.ts";
|
||||||
import {
|
import {
|
||||||
createVector,
|
createVector,
|
||||||
|
getDotProduct,
|
||||||
normalize,
|
normalize,
|
||||||
scale,
|
scale,
|
||||||
type Vector,
|
type Vector,
|
||||||
@@ -55,24 +57,17 @@ process((id, delta) => {
|
|||||||
velocity.x += keyboardInput.arrowRight ? 1 : 0;
|
velocity.x += keyboardInput.arrowRight ? 1 : 0;
|
||||||
velocity.y -= keyboardInput.arrowUp ? 1 : 0;
|
velocity.y -= keyboardInput.arrowUp ? 1 : 0;
|
||||||
velocity.y += keyboardInput.arrowDown ? 1 : 0;
|
velocity.y += keyboardInput.arrowDown ? 1 : 0;
|
||||||
|
|
||||||
normalize(velocity);
|
normalize(velocity);
|
||||||
scale(velocity, speed);
|
scale(velocity, speed);
|
||||||
|
moveAndSlide(id, velocity, delta);
|
||||||
|
|
||||||
let cScale = 1;
|
position.x += velocity.x * delta;
|
||||||
const collisions = moveAndCollide(id, velocity, delta);
|
position.y += velocity.y * delta;
|
||||||
for (const collision of collisions) {
|
|
||||||
cScale = Math.min(0, collision.time - 0.001);
|
|
||||||
}
|
|
||||||
|
|
||||||
position.x += velocity.x * delta * cScale;
|
|
||||||
position.y += velocity.y * delta * cScale;
|
|
||||||
|
|
||||||
velocity.x = 0;
|
velocity.x = 0;
|
||||||
velocity.y = 0;
|
velocity.y = 0;
|
||||||
|
|
||||||
fillRect(viewport.ctx, collider.aabb, "orange");
|
fillRect(viewport.ctx, collider.aabb, "orange");
|
||||||
strokeRect(viewport.ctx, collider.aabb, "red");
|
strokeRect(viewport.ctx, collider.aabb, "red");
|
||||||
if (collisions.some((c: Collision) => c.cid.length > 0)) {
|
|
||||||
fillRect(viewport.ctx, collider.aabb, "red");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user