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,503 @@
|
|
|
1
|
+
# 🎨 Nova64 UI System - First Class Interface
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Nova64 now has a **professional-grade UI system** with buttons, panels, advanced text rendering, progress bars, and layout helpers. This makes Nova64 the most powerful fantasy console for creating polished game interfaces!
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
### ✅ Complete Font System
|
|
10
|
+
|
|
11
|
+
- **5 font sizes**: tiny, small, normal, large, huge
|
|
12
|
+
- **Text alignment**: left, center, right
|
|
13
|
+
- **Text baseline**: top, middle, bottom
|
|
14
|
+
- **Text effects**: shadows, outlines
|
|
15
|
+
- **Text measurement**: get width/height before rendering
|
|
16
|
+
|
|
17
|
+
### ✅ Panel System
|
|
18
|
+
|
|
19
|
+
- **Customizable panels** with borders, shadows, gradients
|
|
20
|
+
- **Title bars** with custom colors
|
|
21
|
+
- **Corner rounding** and decorations
|
|
22
|
+
- **Gradient backgrounds**
|
|
23
|
+
- **Flexible styling** options
|
|
24
|
+
|
|
25
|
+
### ✅ Button System
|
|
26
|
+
|
|
27
|
+
- **Interactive buttons** with hover/press states
|
|
28
|
+
- **Callback functions** on click
|
|
29
|
+
- **Multiple color states**: normal, hover, pressed, disabled
|
|
30
|
+
- **Auto-update system** for all buttons
|
|
31
|
+
- **Flexible positioning** and sizing
|
|
32
|
+
|
|
33
|
+
### ✅ Progress Bars
|
|
34
|
+
|
|
35
|
+
- **Horizontal progress bars** with fill
|
|
36
|
+
- **Customizable colors** based on value
|
|
37
|
+
- **Text display** showing current/max values
|
|
38
|
+
- **Border and background** styling
|
|
39
|
+
|
|
40
|
+
### ✅ Advanced Shapes
|
|
41
|
+
|
|
42
|
+
- **Rounded rectangles** with radius
|
|
43
|
+
- **Gradient rectangles** (vertical/horizontal)
|
|
44
|
+
- **Enhanced drawing** primitives
|
|
45
|
+
|
|
46
|
+
### ✅ Layout Helpers
|
|
47
|
+
|
|
48
|
+
- **Center positioning** for X and Y
|
|
49
|
+
- **Grid layout system** for arranging elements
|
|
50
|
+
- **Automatic calculations**
|
|
51
|
+
|
|
52
|
+
### ✅ Mouse/Input Support
|
|
53
|
+
|
|
54
|
+
- **Mouse position** tracking
|
|
55
|
+
- **Click detection** with pressed/held states
|
|
56
|
+
- **Button hover detection**
|
|
57
|
+
- **Input system integration**
|
|
58
|
+
|
|
59
|
+
## API Reference
|
|
60
|
+
|
|
61
|
+
### Font System
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
// Set font size
|
|
65
|
+
setFont('tiny'); // 1x size
|
|
66
|
+
setFont('small'); // 1x size, more spacing
|
|
67
|
+
setFont('normal'); // 2x size (default)
|
|
68
|
+
setFont('large'); // 3x size
|
|
69
|
+
setFont('huge'); // 4x size
|
|
70
|
+
|
|
71
|
+
// Text alignment
|
|
72
|
+
setTextAlign('left'); // Default
|
|
73
|
+
setTextAlign('center'); // Center-aligned
|
|
74
|
+
setTextAlign('right'); // Right-aligned
|
|
75
|
+
|
|
76
|
+
// Text baseline
|
|
77
|
+
setTextBaseline('top'); // Default
|
|
78
|
+
setTextBaseline('middle'); // Vertically centered
|
|
79
|
+
setTextBaseline('bottom'); // Bottom-aligned
|
|
80
|
+
|
|
81
|
+
// Measure text
|
|
82
|
+
const metrics = measureText('Hello', 2);
|
|
83
|
+
// Returns: { width: 60, height: 16 }
|
|
84
|
+
|
|
85
|
+
// Draw text
|
|
86
|
+
drawText('Hello World', x, y, color, scale);
|
|
87
|
+
|
|
88
|
+
// Draw text with shadow
|
|
89
|
+
drawTextShadow('Title', x, y, color, shadowColor, offset, scale);
|
|
90
|
+
|
|
91
|
+
// Draw text with outline
|
|
92
|
+
drawTextOutline('SCORE', x, y, color, outlineColor, scale);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Panel System
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
// Create panel
|
|
99
|
+
const panel = createPanel(x, y, width, height, {
|
|
100
|
+
bgColor: rgba8(0, 0, 0, 200),
|
|
101
|
+
borderColor: uiColors.primary,
|
|
102
|
+
borderWidth: 2,
|
|
103
|
+
cornerRadius: 0,
|
|
104
|
+
shadow: true,
|
|
105
|
+
shadowOffset: 4,
|
|
106
|
+
title: 'Panel Title',
|
|
107
|
+
titleColor: uiColors.white,
|
|
108
|
+
titleBgColor: uiColors.primary,
|
|
109
|
+
padding: 10,
|
|
110
|
+
visible: true,
|
|
111
|
+
gradient: true,
|
|
112
|
+
gradientColor: rgba8(0, 0, 50, 200),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Draw single panel
|
|
116
|
+
drawPanel(panel);
|
|
117
|
+
|
|
118
|
+
// Draw all panels
|
|
119
|
+
drawAllPanels();
|
|
120
|
+
|
|
121
|
+
// Remove panel
|
|
122
|
+
removePanel(panel);
|
|
123
|
+
|
|
124
|
+
// Clear all panels
|
|
125
|
+
clearPanels();
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Button System
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
// Create button
|
|
132
|
+
const button = createButton(
|
|
133
|
+
x,
|
|
134
|
+
y,
|
|
135
|
+
width,
|
|
136
|
+
height,
|
|
137
|
+
'Click Me',
|
|
138
|
+
() => {
|
|
139
|
+
console.log('Button clicked!');
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
enabled: true,
|
|
143
|
+
visible: true,
|
|
144
|
+
normalColor: uiColors.primary,
|
|
145
|
+
hoverColor: rgba8(50, 150, 255, 255),
|
|
146
|
+
pressedColor: rgba8(0, 80, 200, 255),
|
|
147
|
+
disabledColor: rgba8(100, 100, 100, 255),
|
|
148
|
+
textColor: uiColors.white,
|
|
149
|
+
borderColor: uiColors.white,
|
|
150
|
+
borderWidth: 2,
|
|
151
|
+
rounded: false,
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// Update single button
|
|
156
|
+
updateButton(button);
|
|
157
|
+
|
|
158
|
+
// Update all buttons
|
|
159
|
+
updateAllButtons();
|
|
160
|
+
|
|
161
|
+
// Draw single button
|
|
162
|
+
drawButton(button);
|
|
163
|
+
|
|
164
|
+
// Draw all buttons
|
|
165
|
+
drawAllButtons();
|
|
166
|
+
|
|
167
|
+
// Remove button
|
|
168
|
+
removeButton(button);
|
|
169
|
+
|
|
170
|
+
// Clear all buttons
|
|
171
|
+
clearButtons();
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Progress Bars
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
// Draw progress bar
|
|
178
|
+
drawProgressBar(x, y, width, height, currentValue, maxValue, {
|
|
179
|
+
bgColor: rgba8(50, 50, 50, 255),
|
|
180
|
+
fillColor: uiColors.success,
|
|
181
|
+
borderColor: uiColors.white,
|
|
182
|
+
showText: true,
|
|
183
|
+
textColor: uiColors.white,
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Example: Health bar that changes color
|
|
187
|
+
const healthColor =
|
|
188
|
+
health > 50 ? uiColors.success : health > 25 ? uiColors.warning : uiColors.danger;
|
|
189
|
+
|
|
190
|
+
drawProgressBar(x, y, 200, 20, health, 100, {
|
|
191
|
+
fillColor: healthColor,
|
|
192
|
+
showText: true,
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Advanced Shapes
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
// Rounded rectangle
|
|
200
|
+
drawRoundedRect(x, y, width, height, radius, color, filled);
|
|
201
|
+
|
|
202
|
+
// Gradient rectangle
|
|
203
|
+
drawGradientRect(x, y, width, height, color1, color2, vertical);
|
|
204
|
+
|
|
205
|
+
// Example
|
|
206
|
+
drawGradientRect(
|
|
207
|
+
0,
|
|
208
|
+
0,
|
|
209
|
+
640,
|
|
210
|
+
360,
|
|
211
|
+
rgba8(10, 10, 30, 255), // Top color
|
|
212
|
+
rgba8(30, 10, 50, 255), // Bottom color
|
|
213
|
+
true // Vertical gradient
|
|
214
|
+
);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Layout Helpers
|
|
218
|
+
|
|
219
|
+
```javascript
|
|
220
|
+
// Center element horizontally
|
|
221
|
+
const x = centerX(elementWidth, 640);
|
|
222
|
+
|
|
223
|
+
// Center element vertically
|
|
224
|
+
const y = centerY(elementHeight, 360);
|
|
225
|
+
|
|
226
|
+
// Create grid layout
|
|
227
|
+
const cells = grid(cols, rows, cellWidth, cellHeight, paddingX, paddingY);
|
|
228
|
+
// Returns array of { x, y, width, height, col, row }
|
|
229
|
+
|
|
230
|
+
// Example: 3x2 grid of buttons
|
|
231
|
+
const buttonGrid = grid(3, 2, 80, 40, 10, 10);
|
|
232
|
+
buttonGrid.forEach((cell, i) => {
|
|
233
|
+
createButton(cell.x, cell.y, cell.width, cell.height, `Btn ${i}`, () => {
|
|
234
|
+
console.log(`Button ${i} clicked`);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Mouse/Input
|
|
240
|
+
|
|
241
|
+
```javascript
|
|
242
|
+
// Set mouse position (from actual mouse or keyboard)
|
|
243
|
+
setMousePosition(x, y);
|
|
244
|
+
|
|
245
|
+
// Set mouse button state
|
|
246
|
+
setMouseButton(isDown);
|
|
247
|
+
|
|
248
|
+
// Get mouse position
|
|
249
|
+
const pos = getMousePosition();
|
|
250
|
+
console.log(pos.x, pos.y);
|
|
251
|
+
|
|
252
|
+
// Check mouse state
|
|
253
|
+
if (isMouseDown()) {
|
|
254
|
+
// Mouse button held
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (isMousePressed()) {
|
|
258
|
+
// Mouse button just pressed this frame
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Color Palette
|
|
263
|
+
|
|
264
|
+
```javascript
|
|
265
|
+
// Built-in colors
|
|
266
|
+
uiColors.primary; // Blue
|
|
267
|
+
uiColors.secondary; // Light blue
|
|
268
|
+
uiColors.success; // Green
|
|
269
|
+
uiColors.warning; // Yellow
|
|
270
|
+
uiColors.danger; // Red
|
|
271
|
+
uiColors.dark; // Dark gray
|
|
272
|
+
uiColors.light; // Light gray
|
|
273
|
+
uiColors.white; // White
|
|
274
|
+
uiColors.black; // Black
|
|
275
|
+
uiColors.transparent; // Transparent
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Complete Example
|
|
279
|
+
|
|
280
|
+
```javascript
|
|
281
|
+
// UI Demo Game
|
|
282
|
+
|
|
283
|
+
let ui = {
|
|
284
|
+
healthPanel: null,
|
|
285
|
+
menuButtons: [],
|
|
286
|
+
health: 100,
|
|
287
|
+
score: 0,
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
export async function init() {
|
|
291
|
+
// Create health panel
|
|
292
|
+
ui.healthPanel = createPanel(10, 10, 220, 80, {
|
|
293
|
+
title: 'Player Stats',
|
|
294
|
+
borderColor: uiColors.primary,
|
|
295
|
+
shadow: true,
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Create menu buttons
|
|
299
|
+
ui.menuButtons.push(
|
|
300
|
+
createButton(
|
|
301
|
+
centerX(100),
|
|
302
|
+
200,
|
|
303
|
+
100,
|
|
304
|
+
40,
|
|
305
|
+
'START',
|
|
306
|
+
() => {
|
|
307
|
+
console.log('Game started!');
|
|
308
|
+
},
|
|
309
|
+
{ normalColor: uiColors.success }
|
|
310
|
+
)
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
ui.menuButtons.push(
|
|
314
|
+
createButton(
|
|
315
|
+
centerX(100),
|
|
316
|
+
250,
|
|
317
|
+
100,
|
|
318
|
+
40,
|
|
319
|
+
'OPTIONS',
|
|
320
|
+
() => {
|
|
321
|
+
console.log('Options opened!');
|
|
322
|
+
},
|
|
323
|
+
{ normalColor: uiColors.primary }
|
|
324
|
+
)
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
ui.menuButtons.push(
|
|
328
|
+
createButton(
|
|
329
|
+
centerX(100),
|
|
330
|
+
300,
|
|
331
|
+
100,
|
|
332
|
+
40,
|
|
333
|
+
'QUIT',
|
|
334
|
+
() => {
|
|
335
|
+
console.log('Game quit!');
|
|
336
|
+
},
|
|
337
|
+
{ normalColor: uiColors.danger }
|
|
338
|
+
)
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export function update(dt) {
|
|
343
|
+
// Handle mouse input
|
|
344
|
+
// (In real game, use actual mouse events)
|
|
345
|
+
|
|
346
|
+
// Update all buttons
|
|
347
|
+
updateAllButtons();
|
|
348
|
+
|
|
349
|
+
// Game logic
|
|
350
|
+
ui.health = Math.max(0, ui.health - dt * 2);
|
|
351
|
+
ui.score += Math.floor(dt * 100);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export function draw() {
|
|
355
|
+
// Clear screen
|
|
356
|
+
cls();
|
|
357
|
+
|
|
358
|
+
// Draw gradient background
|
|
359
|
+
drawGradientRect(0, 0, 640, 360, rgba8(20, 20, 40, 255), rgba8(40, 20, 60, 255), true);
|
|
360
|
+
|
|
361
|
+
// Draw panels
|
|
362
|
+
drawAllPanels();
|
|
363
|
+
|
|
364
|
+
// Draw health bar
|
|
365
|
+
setFont('normal');
|
|
366
|
+
setTextAlign('left');
|
|
367
|
+
drawText('HEALTH', 20, 40, uiColors.white, 1);
|
|
368
|
+
drawProgressBar(20, 60, 200, 20, ui.health, 100, {
|
|
369
|
+
fillColor: ui.health > 50 ? uiColors.success : uiColors.danger,
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
// Draw score
|
|
373
|
+
setFont('large');
|
|
374
|
+
setTextAlign('center');
|
|
375
|
+
const scoreText = 'SCORE: ' + ui.score.toString().padStart(6, '0');
|
|
376
|
+
drawTextOutline(scoreText, 320, 100, uiColors.warning, uiColors.black, 1);
|
|
377
|
+
|
|
378
|
+
// Draw buttons
|
|
379
|
+
drawAllButtons();
|
|
380
|
+
|
|
381
|
+
// Draw title
|
|
382
|
+
setFont('huge');
|
|
383
|
+
setTextAlign('center');
|
|
384
|
+
drawTextShadow('MY GAME', 320, 30, uiColors.primary, uiColors.black, 3, 1);
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## Best Practices
|
|
389
|
+
|
|
390
|
+
### 1. Use Panels for Grouping
|
|
391
|
+
|
|
392
|
+
```javascript
|
|
393
|
+
// Create a panel for related UI elements
|
|
394
|
+
const statsPanel = createPanel(10, 10, 200, 150, {
|
|
395
|
+
title: 'Statistics',
|
|
396
|
+
shadow: true,
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// Draw panel first
|
|
400
|
+
drawPanel(statsPanel);
|
|
401
|
+
|
|
402
|
+
// Then draw contents inside panel bounds
|
|
403
|
+
drawText('Health: 100', 20, 40);
|
|
404
|
+
drawText('Mana: 50', 20, 60);
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### 2. Update Buttons Every Frame
|
|
408
|
+
|
|
409
|
+
```javascript
|
|
410
|
+
export function update(dt) {
|
|
411
|
+
// Always update buttons to track hover/click
|
|
412
|
+
updateAllButtons();
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export function draw() {
|
|
416
|
+
// Always draw buttons after updating
|
|
417
|
+
drawAllButtons();
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### 3. Use Font Sizes Appropriately
|
|
422
|
+
|
|
423
|
+
```javascript
|
|
424
|
+
setFont('huge'); // Game titles
|
|
425
|
+
setFont('large'); // Section headers
|
|
426
|
+
setFont('normal'); // Body text (default)
|
|
427
|
+
setFont('small'); // Details
|
|
428
|
+
setFont('tiny'); // Fine print
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### 4. Center Important Elements
|
|
432
|
+
|
|
433
|
+
```javascript
|
|
434
|
+
// Title centered horizontally
|
|
435
|
+
const titleX = centerX(200);
|
|
436
|
+
drawText('GAME TITLE', titleX, 50);
|
|
437
|
+
|
|
438
|
+
// Dialog centered both ways
|
|
439
|
+
const dialogWidth = 300;
|
|
440
|
+
const dialogHeight = 200;
|
|
441
|
+
const dialogX = centerX(dialogWidth);
|
|
442
|
+
const dialogY = centerY(dialogHeight);
|
|
443
|
+
createPanel(dialogX, dialogY, dialogWidth, dialogHeight);
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### 5. Use Color Palette Consistently
|
|
447
|
+
|
|
448
|
+
```javascript
|
|
449
|
+
// Good: Use semantic colors
|
|
450
|
+
createButton(x, y, w, h, 'Accept', callback, {
|
|
451
|
+
normalColor: uiColors.success,
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
createButton(x, y, w, h, 'Cancel', callback, {
|
|
455
|
+
normalColor: uiColors.danger,
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
// Consistent throughout your game
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## Performance Tips
|
|
462
|
+
|
|
463
|
+
1. **Create UI elements once in `init()`**, not every frame
|
|
464
|
+
2. **Only update buttons when needed** (e.g., on menu screens)
|
|
465
|
+
3. **Use `visible` property** to hide/show without recreating
|
|
466
|
+
4. **Clear panels/buttons** when switching screens
|
|
467
|
+
|
|
468
|
+
## Migration from Old API
|
|
469
|
+
|
|
470
|
+
### Before (Basic)
|
|
471
|
+
|
|
472
|
+
```javascript
|
|
473
|
+
print('Score: 100', 10, 10, rgba8(255, 255, 0, 255));
|
|
474
|
+
rect(10, 30, 200, 20, rgba8(0, 255, 0, 255), true);
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### After (Professional)
|
|
478
|
+
|
|
479
|
+
```javascript
|
|
480
|
+
setFont('large');
|
|
481
|
+
setTextAlign('left');
|
|
482
|
+
drawTextOutline('Score: 100', 10, 10, uiColors.warning, uiColors.black, 1);
|
|
483
|
+
drawProgressBar(10, 30, 200, 20, score, maxScore, {
|
|
484
|
+
fillColor: uiColors.success,
|
|
485
|
+
});
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
## Try It Now!
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
# Start dev server
|
|
492
|
+
pnpm dev
|
|
493
|
+
|
|
494
|
+
# Open browser
|
|
495
|
+
http://localhost:5173/?demo=ui-demo
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
Use **Arrow Keys** to move cursor, **Space** to click buttons!
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
**Nova64: The Best Fantasy Console** 🎮✨
|
|
503
|
+
_Now with first-class UI system!_
|