MCPcopy Create free account
hub / github.com/melonjs/melonJS / createGame

Function createGame

packages/examples/src/examples/camera3d/ExampleCamera3d.tsx:37–223  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

35import { createExampleComponent } from "../utils";
36
37const createGame = () => {
38 // Stash teardown work assembled inside the loader callback so the
39 // outer `createGame` can return a single cleanup function from the
40 // async preload completion.
41 let pointerCleanup: (() => void) | null = null;
42 let domCleanup: (() => void) | null = null;
43 // NOTE: an `unmounted` guard around the preload callback would in
44 // principle fix the "user navigates away before preload finishes"
45 // race that Copilot flagged on review. It can't be added cleanly
46 // today — `examples/utils.tsx` runs `currentTeardown()` on every
47 // React useEffect cleanup (including StrictMode's dev double-mount
48 // cycle), but the same-example remount branch only reattaches the
49 // canvas without re-invoking `createGameFn`. An `unmounted` flag
50 // flipped in teardown therefore stays `true` across the StrictMode
51 // remount, the preload callback bails for the rest of the session,
52 // and the example never renders. Picks up cleanly once the
53 // utils.tsx remount path is fixed (separate review thread).
54
55 // opt in to Camera3d at the Application level — every stage in this
56 // app gets a Camera3d as its default camera (the loader screen pins
57 // to Camera2d via its own constructor regardless).
58 const app = new Application(1024, 768, {
59 parent: "screen",
60 renderer: video.WEBGL,
61 scale: "auto",
62 cameraClass: Camera3dClass,
63 });
64
65 app.world.backgroundColor.parseCSS("#0a0a14");
66 plugin.register(DebugPanelPlugin, "debugPanel");
67
68 loader.preload([{ name: "monster", type: "image", src: monsterImg }], () => {
69 // loader.preload internally transitions to state.LOADING (the
70 // DefaultLoadingScreen). Transition back to the default game
71 // stage so its Camera3d becomes the active viewport.
72 state.change(state.DEFAULT, true);
73
74 // three monsters along the camera's forward axis at increasing
75 // depth. Same x, same y — only z differs. Perspective scales
76 // each one inversely to z.
77 const depths = [200, 400, 600];
78 for (const z of depths) {
79 const sprite = new Sprite(0, 0, { image: "monster" });
80 sprite.scale(0.5);
81 app.world.addChild(sprite);
82 // set depth AFTER addChild — Container.autoDepth (default
83 // true) would otherwise overwrite our intended z
84 sprite.depth = z;
85 }
86
87 // the app's default camera is now a Camera3d (via cameraClass).
88 const camera = app.viewport as Camera3d;
89
90 // orbit state: yaw / pitch / distance. Driven by drag + buttons.
91 let yaw = 0;
92 let pitch = 0;
93 let distance = 700;
94

Callers

nothing calls this directly

Calls 8

updateCameraPosFunction · 0.85
mkButtonFunction · 0.85
parseCSSMethod · 0.80
registerMethod · 0.80
addChildMethod · 0.80
getCanvasMethod · 0.80
removeMethod · 0.65
scaleMethod · 0.45

Tested by

no test coverage detected