planck-js
Version:
2D JavaScript/TypeScript physics engine for cross-platform HTML5 game development
139 lines (111 loc) • 3.97 kB
text/typescript
import type { AABBValue } from "../collision/AABB";
import type { World } from "../dynamics/World";
import type { Joint } from "../dynamics/Joint";
import type { Fixture } from "../dynamics/Fixture";
import type { Body } from "../dynamics/Body";
export interface Style {
stroke?: string;
fill?: string;
lineWidth?: number;
}
type KEY = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
"8" | "9" | "A" | "B" | "C" | "D" | "E" | "F" | "G" |
"H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" |
"Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" |
"Z" | "right" | "left" | "up" | "down" | "fire";
export type ActiveKeys = { [key in KEY]?: boolean };
type TestbedMountOptions = { [key: string]: any };
export abstract class Testbed {
/**
* Mounts testbed. Call start with a world to start simulation and rendering.
*/
static mount(options?: TestbedMountOptions): Testbed {
throw new Error("Not implemented");
}
/**
* Mounts testbed if needed, then starts simulation and rendering.
*
* If you need to customize testbed before starting, first run `const testbed = Testbed.mount()` and then `testbed.start()`.
*/
static start(world: World): Testbed {
const testbed = Testbed.mount();
testbed.start(world);
return testbed;
}
/** World viewbox width. */
width: number = 80;
/** World viewbox height. */
height: number = 60;
/** World viewbox center vertical offset. */
x: number = 0;
/** World viewbox center horizontal offset. */
y: number = -10;
/** @hidden */
scaleY: number = -1;
/** World simulation step frequency */
hz: number = 60;
/** World simulation speed, default is 1 */
speed: number = 1;
background: string = "#222222";
mouseForce?: number;
activeKeys: ActiveKeys = {};
/** callback, to be implemented by user */
step = (dt: number, t: number): void => {
return;
};
/** callback, to be implemented by user */
keydown = (keyCode: number, label: string): void => {
return;
};
/** callback, to be implemented by user */
keyup = (keyCode: number, label: string): void => {
return;
};
abstract status(name: string, value: any): void;
abstract status(value: object | string): void;
abstract info(text: string): void;
color(r: number, g: number, b: number): string {
r = r * 256 | 0;
g = g * 256 | 0;
b = b * 256 | 0;
return "rgb(" + r + ", " + g + ", " + b + ")";
}
abstract drawPoint(p: {x: number, y: number}, r: any, color: string): void;
abstract drawCircle(p: {x: number, y: number}, r: number, color: string): void;
abstract drawEdge(a: {x: number, y: number}, b: {x: number, y: number}, color: string): void;
abstract drawSegment(a: {x: number, y: number}, b: {x: number, y: number}, color: string): void;
abstract drawPolygon(points: Array<{x: number, y: number}>, color: string): void;
abstract drawAABB(aabb: AABBValue, color: string): void;
abstract start(world: World): void;
abstract findOne(query: string): (Body | Joint | Fixture | null);
abstract findAll(query: string): (Body | Joint | Fixture)[];
}
type TestbedFactoryOptions = string | TestbedMountOptions;
/** @deprecated */
type TestbedCallback = (testbed: Testbed) => (World | undefined);
/** @deprecated */
export function testbed(callback: TestbedCallback): void;
/** @deprecated */
export function testbed(options: TestbedFactoryOptions, callback: TestbedCallback): void;
/** @internal */
export function testbed(a?: any, b?: any) {
let callback: TestbedCallback | undefined;
let options;
if (typeof a === "function") {
callback = a;
options = b;
} else if (typeof b === "function") {
callback = b;
options = a;
} else {
options = a ?? b;
}
const testbed = Testbed.mount(options);
if (callback) {
// this is for backwards compatibility
const world = callback(testbed) || (testbed as any).world;
testbed.start(world);
} else {
return testbed;
}
}