WIP
This commit is contained in:
@@ -1,43 +0,0 @@
|
|||||||
import { copyVector, type Vector } from "#/engine/Vector.ts";
|
|
||||||
|
|
||||||
export type AABB = {
|
|
||||||
position: Vector;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function createAABB(
|
|
||||||
position: Vector,
|
|
||||||
width: number,
|
|
||||||
height: number,
|
|
||||||
): AABB {
|
|
||||||
return {
|
|
||||||
position,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function fromMinMax(min: Vector, max: Vector): AABB {
|
|
||||||
return {
|
|
||||||
position: copyVector(min),
|
|
||||||
width: max.x - min.x,
|
|
||||||
height: max.y - min.y,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function drawAABB(
|
|
||||||
ctx: CanvasRenderingContext2D,
|
|
||||||
aabb: AABB,
|
|
||||||
color: string = "#fff",
|
|
||||||
): void {
|
|
||||||
ctx.save();
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
ctx.strokeRect(
|
|
||||||
aabb.position.x - 0.5,
|
|
||||||
aabb.position.y - 0.5,
|
|
||||||
aabb.width,
|
|
||||||
aabb.height,
|
|
||||||
);
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
+18
-1
@@ -12,15 +12,32 @@ export function createCircle(position: Vector, radius: number): Circle {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function drawCircle(
|
export function strokeCircle(
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
circle: Circle,
|
circle: Circle,
|
||||||
color: string = "#fff",
|
color: string = "#fff",
|
||||||
|
alpha: number = 1.0,
|
||||||
): void {
|
): void {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.strokeStyle = color;
|
ctx.strokeStyle = color;
|
||||||
|
ctx.globalAlpha = alpha;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(circle.position.x, circle.position.y, circle.radius, 0, 2 * Math.PI);
|
ctx.arc(circle.position.x, circle.position.y, circle.radius, 0, 2 * Math.PI);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function fillCircle(
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
circle: Circle,
|
||||||
|
color: string = "#fff",
|
||||||
|
alpha: number = 1.0,
|
||||||
|
): void {
|
||||||
|
ctx.save();
|
||||||
|
ctx.fillStyle = color;
|
||||||
|
ctx.globalAlpha = alpha;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(circle.position.x, circle.position.y, circle.radius, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import { copyVector, type Vector } from "#/engine/Vector.ts";
|
||||||
|
|
||||||
|
export type Rect = {
|
||||||
|
position: Vector;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createRect(
|
||||||
|
position: Vector,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
): Rect {
|
||||||
|
return {
|
||||||
|
position,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fromMinMax(min: Vector, max: Vector): Rect {
|
||||||
|
return {
|
||||||
|
position: copyVector(min),
|
||||||
|
width: max.x - min.x,
|
||||||
|
height: max.y - min.y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function strokeRect(
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
rect: Rect,
|
||||||
|
color: string = "#fff",
|
||||||
|
alpha: number = 1.0,
|
||||||
|
): void {
|
||||||
|
ctx.save();
|
||||||
|
ctx.strokeStyle = color;
|
||||||
|
ctx.globalAlpha = alpha;
|
||||||
|
ctx.strokeRect(
|
||||||
|
rect.position.x - 0.5,
|
||||||
|
rect.position.y - 0.5,
|
||||||
|
rect.width,
|
||||||
|
rect.height,
|
||||||
|
);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fillRect(
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
rect: Rect,
|
||||||
|
color: string = "#fff",
|
||||||
|
alpha: number = 1.0,
|
||||||
|
): void {
|
||||||
|
ctx.save();
|
||||||
|
ctx.strokeStyle = color;
|
||||||
|
ctx.globalAlpha = alpha;
|
||||||
|
ctx.fillRect(
|
||||||
|
rect.position.x - 0.5,
|
||||||
|
rect.position.y - 0.5,
|
||||||
|
rect.width,
|
||||||
|
rect.height,
|
||||||
|
);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
setScene,
|
setScene,
|
||||||
} from "#/engine/Scene.ts";
|
} from "#/engine/Scene.ts";
|
||||||
import { setScale, viewport } from "#/engine/Viewport.ts";
|
import { setScale, viewport } from "#/engine/Viewport.ts";
|
||||||
|
import { strokeRect } from "../Rect.ts";
|
||||||
import { InputField } from "./controls/InputField.tsx";
|
import { InputField } from "./controls/InputField.tsx";
|
||||||
import { RangeSlider } from "./controls/RangeSlider.tsx";
|
import { RangeSlider } from "./controls/RangeSlider.tsx";
|
||||||
import { GraphBrowser } from "./GraphBrowser.tsx";
|
import { GraphBrowser } from "./GraphBrowser.tsx";
|
||||||
@@ -115,6 +116,7 @@ const DevTools: Component<{ gameContainer: HTMLElement }> = ({
|
|||||||
processProxy(...args);
|
processProxy(...args);
|
||||||
|
|
||||||
ctx.save();
|
ctx.save();
|
||||||
|
ctx.globalAlpha = 0.75;
|
||||||
ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
ctx.strokeStyle = "#6572f5";
|
ctx.strokeStyle = "#6572f5";
|
||||||
viewport.ctx.strokeRect(
|
viewport.ctx.strokeRect(
|
||||||
@@ -131,6 +133,8 @@ const DevTools: Component<{ gameContainer: HTMLElement }> = ({
|
|||||||
2,
|
2,
|
||||||
2,
|
2,
|
||||||
);
|
);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.fill();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
+32
-32
@@ -1,5 +1,5 @@
|
|||||||
import type { AABB } from "#/engine/AABB.ts";
|
|
||||||
import type { Circle } from "#/engine/Circle.ts";
|
import type { Circle } from "#/engine/Circle.ts";
|
||||||
|
import type { Rect } from "#/engine/Rect";
|
||||||
import type { Vector } from "#/engine/Vector.ts";
|
import type { Vector } from "#/engine/Vector.ts";
|
||||||
|
|
||||||
export function isPointInCircle(point: Vector, circle: Circle): boolean {
|
export function isPointInCircle(point: Vector, circle: Circle): boolean {
|
||||||
@@ -9,15 +9,15 @@ export function isPointInCircle(point: Vector, circle: Circle): boolean {
|
|||||||
return dx * dx + dy * dy <= circle.radius ** 2;
|
return dx * dx + dy * dy <= circle.radius ** 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPointInAABB(point: Vector, aabb: AABB): boolean {
|
export function isPointInRect(point: Vector, rect: Rect): boolean {
|
||||||
const rx = aabb.position.x;
|
const rx = rect.position.x;
|
||||||
const ry = aabb.position.y;
|
const ry = rect.position.y;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
point.x >= rx &&
|
point.x >= rx &&
|
||||||
point.x <= rx + aabb.width &&
|
point.x <= rx + rect.width &&
|
||||||
point.y >= ry &&
|
point.y >= ry &&
|
||||||
point.y <= ry + aabb.height
|
point.y <= ry + rect.height
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ export function circleIntersectCircle(a: Circle, b: Circle): boolean {
|
|||||||
return dx * dx + dy * dy <= (a.radius + b.radius) ** 2;
|
return dx * dx + dy * dy <= (a.radius + b.radius) ** 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AABBIntersectAABB(a: AABB, b: AABB): boolean {
|
export function RectIntersectRect(a: Rect, b: Rect): boolean {
|
||||||
const ax = a.position.x;
|
const ax = a.position.x;
|
||||||
const ay = a.position.y;
|
const ay = a.position.y;
|
||||||
const bx = b.position.x;
|
const bx = b.position.x;
|
||||||
@@ -42,14 +42,14 @@ export function AABBIntersectAABB(a: AABB, b: AABB): boolean {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function circleIntersectAABB(circle: Circle, aabb: AABB): boolean {
|
export function circleIntersectRect(circle: Circle, rect: Rect): boolean {
|
||||||
const cx = circle.position.x;
|
const cx = circle.position.x;
|
||||||
const cy = circle.position.y;
|
const cy = circle.position.y;
|
||||||
const rx = aabb.position.x;
|
const rx = rect.position.x;
|
||||||
const ry = aabb.position.y;
|
const ry = rect.position.y;
|
||||||
|
|
||||||
const dx = cx - Math.max(rx, Math.min(cx, rx + aabb.width));
|
const dx = cx - Math.max(rx, Math.min(cx, rx + rect.width));
|
||||||
const dy = cy - Math.max(ry, Math.min(cy, ry + aabb.height));
|
const dy = cy - Math.max(ry, Math.min(cy, ry + rect.height));
|
||||||
|
|
||||||
return dx * dx + dy * dy <= circle.radius ** 2;
|
return dx * dx + dy * dy <= circle.radius ** 2;
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ export function circleContainsCircle(a: Circle, b: Circle): boolean {
|
|||||||
return a.radius >= b.radius + distance;
|
return a.radius >= b.radius + distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AABBContainsAABB(a: AABB, b: AABB): boolean {
|
export function RectContainsRect(a: Rect, b: Rect): boolean {
|
||||||
const ax = a.position.x;
|
const ax = a.position.x;
|
||||||
const ay = a.position.y;
|
const ay = a.position.y;
|
||||||
const bx = b.position.x;
|
const bx = b.position.x;
|
||||||
@@ -76,44 +76,44 @@ export function AABBContainsAABB(a: AABB, b: AABB): boolean {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AABBContainsCircle(aabb: AABB, circle: Circle): boolean {
|
export function RectContainsCircle(rect: Rect, circle: Circle): boolean {
|
||||||
const rx = aabb.position.x;
|
const rx = rect.position.x;
|
||||||
const ry = aabb.position.y;
|
const ry = rect.position.y;
|
||||||
const cx = circle.position.x;
|
const cx = circle.position.x;
|
||||||
const cy = circle.position.y;
|
const cy = circle.position.y;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
rx <= cx - circle.radius &&
|
rx <= cx - circle.radius &&
|
||||||
rx + aabb.width >= cx + circle.radius &&
|
rx + rect.width >= cx + circle.radius &&
|
||||||
ry <= cy - circle.radius &&
|
ry <= cy - circle.radius &&
|
||||||
ry + aabb.height >= cy + circle.radius
|
ry + rect.height >= cy + circle.radius
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function circleContainsAABB(circle: Circle, aabb: AABB): boolean {
|
export function circleContainsRect(circle: Circle, rect: Rect): boolean {
|
||||||
const radiusSquare = circle.radius ** 2;
|
const radSquare = circle.radius ** 2;
|
||||||
|
|
||||||
const dax = aabb.position.x - circle.position.x;
|
const dax = rect.position.x - circle.position.x;
|
||||||
const day = aabb.position.y - circle.position.y;
|
const day = rect.position.y - circle.position.y;
|
||||||
if (dax * dax + day * day > radiusSquare) {
|
if (dax * dax + day * day > radSquare) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dbx = aabb.position.x + aabb.width - circle.position.x;
|
const dbx = rect.position.x + rect.width - circle.position.x;
|
||||||
const dby = aabb.position.y - circle.position.y;
|
const dby = rect.position.y - circle.position.y;
|
||||||
if (dbx * dbx + dby * dby > radiusSquare) {
|
if (dbx * dbx + dby * dby > radSquare) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dcx = aabb.position.x - circle.position.x;
|
const dcx = rect.position.x - circle.position.x;
|
||||||
const dcy = aabb.position.y + aabb.height - circle.position.y;
|
const dcy = rect.position.y + rect.height - circle.position.y;
|
||||||
if (dcx * dcx + dcy * dcy > radiusSquare) {
|
if (dcx * dcx + dcy * dcy > radSquare) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ddx = aabb.position.x + aabb.width - circle.position.x;
|
const ddx = rect.position.x + rect.width - circle.position.x;
|
||||||
const ddy = aabb.position.y + aabb.height - circle.position.y;
|
const ddy = rect.position.y + rect.height - circle.position.y;
|
||||||
if (ddx * ddx + ddy * ddy > radiusSquare) {
|
if (ddx * ddx + ddy * ddy > radSquare) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createAnimation, playAnimation } from "#/engine/Animation.ts";
|
import { createAnimation, playAnimation } from "#/engine/Animation.ts";
|
||||||
import { createCircle, drawCircle } from "#/engine/Circle";
|
import { createCircle } from "#/engine/Circle";
|
||||||
import { moveAndCollide } from "#/engine/Collision.ts";
|
import { moveAndCollide } from "#/engine/Collision.ts";
|
||||||
import { defineEntity } from "#/engine/Entity.ts";
|
import { defineEntity } from "#/engine/Entity.ts";
|
||||||
import { keyboardInput } from "#/engine/Keyboard.ts";
|
import { keyboardInput } from "#/engine/Keyboard.ts";
|
||||||
@@ -28,7 +28,6 @@ animate((entity, ctx, delta) => {
|
|||||||
entity.position.y,
|
entity.position.y,
|
||||||
delta,
|
delta,
|
||||||
);
|
);
|
||||||
drawCircle(ctx, entity.body.shape, "red");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
process((entity, delta) => {
|
process((entity, delta) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { drawCircle } from "#/engine/Circle";
|
import { strokeCircle } from "#/engine/Circle";
|
||||||
import { pointer } from "#/engine/Pointer.ts";
|
import { pointer } from "#/engine/Pointer.ts";
|
||||||
import { defineScene } from "#/engine/Scene.ts";
|
import { defineScene } from "#/engine/Scene.ts";
|
||||||
import data from "./data.json";
|
import data from "./data.json";
|
||||||
@@ -17,7 +17,7 @@ preProcess((entityInstanceMap) => {
|
|||||||
|
|
||||||
process((ctx, delta) => {
|
process((ctx, delta) => {
|
||||||
if (!pointer.isDown) {
|
if (!pointer.isDown) {
|
||||||
drawCircle(ctx, {
|
strokeCircle(ctx, {
|
||||||
position: pointer.position,
|
position: pointer.position,
|
||||||
radius: 4,
|
radius: 4,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user