nova64 0.2.4 → 0.2.6
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/README.md +25 -8
- package/bin/nova64.js +165 -0
- package/dist/assets/console-CY_kygm3.js +14 -0
- package/dist/assets/console-CY_kygm3.js.map +1 -0
- package/dist/assets/main-l0sNRNKZ.js.map +1 -0
- package/dist/assets/sky/studio/nx.png +0 -0
- package/dist/assets/sky/studio/ny.png +0 -0
- package/dist/assets/sky/studio/nz.png +0 -0
- package/dist/assets/sky/studio/px.png +0 -0
- package/dist/assets/sky/studio/py.png +0 -0
- package/dist/assets/sky/studio/pz.png +0 -0
- package/dist/assets/vanilla-Dcuy32gi.js +2 -0
- package/dist/assets/vanilla-Dcuy32gi.js.map +1 -0
- package/dist/console.html +899 -0
- package/dist/docs/BENCHMARK.md +77 -0
- package/dist/docs/CHEATSHEET.md +255 -0
- package/dist/docs/EFFECTS_API_GUIDE.md +577 -0
- package/dist/docs/EFFECTS_QUICK_REFERENCE.md +331 -0
- package/dist/docs/FONT_CHARACTER_REFERENCE.md +219 -0
- package/dist/docs/FREE_GLB_ASSETS.md +330 -0
- package/dist/docs/FULLSCREEN_BUTTON_FEATURE.md +296 -0
- package/dist/docs/GAMEPAD_SUPPORT.md +348 -0
- package/dist/docs/GAME_IMPROVEMENTS.md +278 -0
- package/dist/docs/GAME_QUALITY_STATUS.md +300 -0
- package/dist/docs/MIGRATION_GUIDE.md +553 -0
- package/dist/docs/NOVA64_3D_API.md +356 -0
- package/dist/docs/NOVA64_API_REFERENCE.md +1406 -0
- package/dist/docs/NOVA64_UI_API.md +503 -0
- package/dist/docs/UI_SYSTEM_SUMMARY.md +445 -0
- package/dist/docs/VOXEL_ENGINE_GUIDE.md +662 -0
- package/dist/docs/VOXEL_QUICK_REFERENCE.md +386 -0
- package/dist/docs/api-3d.html +750 -0
- package/dist/docs/api-effects.html +385 -0
- package/dist/docs/api-improvements.md +121 -0
- package/dist/docs/api-skybox.html +407 -0
- package/dist/docs/api-sprites.html +321 -0
- package/dist/docs/api-voxel.html +337 -0
- package/dist/docs/api.html +543 -0
- package/dist/docs/assets.html +306 -0
- package/dist/docs/audio.html +340 -0
- package/dist/docs/blogs.html +286 -0
- package/dist/docs/collision.html +316 -0
- package/dist/docs/console.html +247 -0
- package/dist/docs/editor.html +297 -0
- package/dist/docs/font.html +247 -0
- package/dist/docs/framebuffer.html +247 -0
- package/dist/docs/fullscreen-button.html +297 -0
- package/dist/docs/gpu-systems.html +247 -0
- package/dist/docs/index.html +580 -0
- package/dist/docs/input.html +491 -0
- package/dist/docs/physics.html +311 -0
- package/dist/docs/screens.html +311 -0
- package/dist/docs/storage.html +311 -0
- package/dist/docs/textinput.html +332 -0
- package/dist/docs/ui.html +488 -0
- package/dist/examples/3d-advanced/code.js +695 -0
- package/dist/examples/adventure-comic-3d/code.js +342 -0
- package/dist/examples/audio-lab/code.js +150 -0
- package/dist/examples/boids-flocking/code.js +270 -0
- package/dist/examples/crystal-cathedral-3d/code.js +706 -0
- package/dist/examples/cyberpunk-city-3d/code.js +1383 -0
- package/dist/examples/demoscene/README.md +192 -0
- package/dist/examples/demoscene/code.js +1081 -0
- package/dist/examples/demoscene/meta.json +21 -0
- package/dist/examples/dungeon-crawler-3d/code.js +1117 -0
- package/dist/examples/f-zero-nova-3d/code.js +865 -0
- package/dist/examples/f-zero-nova-3d/code_old.js +1555 -0
- package/dist/examples/fps-demo-3d/code.js +744 -0
- package/dist/examples/game-of-life-3d/code.js +338 -0
- package/dist/examples/generative-art/code.js +632 -0
- package/dist/examples/hello-3d/code.js +325 -0
- package/dist/examples/hello-skybox/code.js +183 -0
- package/dist/examples/hello-world/code.js +19 -0
- package/dist/examples/input-showcase/code.js +109 -0
- package/dist/examples/instancing-demo/code.js +315 -0
- package/dist/examples/minecraft-demo/code.js +387 -0
- package/dist/examples/model-viewer-3d/code.js +114 -0
- package/dist/examples/mystical-realm-3d/code.js +1203 -0
- package/dist/examples/nature-explorer-3d/code.js +1318 -0
- package/dist/examples/particles-demo/code.js +522 -0
- package/dist/examples/pbr-showcase/code.js +140 -0
- package/dist/examples/physics-demo-3d/code.js +948 -0
- package/dist/examples/screen-demo/code.js +267 -0
- package/dist/examples/shooter-demo-3d/code.js +1286 -0
- package/dist/examples/space-combat-3d/IMPLEMENTATION_SUMMARY.md +109 -0
- package/dist/examples/space-combat-3d/README.md +135 -0
- package/dist/examples/space-combat-3d/code.js +1332 -0
- package/dist/examples/space-harrier-3d/code.js +923 -0
- package/dist/examples/star-fox-nova-3d/code.js +1116 -0
- package/dist/examples/star-fox-nova-3d/code_backup.js +410 -0
- package/dist/examples/star-fox-nova-3d/code_broken.js +1821 -0
- package/dist/examples/storage-quest/code.js +209 -0
- package/dist/examples/strider-demo-3d/IMPROVEMENT_OPTIONS.md +285 -0
- package/dist/examples/strider-demo-3d/cache-test.html +132 -0
- package/dist/examples/strider-demo-3d/code-fixed.js +582 -0
- package/dist/examples/strider-demo-3d/code-old.js +1537 -0
- package/dist/examples/strider-demo-3d/code.js +1462 -0
- package/dist/examples/strider-demo-3d/code.js.bak2 +1169 -0
- package/dist/examples/strider-demo-3d/fix-game.sh +53 -0
- package/dist/examples/super-plumber-64/README.md +128 -0
- package/dist/examples/super-plumber-64/code.js +1185 -0
- package/dist/examples/super-plumber-64/index.html +88 -0
- package/dist/examples/test-2d-overlay/code.js +32 -0
- package/dist/examples/test-font/code.js +51 -0
- package/dist/examples/test-minimal/code.js +21 -0
- package/dist/examples/ui-demo/code.js +306 -0
- package/dist/examples/wing-commander-space/README.md +180 -0
- package/dist/examples/wing-commander-space/code.js +1285 -0
- package/dist/examples/wizardry-3d/CHANGELOG.md +366 -0
- package/dist/examples/wizardry-3d/code.js +3928 -0
- package/dist/index.html +666 -0
- package/dist/os9-shell/assets/index-DIHfrTaW.css +1 -0
- package/dist/os9-shell/assets/index-KchE_ngx.js +483 -0
- package/dist/os9-shell/assets/index-KchE_ngx.js.map +1 -0
- package/dist/os9-shell/index.html +23 -0
- package/dist/os9-shell/nova-icon.svg +12 -0
- package/index.html +6 -1
- package/package.json +37 -32
- package/public/assets/sky/studio/nx.png +0 -0
- package/public/assets/sky/studio/ny.png +0 -0
- package/public/assets/sky/studio/nz.png +0 -0
- package/public/assets/sky/studio/px.png +0 -0
- package/public/assets/sky/studio/py.png +0 -0
- package/public/assets/sky/studio/pz.png +0 -0
- package/public/os9-shell/assets/index-KchE_ngx.js +483 -0
- package/public/os9-shell/assets/index-KchE_ngx.js.map +1 -0
- package/public/os9-shell/index.html +10 -1
- package/runtime/api-2d.js +301 -21
- package/runtime/api-3d/pbr.js +45 -1
- package/runtime/api-3d.js +1 -0
- package/runtime/api-effects.js +90 -3
- package/runtime/api-gameutils.js +476 -0
- package/runtime/api-generative.js +610 -0
- package/runtime/api-skybox.js +54 -0
- package/runtime/api-voxel.js +139 -28
- package/runtime/gpu-threejs.js +13 -9
- package/runtime/ui.js +2 -2
- package/src/main.js +24 -1
- package/public/os9-shell/assets/index-B1Uvacma.js +0 -32825
- package/public/os9-shell/assets/index-B1Uvacma.js.map +0 -1
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// BOIDS FLOCKING SIMULATION — Mesmerizing Emergent Behavior
|
|
2
|
+
// Uses the Nova64 generative art API for noise and HSB colors
|
|
3
|
+
// Watch hundreds of autonomous agents self-organize into beautiful flocks
|
|
4
|
+
|
|
5
|
+
const NUM_BOIDS = 350;
|
|
6
|
+
const SEPARATION_RADIUS = 12;
|
|
7
|
+
const ALIGNMENT_RADIUS = 25;
|
|
8
|
+
const COHESION_RADIUS = 35;
|
|
9
|
+
const MAX_SPEED = 3.2;
|
|
10
|
+
const MAX_FORCE = 0.12;
|
|
11
|
+
const TRAIL_LENGTH = 8;
|
|
12
|
+
const W = 640,
|
|
13
|
+
H = 360;
|
|
14
|
+
|
|
15
|
+
let boids = [];
|
|
16
|
+
let predator = null;
|
|
17
|
+
let mode = 0; // 0=flock, 1=predator, 2=vortex, 3=fireworks
|
|
18
|
+
const MODES = ['FLOCKING', 'PREDATOR CHASE', 'COSMIC VORTEX', 'FIREWORKS'];
|
|
19
|
+
let modeTimer = 0;
|
|
20
|
+
let autoSwitch = true;
|
|
21
|
+
let time = 0;
|
|
22
|
+
let backgroundColor = 0;
|
|
23
|
+
|
|
24
|
+
class Boid {
|
|
25
|
+
constructor(x, y) {
|
|
26
|
+
this.x = x;
|
|
27
|
+
this.y = y;
|
|
28
|
+
const angle = Math.random() * Math.PI * 2;
|
|
29
|
+
this.vx = Math.cos(angle) * MAX_SPEED * 0.5;
|
|
30
|
+
this.vy = Math.sin(angle) * MAX_SPEED * 0.5;
|
|
31
|
+
this.hue = Math.random() * 360;
|
|
32
|
+
this.trail = [];
|
|
33
|
+
this.size = 2 + Math.random() * 1.5;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
update(flock) {
|
|
37
|
+
// Reynolds flocking rules
|
|
38
|
+
let sepX = 0,
|
|
39
|
+
sepY = 0,
|
|
40
|
+
sepCount = 0;
|
|
41
|
+
let aliVx = 0,
|
|
42
|
+
aliVy = 0,
|
|
43
|
+
aliCount = 0;
|
|
44
|
+
let cohX = 0,
|
|
45
|
+
cohY = 0,
|
|
46
|
+
cohCount = 0;
|
|
47
|
+
|
|
48
|
+
for (const other of flock) {
|
|
49
|
+
if (other === this) continue;
|
|
50
|
+
const dx = other.x - this.x;
|
|
51
|
+
const dy = other.y - this.y;
|
|
52
|
+
const d = Math.sqrt(dx * dx + dy * dy);
|
|
53
|
+
|
|
54
|
+
if (d < SEPARATION_RADIUS && d > 0) {
|
|
55
|
+
sepX -= dx / d;
|
|
56
|
+
sepY -= dy / d;
|
|
57
|
+
sepCount++;
|
|
58
|
+
}
|
|
59
|
+
if (d < ALIGNMENT_RADIUS) {
|
|
60
|
+
aliVx += other.vx;
|
|
61
|
+
aliVy += other.vy;
|
|
62
|
+
aliCount++;
|
|
63
|
+
}
|
|
64
|
+
if (d < COHESION_RADIUS) {
|
|
65
|
+
cohX += other.x;
|
|
66
|
+
cohY += other.y;
|
|
67
|
+
cohCount++;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let fx = 0,
|
|
72
|
+
fy = 0;
|
|
73
|
+
|
|
74
|
+
// Separation
|
|
75
|
+
if (sepCount > 0) {
|
|
76
|
+
sepX /= sepCount;
|
|
77
|
+
sepY /= sepCount;
|
|
78
|
+
fx += sepX * 1.8;
|
|
79
|
+
fy += sepY * 1.8;
|
|
80
|
+
}
|
|
81
|
+
// Alignment
|
|
82
|
+
if (aliCount > 0) {
|
|
83
|
+
aliVx /= aliCount;
|
|
84
|
+
aliVy /= aliCount;
|
|
85
|
+
fx += (aliVx - this.vx) * 0.08;
|
|
86
|
+
fy += (aliVy - this.vy) * 0.08;
|
|
87
|
+
}
|
|
88
|
+
// Cohesion
|
|
89
|
+
if (cohCount > 0) {
|
|
90
|
+
cohX /= cohCount;
|
|
91
|
+
cohY /= cohCount;
|
|
92
|
+
fx += (cohX - this.x) * 0.003;
|
|
93
|
+
fy += (cohY - this.y) * 0.003;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Mode-specific forces
|
|
97
|
+
if (mode === 1 && predator) {
|
|
98
|
+
// Flee from predator
|
|
99
|
+
const dx = this.x - predator.x;
|
|
100
|
+
const dy = this.y - predator.y;
|
|
101
|
+
const d = Math.sqrt(dx * dx + dy * dy);
|
|
102
|
+
if (d < 80 && d > 0) {
|
|
103
|
+
const flee = (80 - d) / 80;
|
|
104
|
+
fx += (dx / d) * flee * 0.5;
|
|
105
|
+
fy += (dy / d) * flee * 0.5;
|
|
106
|
+
}
|
|
107
|
+
} else if (mode === 2) {
|
|
108
|
+
// Vortex — spiral toward center with noise
|
|
109
|
+
const cx = W / 2,
|
|
110
|
+
cy = H / 2;
|
|
111
|
+
const dx = cx - this.x,
|
|
112
|
+
dy = cy - this.y;
|
|
113
|
+
const d = Math.sqrt(dx * dx + dy * dy);
|
|
114
|
+
const n = noise(this.x * 0.005, this.y * 0.005, time * 0.3);
|
|
115
|
+
const angle = Math.atan2(dy, dx) + Math.PI * 0.4 + n * 2;
|
|
116
|
+
fx += Math.cos(angle) * 0.15;
|
|
117
|
+
fy += Math.sin(angle) * 0.15;
|
|
118
|
+
if (d > 150) {
|
|
119
|
+
fx += dx * 0.001;
|
|
120
|
+
fy += dy * 0.001;
|
|
121
|
+
}
|
|
122
|
+
} else if (mode === 3) {
|
|
123
|
+
// Fireworks — noise bursts from center
|
|
124
|
+
const n = noise(this.x * 0.01 + time, this.y * 0.01, time * 0.5);
|
|
125
|
+
fx += Math.cos(n * TWO_PI * 2) * 0.2;
|
|
126
|
+
fy += Math.sin(n * TWO_PI * 2) * 0.2;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Clamp force
|
|
130
|
+
const fm = Math.sqrt(fx * fx + fy * fy);
|
|
131
|
+
if (fm > MAX_FORCE) {
|
|
132
|
+
fx = (fx / fm) * MAX_FORCE;
|
|
133
|
+
fy = (fy / fm) * MAX_FORCE;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
this.vx += fx;
|
|
137
|
+
this.vy += fy;
|
|
138
|
+
|
|
139
|
+
// Clamp speed
|
|
140
|
+
const speed = Math.sqrt(this.vx * this.vx + this.vy * this.vy);
|
|
141
|
+
if (speed > MAX_SPEED) {
|
|
142
|
+
this.vx = (this.vx / speed) * MAX_SPEED;
|
|
143
|
+
this.vy = (this.vy / speed) * MAX_SPEED;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this.x += this.vx;
|
|
147
|
+
this.y += this.vy;
|
|
148
|
+
|
|
149
|
+
// Wrap edges
|
|
150
|
+
if (this.x < -10) this.x += W + 20;
|
|
151
|
+
if (this.x > W + 10) this.x -= W + 20;
|
|
152
|
+
if (this.y < -10) this.y += H + 20;
|
|
153
|
+
if (this.y > H + 10) this.y -= H + 20;
|
|
154
|
+
|
|
155
|
+
// Trail
|
|
156
|
+
this.trail.push({ x: this.x, y: this.y });
|
|
157
|
+
if (this.trail.length > TRAIL_LENGTH) this.trail.shift();
|
|
158
|
+
|
|
159
|
+
// Color drift
|
|
160
|
+
this.hue = (this.hue + speed * 0.3) % 360;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function init() {
|
|
165
|
+
noiseSeed(42);
|
|
166
|
+
boids = [];
|
|
167
|
+
for (let i = 0; i < NUM_BOIDS; i++) {
|
|
168
|
+
boids.push(new Boid(Math.random() * W, Math.random() * H));
|
|
169
|
+
}
|
|
170
|
+
predator = { x: W / 2, y: H / 2, vx: 0, vy: 0 };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function update(dt) {
|
|
174
|
+
time += dt;
|
|
175
|
+
modeTimer += dt;
|
|
176
|
+
|
|
177
|
+
// Auto-switch modes every 12 seconds
|
|
178
|
+
if (autoSwitch && modeTimer > 12) {
|
|
179
|
+
mode = (mode + 1) % MODES.length;
|
|
180
|
+
modeTimer = 0;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Manual mode switch
|
|
184
|
+
if (keyp('ArrowRight')) {
|
|
185
|
+
mode = (mode + 1) % MODES.length;
|
|
186
|
+
modeTimer = 0;
|
|
187
|
+
autoSwitch = false;
|
|
188
|
+
}
|
|
189
|
+
if (keyp('ArrowLeft')) {
|
|
190
|
+
mode = (mode - 1 + MODES.length) % MODES.length;
|
|
191
|
+
modeTimer = 0;
|
|
192
|
+
autoSwitch = false;
|
|
193
|
+
}
|
|
194
|
+
if (keyp('Space')) {
|
|
195
|
+
autoSwitch = !autoSwitch;
|
|
196
|
+
modeTimer = 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Predator follows a lissajous curve
|
|
200
|
+
if (mode === 1) {
|
|
201
|
+
predator.x = W / 2 + Math.sin(time * 0.7) * 200;
|
|
202
|
+
predator.y = H / 2 + Math.cos(time * 1.1) * 120;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Update all boids with spatial optimization (grid)
|
|
206
|
+
for (const b of boids) {
|
|
207
|
+
b.update(boids);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Slowly shift background hue
|
|
211
|
+
backgroundColor = hsb((time * 5) % 360, 15, 5);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function draw() {
|
|
215
|
+
cls(backgroundColor);
|
|
216
|
+
|
|
217
|
+
// Draw trails
|
|
218
|
+
for (const b of boids) {
|
|
219
|
+
for (let i = 1; i < b.trail.length; i++) {
|
|
220
|
+
const alpha = (i / b.trail.length) * 0.4;
|
|
221
|
+
const col = hsb(b.hue, 70, 80 + i * 2, alpha);
|
|
222
|
+
line(b.trail[i - 1].x | 0, b.trail[i - 1].y | 0, b.trail[i].x | 0, b.trail[i].y | 0, col);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Draw boids as directional triangles
|
|
227
|
+
for (const b of boids) {
|
|
228
|
+
const angle = Math.atan2(b.vy, b.vx);
|
|
229
|
+
const speed = Math.sqrt(b.vx * b.vx + b.vy * b.vy);
|
|
230
|
+
const brightness = 60 + speed * 12;
|
|
231
|
+
const col = hsb(b.hue, 80, Math.min(100, brightness));
|
|
232
|
+
const s = b.size;
|
|
233
|
+
|
|
234
|
+
// Triangle pointing in direction of movement
|
|
235
|
+
const x1 = b.x + Math.cos(angle) * s * 2;
|
|
236
|
+
const y1 = b.y + Math.sin(angle) * s * 2;
|
|
237
|
+
const x2 = b.x + Math.cos(angle + 2.4) * s;
|
|
238
|
+
const y2 = b.y + Math.sin(angle + 2.4) * s;
|
|
239
|
+
const x3 = b.x + Math.cos(angle - 2.4) * s;
|
|
240
|
+
const y3 = b.y + Math.sin(angle - 2.4) * s;
|
|
241
|
+
|
|
242
|
+
line(x1 | 0, y1 | 0, x2 | 0, y2 | 0, col);
|
|
243
|
+
line(x2 | 0, y2 | 0, x3 | 0, y3 | 0, col);
|
|
244
|
+
line(x3 | 0, y3 | 0, x1 | 0, y1 | 0, col);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Draw predator in chase mode
|
|
248
|
+
if (mode === 1) {
|
|
249
|
+
const pulse = Math.sin(time * 6) * 0.3 + 0.7;
|
|
250
|
+
const r = 6 + pulse * 4;
|
|
251
|
+
circle(predator.x | 0, predator.y | 0, r, rgba8(255, 50, 50, 200), true);
|
|
252
|
+
circle(predator.x | 0, predator.y | 0, r + 3, rgba8(255, 100, 50, 100), false);
|
|
253
|
+
// Danger zone ring
|
|
254
|
+
circle(predator.x | 0, predator.y | 0, 80, rgba8(255, 30, 30, 30), false);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// HUD
|
|
258
|
+
rect(0, 0, 640, 24, rgba8(0, 0, 0, 150), true);
|
|
259
|
+
print(
|
|
260
|
+
`BOIDS FLOCKING | MODE: ${MODES[mode]} | ${NUM_BOIDS} AGENTS`,
|
|
261
|
+
10,
|
|
262
|
+
8,
|
|
263
|
+
rgba8(180, 220, 255)
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
const controlText = autoSwitch
|
|
267
|
+
? 'AUTO-SWITCHING (SPACE to pause) | LEFT/RIGHT to manual'
|
|
268
|
+
: 'MANUAL | LEFT/RIGHT switch | SPACE to auto';
|
|
269
|
+
print(controlText, 10, 348, rgba8(120, 120, 150, 200));
|
|
270
|
+
}
|