Add shared-scene 2D authoring, sprite animation and Rapier2D physics
CI / validate (push) Canceled after 0s
CI / validate (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import { emptyProject, entity, activeScene, type Asset } from "./schema.ts";
|
||||
import { sliceImage } from "./two-d.ts";
|
||||
/** Small original pixel-art sheet for the runnable 2D example; no external assets. */
|
||||
const sheet =
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAGAAAAAQCAYAAADpunr5AAAAw0lEQVR4nGNgGOGgeHPBf0rw0nQHijCGg74d7f+PDxPy0FDTPxoBwyQCLs0KJwmTFAGSaqZgTG4ADGb9MU6O/ynBoxEwyCJgWrQjXkxWBAzmIoRS/aMRMBoBmI733HgVKyYUCENRPywgS4I9UPBoBIxGwNAIQGpFwGgRNBoBhD0Awrg8P1T1D6oIAAF8jicUAENRP7EB7WBoBcf4IoDijpiqVdx/GMYnhg8gq6dELz3sH42AAbafWkUQ1QbjRiOAvhEAAD+44yBoQmIqAAAAAElFTkSuQmCC";
|
||||
export function project2D(example = false) {
|
||||
const p = emptyProject();
|
||||
p.name = example ? "2D Platformer" : "2D Project";
|
||||
const scene = activeScene(p);
|
||||
scene.name = "2D Scene";
|
||||
scene.mode = "2d";
|
||||
p.settings.background = "#233546";
|
||||
p.settings.physics2d = { gravity: [0, -9.81] };
|
||||
if (!example) return p;
|
||||
const a: Asset = {
|
||||
id: "sprites_2d",
|
||||
kind: "image",
|
||||
name: "platformer.png",
|
||||
uri: "data:image/png;base64," + sheet,
|
||||
image: {
|
||||
width: 96,
|
||||
height: 16,
|
||||
pixelsPerUnit: 16,
|
||||
filter: "nearest",
|
||||
frames: sliceImage(96, 16, 16, 16),
|
||||
},
|
||||
};
|
||||
p.assets = [a];
|
||||
const sprite = (frame: number, size = [1, 1]) => ({
|
||||
assetId: a.id,
|
||||
frame,
|
||||
size,
|
||||
});
|
||||
const player = entity(
|
||||
"Player",
|
||||
{
|
||||
sprite: sprite(0, [1, 1.5]),
|
||||
spriteAnimator: {
|
||||
autoplay: "idle",
|
||||
autoStates: true,
|
||||
clips: [
|
||||
{ name: "idle", frames: [0], fps: 4, loop: true },
|
||||
{ name: "run", frames: [1, 2], fps: 10, loop: true },
|
||||
{ name: "jump", frames: [3], fps: 1, loop: true },
|
||||
],
|
||||
},
|
||||
collider2d: { shape: "capsule", radius: 0.3, height: 1.4 },
|
||||
rigidbody2d: { type: "kinematic", lockRotation: true },
|
||||
character2d: {
|
||||
mode: "platformer",
|
||||
controls: true,
|
||||
speed: 5,
|
||||
jumpSpeed: 9,
|
||||
gravity: 20,
|
||||
autostep: 0.15,
|
||||
},
|
||||
},
|
||||
[3, 2, 0],
|
||||
"player_2d",
|
||||
);
|
||||
const ground = entity(
|
||||
"Tilemap",
|
||||
{
|
||||
tilemap: {
|
||||
assetId: a.id,
|
||||
width: 26,
|
||||
height: 10,
|
||||
tileSize: [1, 1],
|
||||
cells: [
|
||||
...Array.from({ length: 26 }, (_, x) => ({ x, y: 0, frame: 4 })),
|
||||
...Array.from({ length: 4 }, (_, x) => ({
|
||||
x: x + 7,
|
||||
y: 2,
|
||||
frame: 4,
|
||||
})),
|
||||
...Array.from({ length: 4 }, (_, x) => ({
|
||||
x: x + 18,
|
||||
y: 3,
|
||||
frame: 4,
|
||||
})),
|
||||
],
|
||||
collisions: true,
|
||||
layer: -1,
|
||||
},
|
||||
},
|
||||
[0, -1, 0],
|
||||
"tilemap_2d",
|
||||
);
|
||||
const platform = entity(
|
||||
"One-way platform",
|
||||
{
|
||||
sprite: { ...sprite(4, [3, 0.3]), color: "#90bdc8" },
|
||||
collider2d: { shape: "box", size: [3, 0.3], oneWay: true },
|
||||
rigidbody2d: { type: "fixed" },
|
||||
},
|
||||
[14, 3, 0],
|
||||
"platform_2d",
|
||||
);
|
||||
const crate = entity(
|
||||
"Dynamic crate",
|
||||
{
|
||||
sprite: sprite(5),
|
||||
collider2d: { shape: "box", size: [1, 1] },
|
||||
rigidbody2d: { type: "dynamic", mass: 1, lockRotation: false },
|
||||
},
|
||||
[5, 4, 0],
|
||||
"crate_2d",
|
||||
);
|
||||
const camera = entity(
|
||||
"Camera 2D",
|
||||
{
|
||||
camera: {
|
||||
mode: "2d",
|
||||
orthoWidth: 22,
|
||||
targetId: player.id,
|
||||
offset: [5, 3, 0],
|
||||
bounds: [11, 4, 15, 4],
|
||||
},
|
||||
},
|
||||
[11, 4, 20],
|
||||
"camera_2d",
|
||||
);
|
||||
const background = entity(
|
||||
"3D object in the same scene",
|
||||
{
|
||||
mesh: { type: "box", size: [2, 2, 2] },
|
||||
material: { color: "#45647c", roughness: 1 },
|
||||
},
|
||||
[20, 5, -4],
|
||||
"background_3d",
|
||||
);
|
||||
background.transform.rotation = [0.3, 0.4, 0.2];
|
||||
scene.entities = [ground, player, platform, crate, camera, background];
|
||||
return p;
|
||||
}
|
||||
Reference in New Issue
Block a user