create-bloop 0.0.15 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-bloop",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "Create a new Bloop game",
5
5
  "type": "module",
6
6
  "bin": "./dist/index.js",
@@ -13,8 +13,8 @@
13
13
  "vite": "^7.2.2"
14
14
  },
15
15
  "dependencies": {
16
- "@bloopjs/bloop": "^0.0.87",
16
+ "@bloopjs/bloop": "^0.0.89",
17
17
  "@bloopjs/toodle": "^0.1.3",
18
- "@bloopjs/web": "^0.0.87"
18
+ "@bloopjs/web": "^0.0.89"
19
19
  }
20
20
  }
@@ -15,8 +15,8 @@
15
15
  "vite": "^7.2.2"
16
16
  },
17
17
  "dependencies": {
18
- "@bloopjs/bloop": "^0.0.87",
18
+ "@bloopjs/bloop": "^0.0.89",
19
19
  "@bloopjs/toodle": "^0.1.3",
20
- "@bloopjs/web": "^0.0.87"
20
+ "@bloopjs/web": "^0.0.89"
21
21
  }
22
22
  }
@@ -0,0 +1,26 @@
1
+ { "frames": {
2
+ "Ground.aseprite": {
3
+ "frame": { "x": 0, "y": 0, "w": 16, "h": 16 },
4
+ "rotated": false,
5
+ "trimmed": false,
6
+ "spriteSourceSize": { "x": 0, "y": 0, "w": 16, "h": 16 },
7
+ "sourceSize": { "w": 16, "h": 16 },
8
+ "duration": 100
9
+ }
10
+ },
11
+ "meta": {
12
+ "app": "https://www.aseprite.org/",
13
+ "version": "1.3.8.1-arm64",
14
+ "image": "Ground.png",
15
+ "format": "I8",
16
+ "size": { "w": 16, "h": 16 },
17
+ "scale": "1",
18
+ "frameTags": [
19
+ ],
20
+ "layers": [
21
+ { "name": "Layer 1", "opacity": 255, "blendMode": "normal" }
22
+ ],
23
+ "slices": [
24
+ ]
25
+ }
26
+ }
@@ -79,9 +79,8 @@ export function createDrawState(toodle: Toodle): DrawState {
79
79
  );
80
80
 
81
81
  const block = gameScreen.add(
82
- toodle.shapes.Rect({
82
+ toodle.Quad("brick", {
83
83
  size: { width: BLOCK_SIZE, height: BLOCK_SIZE },
84
- color: BLOCK_COLOR,
85
84
  }),
86
85
  );
87
86
 
@@ -5,6 +5,7 @@ import { FLIPBOOKS } from "./sprites";
5
5
  import { AnimationSystem } from "./systems/animation";
6
6
  import { CollisionSystem } from "./systems/collision";
7
7
  import { InputsSystem } from "./systems/inputs";
8
+ import { MatchmakingSystem } from "./systems/matchmaking";
8
9
  import { PhaseSystem } from "./systems/phase";
9
10
  import { PhysicsSystem } from "./systems/physics";
10
11
 
@@ -113,12 +114,10 @@ game.system(
113
114
  }),
114
115
  );
115
116
 
117
+ game.system("matchmaking", MatchmakingSystem);
116
118
  game.system("inputs", InputsSystem);
117
-
118
119
  game.system("physics", PhysicsSystem);
119
-
120
120
  game.system("collision", CollisionSystem);
121
-
122
121
  game.system("animation", AnimationSystem);
123
122
 
124
123
  // Debug hitbox toggle (H key)
@@ -1,12 +1,13 @@
1
1
  import "./style.css";
2
2
  import { Toodle } from "@bloopjs/toodle";
3
- import { joinRollbackRoom, start } from "@bloopjs/web";
3
+ import { start } from "@bloopjs/web";
4
4
  import { createChromaticAberrationEffect } from "./chromatic-aberration";
5
5
  import { createDrawState, draw as drawFn } from "./draw";
6
6
  import { game } from "./game";
7
7
 
8
8
  let draw = drawFn;
9
9
 
10
+ // boot up the game
10
11
  const app = await start({
11
12
  game,
12
13
  startRecording: false,
@@ -15,6 +16,17 @@ const app = await start({
15
16
  },
16
17
  });
17
18
 
19
+ // HMR support
20
+ if (import.meta.hot) {
21
+ import.meta.hot.accept("./game", async (newModule) => {
22
+ await app.acceptHmr(newModule?.game);
23
+ });
24
+
25
+ import.meta.hot.accept("./draw", async (newModule) => {
26
+ draw = newModule?.draw;
27
+ });
28
+ }
29
+
18
30
  const canvas = app.canvas;
19
31
  if (!canvas) throw new Error("No canvas element found");
20
32
 
@@ -38,6 +50,8 @@ await toodle.assets.registerBundle("main", {
38
50
  marioWalk: spriteUrl("MarioWalk"),
39
51
  marioJump: spriteUrl("MarioJump"),
40
52
  marioSkid: spriteUrl("MarioSkid"),
53
+ brick: spriteUrl("Brick"),
54
+ ground: spriteUrl("Ground"),
41
55
  },
42
56
  autoLoad: true,
43
57
  });
