A hackable template for creating small and fast browser games.
1/**
2 * # RigidBody2D
3 *
4 * The `RigidBody2D` component allows the entity to collide and interact with
5 * other rigid bodies
6 *
7 * The physics simulation is simplified. Among others, it assumes mass = 1,
8 * which means that acceleration and force are numerically equal.
9 */
10
11import {Vec2} from "../../lib/math.js";
12import {clamp} from "../../lib/number.js";
13import {Entity} from "../../lib/world.js";
14import {Game} from "../game.js";
15import {Has} from "../world.js";
16
17export const enum RigidKind {
18 Static,
19 Dynamic,
20}
21
22export interface RigidBody2D {
23 Kind: RigidKind;
24 Drag: number;
25 Bounciness: number;
26 Acceleration: Vec2;
27 VelocityLinear: Vec2;
28 VelocityResolved: Vec2;
29 VelocityAngular: number;
30 IsGrounded: boolean;
31}
32
33/**
34 * Add `RigidBody2D` to an entity.
35 *
36 * @param kind The type of the rigid body (static, dynamic).
37 * @param bounciness Bounciness factor (0 = no bounce, 1 = full bounce).
38 * @param drag Drag factor (0 = no drag, 1 = entity never moves).
39 */
40export function rigid_body2d(kind: RigidKind, bounciness = 1, drag = 0.001) {
41 return (game: Game, entity: Entity) => {
42 game.World.Signature[entity] |= Has.RigidBody2D;
43 game.World.RigidBody2D[entity] = {
44 Kind: kind,
45 Drag: clamp(0, 1, drag),
46 Bounciness: clamp(0, 1, bounciness),
47 Acceleration: [0, 0],
48 VelocityLinear: [0, 0],
49 VelocityResolved: [0, 0],
50 VelocityAngular: 0,
51 IsGrounded: false,
52 };
53 };
54}