@@ -54,7 +68,20 @@ requestAnimationFrame(function frame() {
54
68
  requestAnimationFrame(frame);
55
69
  });
56
70
 
57
- let networkJoined = false;
71
+ game.system("recording-watcher", {
72
+ netcode({ event, time }) {
73
+ console.log("[netcode]", event.type, event);
74
+ if (event.type === "session:start") {
75
+ console.log(
76
+ "[netcode]",
77
+ "session started, recording at frame",
78
+ time.frame,
79
+ );
80
+
81
+ app.sim.record(100_000);
82
+ }
83
+ },
84
+ });
58
85
 
59
86
  // Debug: Press R to start recording mid-game
60
87
  window.addEventListener("keydown", (e) => {
@@ -75,43 +102,3 @@ if (toodle.backend.type === "webgpu") {
75
102
  }
76
103
  });
77
104
  }
78
-
79
- game.system("title-input", {
80
- update({ bag, inputs }) {
81
- if (bag.phase !== "title") return;
82
-
83
- if ((inputs.keys.enter.down || inputs.mouse.left.down) && !networkJoined) {
84
- // Online multiplayer - wait for connection
85
- bag.mode = "online";
86
- bag.phase = "waiting";
87
- networkJoined = true;
88
-
89
- // Phase transitions are handled by the session-watcher system
90
- joinRollbackRoom("mario-demo", app, {
91
- onSessionStart() {
92
- bag.phase = "playing";
93
-
94
- app.sim.record(100_000);
95
- console.log(
96
- "Network session started, recording at frame",
97
- app.sim.time.frame,
98
- );
99
- },
100
- onSessionEnd() {
101
- networkJoined = false;
102
- },
103
- });
104
- }
105
- },
106
- });
107
-
108
- // HMR support
109
- if (import.meta.hot) {
110
- import.meta.hot.accept("./game", async (newModule) => {
111
- await app.acceptHmr(newModule?.game);
112
- });
113
-
114
- import.meta.hot.accept("./draw", async (newModule) => {
115
- draw = newModule?.draw;
116
- });
117
- }
@@ -1,4 +1,6 @@
1
1
  // TODO: allow loading animated sprite JSON from async boot
2
+ import brickJson from "../public/sprites/Brick.json";
3
+ import groundJson from "../public/sprites/Ground.json";
2
4
  import marioIdleJson from "../public/sprites/MarioIdle.json";
3
5
  import marioJumpJson from "../public/sprites/MarioJump.json";
4
6
  import marioSkidJson from "../public/sprites/MarioSkid.json";
@@ -11,4 +13,7 @@ export const FLIPBOOKS = {
11
13
  run: AsepriteFlipbook(marioWalkJson),
12
14
  jump: AsepriteFlipbook(marioJumpJson),
13
15
  skid: AsepriteFlipbook(marioSkidJson),
16
+
17
+ brick: AsepriteFlipbook(brickJson),
18
+ ground: AsepriteFlipbook(groundJson),
14
19
  };
@@ -0,0 +1,24 @@
1
+ import { PhaseSystem } from "./phase";
2
+
3
+ export const MatchmakingSystem = PhaseSystem("title", {
4
+ update({ bag, inputs, net }) {
5
+ if (net.isInSession) return;
6
+ if (inputs.keys.enter.down || inputs.mouse.left.down) {
7
+ bag.mode = "online";
8
+ bag.phase = "waiting";
9
+ net.wantsRoomCode = "mario-demo";
10
+ console.log("[netcode] setting wantsRoomCode");
11
+ }
12
+ },
13
+
14
+ netcode({ event, bag }) {
15
+ switch (event.type) {
16
+ case "session:start":
17
+ bag.phase = "playing";
18
+ break;
19
+ case "session:end":
20
+ bag.phase = "title";
21
+ break;
22
+ }
23
+ },
24
+ });
@@ -75,6 +75,8 @@ async function loadTape(bytes: Uint8Array, fileName: string) {
75
75
  marioWalk: spriteUrl("MarioWalk"),
76
76
  marioJump: spriteUrl("MarioJump"),
77
77
  marioSkid: spriteUrl("MarioSkid"),
78
+ brick: spriteUrl("Brick"),
79
+ ground: spriteUrl("Ground"),
78
80
  },
79
81
  autoLoad: true,
80
82
  });