phaser-wind 0.1.0 → 0.3.0
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 +317 -95
- package/dist/core/color.d.ts +287 -0
- package/dist/core/color.d.ts.map +1 -0
- package/dist/core/color.js +386 -0
- package/dist/core/color.js.map +1 -0
- package/dist/core/color.spec.d.ts +2 -0
- package/dist/core/color.spec.d.ts.map +1 -0
- package/dist/core/color.spec.js +252 -0
- package/dist/core/color.spec.js.map +1 -0
- package/dist/core/font-size.d.ts +34 -0
- package/dist/core/font-size.d.ts.map +1 -0
- package/dist/core/font-size.js +68 -0
- package/dist/core/font-size.js.map +1 -0
- package/dist/core/font-size.spec.d.ts +2 -0
- package/dist/core/font-size.spec.d.ts.map +1 -0
- package/dist/core/font-size.spec.js +73 -0
- package/dist/core/font-size.spec.js.map +1 -0
- package/dist/core/font.d.ts +94 -0
- package/dist/core/font.d.ts.map +1 -0
- package/dist/core/font.js +178 -0
- package/dist/core/font.js.map +1 -0
- package/dist/core/font.spec.d.ts +2 -0
- package/dist/core/font.spec.d.ts.map +1 -0
- package/dist/core/font.spec.js +84 -0
- package/dist/core/font.spec.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -0
- package/dist/{color → core}/pallete.d.ts.map +1 -1
- package/dist/core/pallete.js.map +1 -0
- package/dist/core/radius.d.ts +34 -0
- package/dist/core/radius.d.ts.map +1 -0
- package/dist/core/radius.js +46 -0
- package/dist/core/radius.js.map +1 -0
- package/dist/core/radius.spec.d.ts +2 -0
- package/dist/core/radius.spec.d.ts.map +1 -0
- package/dist/core/radius.spec.js +61 -0
- package/dist/core/radius.spec.js.map +1 -0
- package/dist/core/shadow.d.ts +23 -0
- package/dist/core/shadow.d.ts.map +1 -0
- package/dist/core/shadow.js +23 -0
- package/dist/core/shadow.js.map +1 -0
- package/dist/core/spacing.d.ts +39 -0
- package/dist/core/spacing.d.ts.map +1 -0
- package/dist/core/spacing.js +82 -0
- package/dist/core/spacing.js.map +1 -0
- package/dist/core/spacing.spec.d.ts +2 -0
- package/dist/core/spacing.spec.d.ts.map +1 -0
- package/dist/core/spacing.spec.js +49 -0
- package/dist/core/spacing.spec.js.map +1 -0
- package/dist/font/index.d.ts +2 -1
- package/dist/font/index.d.ts.map +1 -1
- package/dist/font/index.js +2 -1
- package/dist/font/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/theme/index.d.ts +3 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +3 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/theme-config.d.ts +98 -0
- package/dist/theme/theme-config.d.ts.map +1 -0
- package/dist/theme/theme-config.js +156 -0
- package/dist/theme/theme-config.js.map +1 -0
- package/dist/theme/theme-manager.d.ts +108 -0
- package/dist/theme/theme-manager.d.ts.map +1 -0
- package/dist/theme/theme-manager.js +190 -0
- package/dist/theme/theme-manager.js.map +1 -0
- package/dist/theme/type.d.ts +1 -0
- package/dist/theme/type.d.ts.map +1 -0
- package/dist/theme/type.js +2 -0
- package/dist/theme/type.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/is-valid-color.d.ts +13 -0
- package/dist/utils/is-valid-color.d.ts.map +1 -0
- package/dist/utils/is-valid-color.js +32 -0
- package/dist/utils/is-valid-color.js.map +1 -0
- package/dist/utils/is-valid-color.spec.d.ts +2 -0
- package/dist/utils/is-valid-color.spec.d.ts.map +1 -0
- package/dist/utils/is-valid-color.spec.js +82 -0
- package/dist/utils/is-valid-color.spec.js.map +1 -0
- package/package.json +5 -3
- package/dist/color/color-picker.d.ts +0 -13
- package/dist/color/color-picker.d.ts.map +0 -1
- package/dist/color/color-picker.js +0 -61
- package/dist/color/color-picker.js.map +0 -1
- package/dist/color/color-picker.spec.d.ts +0 -2
- package/dist/color/color-picker.spec.d.ts.map +0 -1
- package/dist/color/color-picker.spec.js +0 -41
- package/dist/color/color-picker.spec.js.map +0 -1
- package/dist/color/index.d.ts +0 -3
- package/dist/color/index.d.ts.map +0 -1
- package/dist/color/index.js +0 -3
- package/dist/color/index.js.map +0 -1
- package/dist/color/pallete.js.map +0 -1
- package/dist/font/font-size-picker.d.ts +0 -19
- package/dist/font/font-size-picker.d.ts.map +0 -1
- package/dist/font/font-size-picker.js +0 -24
- package/dist/font/font-size-picker.js.map +0 -1
- package/dist/font/font-size-picker.spec.d.ts +0 -2
- package/dist/font/font-size-picker.spec.d.ts.map +0 -1
- package/dist/font/font-size-picker.spec.js +0 -48
- package/dist/font/font-size-picker.spec.js.map +0 -1
- /package/dist/{color → core}/pallete.d.ts +0 -0
- /package/dist/{color → core}/pallete.js +0 -0
package/README.md
CHANGED
|
@@ -37,18 +37,18 @@ const title = this.add.text(200, 100, 'Game Title', {
|
|
|
37
37
|
### The Solution 🌟
|
|
38
38
|
|
|
39
39
|
```typescript
|
|
40
|
-
import {
|
|
40
|
+
import { Color, FontSize } from 'phaser-wind';
|
|
41
41
|
|
|
42
42
|
// Clean, semantic, consistent!
|
|
43
43
|
const button = this.add.text(100, 50, 'Click me!', {
|
|
44
|
-
fontSize:
|
|
45
|
-
fill:
|
|
46
|
-
backgroundColor:
|
|
44
|
+
fontSize: FontSize.css('lg'), // Clear intention!
|
|
45
|
+
fill: Color.rgb('blue-500'), // Beautiful blue
|
|
46
|
+
backgroundColor: Color.rgb('gray-800'), // Perfect contrast
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
const title = this.add.text(200, 100, 'Game Title', {
|
|
50
|
-
fontSize:
|
|
51
|
-
fill:
|
|
50
|
+
fontSize: FontSize.css('3xl'), // Clearly bigger!
|
|
51
|
+
fill: Color.rgb('red-500'), // Vibrant red
|
|
52
52
|
});
|
|
53
53
|
```
|
|
54
54
|
|
|
@@ -58,6 +58,9 @@ const title = this.add.text(200, 100, 'Game Title', {
|
|
|
58
58
|
|
|
59
59
|
- 🎨 **Complete Tailwind Color Palette** - All 22 color families with 11 shades each
|
|
60
60
|
- 📐 **Semantic Font Sizes** - From `xs` to `6xl`, just like Tailwind
|
|
61
|
+
- 🎨 **Structured Theme System** - Nested design tokens for colors, fonts, spacing, typography, and effects
|
|
62
|
+
- 🔄 **Dynamic Theme Switching** - Change themes at runtime with full type safety
|
|
63
|
+
- 🎯 **Smart Token Resolution** - Themes can reference other theme tokens automatically
|
|
61
64
|
- 🔧 **TypeScript First** - Full type safety and IntelliSense
|
|
62
65
|
- 🎮 **Phaser Ready** - Designed specifically for Phaser 3 games
|
|
63
66
|
- 🌈 **Consistent Design** - No more guessing colors and sizes
|
|
@@ -84,19 +87,19 @@ pnpm add phaser-wind
|
|
|
84
87
|
Access all Tailwind colors with semantic naming:
|
|
85
88
|
|
|
86
89
|
```typescript
|
|
87
|
-
import {
|
|
90
|
+
import { Color } from 'phaser-wind';
|
|
88
91
|
|
|
89
92
|
// RGB strings (for Phaser text styles)
|
|
90
|
-
const blueText =
|
|
91
|
-
const redButton =
|
|
93
|
+
const blueText = Color.rgb('blue-500'); // 'rgb(59, 130, 246)'
|
|
94
|
+
const redButton = Color.rgb('red-600'); // 'rgb(220, 38, 38)'
|
|
92
95
|
|
|
93
96
|
// Hex numbers (for Phaser graphics)
|
|
94
|
-
const greenRect =
|
|
95
|
-
const purpleCircle =
|
|
97
|
+
const greenRect = Color.hex('green-400'); // 0x4ADE80
|
|
98
|
+
const purpleCircle = Color.hex('purple-300'); // 0xD8B4FE
|
|
96
99
|
|
|
97
100
|
// Basic colors
|
|
98
|
-
const blackText =
|
|
99
|
-
const whiteBackground =
|
|
101
|
+
const blackText = Color.rgb('black'); // 'rgb(0, 0, 0)'
|
|
102
|
+
const whiteBackground = Color.hex('white'); // 0xFFFFFF
|
|
100
103
|
```
|
|
101
104
|
|
|
102
105
|
### Available Colors
|
|
@@ -114,35 +117,252 @@ const whiteBackground = ColorPicker.hex('white'); // 0xFFFFFF
|
|
|
114
117
|
Stop guessing font sizes and use semantic tokens:
|
|
115
118
|
|
|
116
119
|
```typescript
|
|
117
|
-
import {
|
|
120
|
+
import { FontSize } from 'phaser-wind';
|
|
118
121
|
|
|
119
122
|
// Get pixel values
|
|
120
|
-
const smallText =
|
|
121
|
-
const normalText =
|
|
122
|
-
const largeTitle =
|
|
123
|
+
const smallText = FontSize.px('sm'); // 14
|
|
124
|
+
const normalText = FontSize.px('base'); // 16
|
|
125
|
+
const largeTitle = FontSize.px('3xl'); // 30
|
|
123
126
|
|
|
124
127
|
// Get CSS strings (perfect for Phaser)
|
|
125
|
-
const buttonText =
|
|
126
|
-
const heroTitle =
|
|
128
|
+
const buttonText = FontSize.css('lg'); // '18px'
|
|
129
|
+
const heroTitle = FontSize.css('6xl'); // '60px'
|
|
127
130
|
|
|
128
131
|
// Get rem values (if needed)
|
|
129
|
-
const responsiveText =
|
|
132
|
+
const responsiveText = FontSize.rem('xl'); // 1.25
|
|
130
133
|
```
|
|
131
134
|
|
|
132
135
|
### Font Size Scale
|
|
133
136
|
|
|
134
|
-
| Token
|
|
135
|
-
|
|
|
136
|
-
| `xs`
|
|
137
|
-
| `sm`
|
|
138
|
-
| `
|
|
139
|
-
| `lg`
|
|
140
|
-
| `xl`
|
|
141
|
-
| `2xl`
|
|
142
|
-
| `3xl`
|
|
143
|
-
| `4xl`
|
|
144
|
-
| `5xl`
|
|
145
|
-
| `6xl`
|
|
137
|
+
| Token | Pixels | Use Case |
|
|
138
|
+
| ------ | ------ | ----------------------- |
|
|
139
|
+
| `xs` | 12px | Small labels, captions |
|
|
140
|
+
| `sm` | 14px | Body text, descriptions |
|
|
141
|
+
| `base` | 16px | Default text size |
|
|
142
|
+
| `lg` | 18px | Slightly larger text |
|
|
143
|
+
| `xl` | 20px | Subheadings |
|
|
144
|
+
| `2xl` | 24px | Headings |
|
|
145
|
+
| `3xl` | 30px | Large headings |
|
|
146
|
+
| `4xl` | 36px | Hero text |
|
|
147
|
+
| `5xl` | 48px | Display text |
|
|
148
|
+
| `6xl` | 60px | Giant display text |
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 🎨 Theme System
|
|
153
|
+
|
|
154
|
+
Phaser Wind includes a powerful **structured theme system** that lets you organize your design tokens into logical categories and create consistent, reusable designs.
|
|
155
|
+
|
|
156
|
+
### 🏗️ **Theme Structure**
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { createTheme, ThemeManager } from 'phaser-wind';
|
|
160
|
+
|
|
161
|
+
const gameTheme = createTheme({
|
|
162
|
+
fonts: {
|
|
163
|
+
primary: 'Inter, system-ui, sans-serif',
|
|
164
|
+
display: 'Orbitron, monospace', // Sci-fi font for headers
|
|
165
|
+
ui: 'Roboto, Arial, sans-serif',
|
|
166
|
+
},
|
|
167
|
+
colors: {
|
|
168
|
+
primary: 'purple-600',
|
|
169
|
+
secondary: 'cyan-500',
|
|
170
|
+
'ui-background': 'slate-900',
|
|
171
|
+
'player-health': 'green-500',
|
|
172
|
+
'enemy-health': 'red-600',
|
|
173
|
+
},
|
|
174
|
+
spacing: {
|
|
175
|
+
xs: 4,
|
|
176
|
+
sm: 8,
|
|
177
|
+
md: 16,
|
|
178
|
+
lg: 24,
|
|
179
|
+
xl: 32,
|
|
180
|
+
},
|
|
181
|
+
typography: {
|
|
182
|
+
heading: {
|
|
183
|
+
fontSize: '2xl',
|
|
184
|
+
fontFamily: 'fonts.display', // 🔗 References fonts.display!
|
|
185
|
+
fontWeight: 600,
|
|
186
|
+
lineHeight: 1.2,
|
|
187
|
+
},
|
|
188
|
+
body: {
|
|
189
|
+
fontSize: 'md',
|
|
190
|
+
fontFamily: 'fonts.primary',
|
|
191
|
+
fontWeight: 400,
|
|
192
|
+
lineHeight: 1.5,
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
effects: {
|
|
196
|
+
'glow-primary': {
|
|
197
|
+
blur: 8,
|
|
198
|
+
color: 'colors.primary', // 🔗 References colors.primary!
|
|
199
|
+
alpha: 0.6,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
// Custom categories work too!
|
|
203
|
+
animations: {
|
|
204
|
+
duration: 300,
|
|
205
|
+
easing: 'ease-out',
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Initialize your theme
|
|
210
|
+
ThemeManager.init(gameTheme);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 🎯 **Using Theme Tokens**
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import { Color, Font, FontSize, Spacing, ThemeManager } from 'phaser-wind';
|
|
217
|
+
|
|
218
|
+
// Colors - automatically looks in colors.*
|
|
219
|
+
const primaryColor = Color.rgb('primary'); // Gets colors.primary
|
|
220
|
+
const uiBackground = Color.hex('ui-background'); // Gets colors.ui-background
|
|
221
|
+
|
|
222
|
+
// Fonts
|
|
223
|
+
const displayFont = Font.family('display'); // Gets fonts.display
|
|
224
|
+
const primaryFont = Font.family('primary'); // Gets fonts.primary
|
|
225
|
+
|
|
226
|
+
// Spacing
|
|
227
|
+
const mediumSpace = Spacing.px('md'); // Gets spacing.md (16px)
|
|
228
|
+
const largeSpace = Spacing.px('lg'); // Gets spacing.lg (24px)
|
|
229
|
+
|
|
230
|
+
// Complete typography styles - using basic components for now
|
|
231
|
+
const headingStyle = {
|
|
232
|
+
fontSize: FontSize.css('2xl'),
|
|
233
|
+
fontFamily: Font.family('display'),
|
|
234
|
+
fontWeight: 'bold',
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// Custom tokens
|
|
238
|
+
const animDuration = ThemeManager.getToken('animations.duration'); // 300
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### 🔄 **Dynamic Theme Switching**
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
// Register multiple themes
|
|
245
|
+
ThemeManager.registerTheme('light', lightTheme);
|
|
246
|
+
ThemeManager.registerTheme('dark', darkTheme);
|
|
247
|
+
ThemeManager.registerTheme('cyberpunk', cyberpunkTheme);
|
|
248
|
+
|
|
249
|
+
// Switch themes instantly
|
|
250
|
+
ThemeManager.setTheme('dark');
|
|
251
|
+
|
|
252
|
+
// Listen for theme changes
|
|
253
|
+
ThemeManager.onThemeChange(newTheme => {
|
|
254
|
+
console.log('Theme changed!', newTheme);
|
|
255
|
+
// Update your game UI here
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Get available themes
|
|
259
|
+
const themes = ThemeManager.getRegisteredThemes(); // ['light', 'dark', 'cyberpunk']
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 🎮 **Real Game Example**
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
export class GameScene extends Phaser.Scene {
|
|
266
|
+
create() {
|
|
267
|
+
// Player health bar with theme colors
|
|
268
|
+
const healthWidth = Spacing.px('24'); // 96px
|
|
269
|
+
const healthHeight = Spacing.px('4'); // 16px
|
|
270
|
+
|
|
271
|
+
this.add.rectangle(
|
|
272
|
+
50,
|
|
273
|
+
50,
|
|
274
|
+
healthWidth,
|
|
275
|
+
healthHeight,
|
|
276
|
+
Color.hex('player-health')
|
|
277
|
+
); // Green from theme
|
|
278
|
+
|
|
279
|
+
// Game title with theme typography
|
|
280
|
+
this.add
|
|
281
|
+
.text(400, 50, 'CYBER QUEST', {
|
|
282
|
+
fontSize: FontSize.css('4xl'),
|
|
283
|
+
fontFamily: Font.family('display'),
|
|
284
|
+
color: Color.rgb('primary'), // Purple from theme
|
|
285
|
+
})
|
|
286
|
+
.setOrigin(0.5);
|
|
287
|
+
|
|
288
|
+
// UI button with consistent spacing and colors
|
|
289
|
+
this.createButton(
|
|
290
|
+
400,
|
|
291
|
+
400,
|
|
292
|
+
'START GAME',
|
|
293
|
+
Spacing.px('16'), // 64px width
|
|
294
|
+
Spacing.px('6') // 24px height
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
createButton(
|
|
299
|
+
x: number,
|
|
300
|
+
y: number,
|
|
301
|
+
text: string,
|
|
302
|
+
width: number,
|
|
303
|
+
height: number
|
|
304
|
+
) {
|
|
305
|
+
const button = this.add
|
|
306
|
+
.rectangle(x, y, width, height, Color.hex('ui-background'))
|
|
307
|
+
.setInteractive()
|
|
308
|
+
.on('pointerover', () => button.setFillStyle(Color.hex('secondary')))
|
|
309
|
+
.on('pointerout', () => button.setFillStyle(Color.hex('ui-background')));
|
|
310
|
+
|
|
311
|
+
this.add
|
|
312
|
+
.text(x, y, text, {
|
|
313
|
+
fontSize: FontSize.css('base'),
|
|
314
|
+
fontFamily: Font.family('primary'),
|
|
315
|
+
color: Color.rgb('primary'),
|
|
316
|
+
})
|
|
317
|
+
.setOrigin(0.5);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### 🎨 **Pre-built Themes**
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import { defaultLightTheme, defaultDarkTheme } from 'phaser-wind';
|
|
326
|
+
|
|
327
|
+
// Light theme with professional colors
|
|
328
|
+
ThemeManager.init(defaultLightTheme);
|
|
329
|
+
|
|
330
|
+
// Dark theme perfect for games
|
|
331
|
+
ThemeManager.init(defaultDarkTheme);
|
|
332
|
+
|
|
333
|
+
// Create variations
|
|
334
|
+
const winterTheme = ThemeManager.extendCurrentTheme({
|
|
335
|
+
'colors.primary': 'blue-400',
|
|
336
|
+
'colors.secondary': 'cyan-300',
|
|
337
|
+
'colors.accent': 'white',
|
|
338
|
+
});
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 🔗 **Smart Token References**
|
|
342
|
+
|
|
343
|
+
Themes can reference other tokens using dot notation:
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
const theme = createTheme({
|
|
347
|
+
colors: {
|
|
348
|
+
brand: 'purple-600',
|
|
349
|
+
danger: 'red-500',
|
|
350
|
+
},
|
|
351
|
+
typography: {
|
|
352
|
+
title: {
|
|
353
|
+
fontSize: '4xl',
|
|
354
|
+
fontFamily: 'fonts.display', // 🔗 Auto-resolves to fonts.display
|
|
355
|
+
color: 'colors.brand', // 🔗 Auto-resolves to purple-600
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
effects: {
|
|
359
|
+
'brand-glow': {
|
|
360
|
+
color: 'colors.brand', // 🔗 Auto-resolves to purple-600
|
|
361
|
+
blur: 8,
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
});
|
|
365
|
+
```
|
|
146
366
|
|
|
147
367
|
---
|
|
148
368
|
|
|
@@ -151,50 +371,50 @@ const responsiveText = FontSizePicker.rem('xl'); // 1.25
|
|
|
151
371
|
### Game UI Components
|
|
152
372
|
|
|
153
373
|
```typescript
|
|
154
|
-
import {
|
|
374
|
+
import { Color, FontSize } from 'phaser-wind';
|
|
155
375
|
|
|
156
376
|
export class GameScene extends Phaser.Scene {
|
|
157
377
|
create() {
|
|
158
378
|
// Main title
|
|
159
379
|
this.add
|
|
160
380
|
.text(400, 100, 'SPACE RAIDERS', {
|
|
161
|
-
fontSize:
|
|
162
|
-
fill:
|
|
163
|
-
stroke:
|
|
381
|
+
fontSize: FontSize.css('5xl'),
|
|
382
|
+
fill: Color.rgb('yellow-400'),
|
|
383
|
+
stroke: Color.rgb('yellow-800'),
|
|
164
384
|
strokeThickness: 2,
|
|
165
385
|
})
|
|
166
386
|
.setOrigin(0.5);
|
|
167
387
|
|
|
168
388
|
// Score display
|
|
169
389
|
this.add.text(50, 50, 'Score: 12,500', {
|
|
170
|
-
fontSize:
|
|
171
|
-
fill:
|
|
390
|
+
fontSize: FontSize.css('xl'),
|
|
391
|
+
fill: Color.rgb('green-400'),
|
|
172
392
|
});
|
|
173
393
|
|
|
174
394
|
// Health bar background
|
|
175
395
|
const healthBg = this.add.graphics();
|
|
176
|
-
healthBg.fillStyle(
|
|
396
|
+
healthBg.fillStyle(Color.hex('red-900'));
|
|
177
397
|
healthBg.fillRect(50, 100, 200, 20);
|
|
178
398
|
|
|
179
399
|
// Health bar fill
|
|
180
400
|
const healthFill = this.add.graphics();
|
|
181
|
-
healthFill.fillStyle(
|
|
401
|
+
healthFill.fillStyle(Color.hex('red-500'));
|
|
182
402
|
healthFill.fillRect(52, 102, 156, 16); // 80% health
|
|
183
403
|
|
|
184
404
|
// Game over screen
|
|
185
|
-
this.add.rectangle(400, 300, 600, 400,
|
|
405
|
+
this.add.rectangle(400, 300, 600, 400, Color.hex('slate-900'), 0.9);
|
|
186
406
|
|
|
187
407
|
this.add
|
|
188
408
|
.text(400, 250, 'GAME OVER', {
|
|
189
|
-
fontSize:
|
|
190
|
-
fill:
|
|
409
|
+
fontSize: FontSize.css('4xl'),
|
|
410
|
+
fill: Color.rgb('red-500'),
|
|
191
411
|
})
|
|
192
412
|
.setOrigin(0.5);
|
|
193
413
|
|
|
194
414
|
this.add
|
|
195
415
|
.text(400, 320, 'Final Score: 12,500', {
|
|
196
|
-
fontSize:
|
|
197
|
-
fill:
|
|
416
|
+
fontSize: FontSize.css('2xl'),
|
|
417
|
+
fill: Color.rgb('slate-300'),
|
|
198
418
|
})
|
|
199
419
|
.setOrigin(0.5);
|
|
200
420
|
}
|
|
@@ -214,19 +434,19 @@ class GameButton {
|
|
|
214
434
|
) {
|
|
215
435
|
const colors = {
|
|
216
436
|
primary: {
|
|
217
|
-
bg:
|
|
218
|
-
bgHover:
|
|
219
|
-
text:
|
|
437
|
+
bg: Color.hex('blue-600'),
|
|
438
|
+
bgHover: Color.hex('blue-700'),
|
|
439
|
+
text: Color.rgb('white'),
|
|
220
440
|
},
|
|
221
441
|
secondary: {
|
|
222
|
-
bg:
|
|
223
|
-
bgHover:
|
|
224
|
-
text:
|
|
442
|
+
bg: Color.hex('slate-600'),
|
|
443
|
+
bgHover: Color.hex('slate-700'),
|
|
444
|
+
text: Color.rgb('slate-100'),
|
|
225
445
|
},
|
|
226
446
|
danger: {
|
|
227
|
-
bg:
|
|
228
|
-
bgHover:
|
|
229
|
-
text:
|
|
447
|
+
bg: Color.hex('red-600'),
|
|
448
|
+
bgHover: Color.hex('red-700'),
|
|
449
|
+
text: Color.rgb('white'),
|
|
230
450
|
},
|
|
231
451
|
};
|
|
232
452
|
|
|
@@ -242,7 +462,7 @@ class GameButton {
|
|
|
242
462
|
// Text
|
|
243
463
|
this.text = scene.add
|
|
244
464
|
.text(x, y, text, {
|
|
245
|
-
fontSize:
|
|
465
|
+
fontSize: FontSize.css('lg'),
|
|
246
466
|
fill: style.text,
|
|
247
467
|
})
|
|
248
468
|
.setOrigin(0.5);
|
|
@@ -262,11 +482,11 @@ const quitButton = new GameButton(this, 400, 360, 'QUIT', 'danger');
|
|
|
262
482
|
this.add.particles(player.x, player.y, 'sparkle', {
|
|
263
483
|
speed: { min: 50, max: 100 },
|
|
264
484
|
tint: [
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
485
|
+
Color.hex('blue-400'),
|
|
486
|
+
Color.hex('blue-500'),
|
|
487
|
+
Color.hex('blue-600'),
|
|
488
|
+
Color.hex('cyan-400'),
|
|
489
|
+
Color.hex('cyan-500'),
|
|
270
490
|
],
|
|
271
491
|
lifespan: 1000,
|
|
272
492
|
});
|
|
@@ -279,7 +499,7 @@ this.add.particles(player.x, player.y, 'sparkle', {
|
|
|
279
499
|
### Scene Setup
|
|
280
500
|
|
|
281
501
|
```typescript
|
|
282
|
-
import {
|
|
502
|
+
import { Color, FontSize } from 'phaser-wind';
|
|
283
503
|
|
|
284
504
|
export class MenuScene extends Phaser.Scene {
|
|
285
505
|
constructor() {
|
|
@@ -290,10 +510,10 @@ export class MenuScene extends Phaser.Scene {
|
|
|
290
510
|
// Background gradient effect
|
|
291
511
|
const bg = this.add.graphics();
|
|
292
512
|
bg.fillGradientStyle(
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
513
|
+
Color.hex('slate-900'), // top-left
|
|
514
|
+
Color.hex('slate-800'), // top-right
|
|
515
|
+
Color.hex('slate-800'), // bottom-left
|
|
516
|
+
Color.hex('slate-700') // bottom-right
|
|
297
517
|
);
|
|
298
518
|
bg.fillRect(0, 0, this.cameras.main.width, this.cameras.main.height);
|
|
299
519
|
|
|
@@ -305,9 +525,9 @@ export class MenuScene extends Phaser.Scene {
|
|
|
305
525
|
private createTitle() {
|
|
306
526
|
this.add
|
|
307
527
|
.text(this.cameras.main.centerX, 150, 'MY AWESOME GAME', {
|
|
308
|
-
fontSize:
|
|
309
|
-
fill:
|
|
310
|
-
stroke:
|
|
528
|
+
fontSize: FontSize.css('4xl'),
|
|
529
|
+
fill: Color.rgb('yellow-400'),
|
|
530
|
+
stroke: Color.rgb('yellow-700'),
|
|
311
531
|
strokeThickness: 3,
|
|
312
532
|
})
|
|
313
533
|
.setOrigin(0.5);
|
|
@@ -319,13 +539,13 @@ export class MenuScene extends Phaser.Scene {
|
|
|
319
539
|
menuItems.forEach((item, index) => {
|
|
320
540
|
this.add
|
|
321
541
|
.text(this.cameras.main.centerX, 250 + index * 60, item, {
|
|
322
|
-
fontSize:
|
|
323
|
-
fill:
|
|
542
|
+
fontSize: FontSize.css('xl'),
|
|
543
|
+
fill: Color.rgb('slate-300'),
|
|
324
544
|
})
|
|
325
545
|
.setOrigin(0.5)
|
|
326
546
|
.setInteractive()
|
|
327
547
|
.on('pointerover', function () {
|
|
328
|
-
this.setTint(
|
|
548
|
+
this.setTint(Color.hex('yellow-400'));
|
|
329
549
|
})
|
|
330
550
|
.on('pointerout', function () {
|
|
331
551
|
this.clearTint();
|
|
@@ -344,21 +564,21 @@ export class MenuScene extends Phaser.Scene {
|
|
|
344
564
|
```typescript
|
|
345
565
|
// Create consistent themes
|
|
346
566
|
const darkTheme = {
|
|
347
|
-
background:
|
|
348
|
-
surface:
|
|
349
|
-
primary:
|
|
350
|
-
secondary:
|
|
351
|
-
text:
|
|
352
|
-
textMuted:
|
|
567
|
+
background: Color.hex('slate-900'),
|
|
568
|
+
surface: Color.hex('slate-800'),
|
|
569
|
+
primary: Color.hex('blue-500'),
|
|
570
|
+
secondary: Color.hex('slate-600'),
|
|
571
|
+
text: Color.rgb('slate-100'),
|
|
572
|
+
textMuted: Color.rgb('slate-400'),
|
|
353
573
|
};
|
|
354
574
|
|
|
355
575
|
const lightTheme = {
|
|
356
|
-
background:
|
|
357
|
-
surface:
|
|
358
|
-
primary:
|
|
359
|
-
secondary:
|
|
360
|
-
text:
|
|
361
|
-
textMuted:
|
|
576
|
+
background: Color.hex('slate-50'),
|
|
577
|
+
surface: Color.hex('white'),
|
|
578
|
+
primary: Color.hex('blue-600'),
|
|
579
|
+
secondary: Color.hex('slate-200'),
|
|
580
|
+
text: Color.rgb('slate-900'),
|
|
581
|
+
textMuted: Color.rgb('slate-600'),
|
|
362
582
|
};
|
|
363
583
|
```
|
|
364
584
|
|
|
@@ -368,13 +588,13 @@ const lightTheme = {
|
|
|
368
588
|
// Scale text based on screen size
|
|
369
589
|
const getResponsiveTextSize = (baseSize: FontSizeKey): string => {
|
|
370
590
|
const scale = this.cameras.main.width / 1920; // Base on 1920px width
|
|
371
|
-
const basePixels =
|
|
591
|
+
const basePixels = FontSize.px(baseSize);
|
|
372
592
|
return `${Math.round(basePixels * scale)}px`;
|
|
373
593
|
};
|
|
374
594
|
|
|
375
595
|
this.add.text(x, y, 'Responsive Text', {
|
|
376
596
|
fontSize: getResponsiveTextSize('2xl'),
|
|
377
|
-
fill:
|
|
597
|
+
fill: Color.rgb('blue-500'),
|
|
378
598
|
});
|
|
379
599
|
```
|
|
380
600
|
|
|
@@ -394,24 +614,26 @@ Plus, `phaser-wind` is way easier to type than `phaser-tailwind-css-design-token
|
|
|
394
614
|
|
|
395
615
|
## 📚 Compared to Raw Phaser
|
|
396
616
|
|
|
397
|
-
| Without Phaser Wind | With Phaser Wind
|
|
398
|
-
| ------------------------ |
|
|
399
|
-
| `fill: '#3B82F6'` | `fill:
|
|
400
|
-
| `fontSize: '18px'` | `fontSize:
|
|
401
|
-
| `tint: 0x4ADE80` | `tint:
|
|
402
|
-
|
|
|
403
|
-
|
|
|
404
|
-
|
|
|
617
|
+
| Without Phaser Wind | With Phaser Wind |
|
|
618
|
+
| ------------------------ | ------------------------------- |
|
|
619
|
+
| `fill: '#3B82F6'` | `fill: Color.rgb('primary')` |
|
|
620
|
+
| `fontSize: '18px'` | `fontSize: FontSize.css('lg')` |
|
|
621
|
+
| `tint: 0x4ADE80` | `tint: Color.hex('success')` |
|
|
622
|
+
| `fontFamily: 'Arial'` | `fontFamily: Font.family('ui')` |
|
|
623
|
+
| Magic numbers everywhere | Semantic, consistent tokens |
|
|
624
|
+
| Color picking hell | Harmonious color palettes |
|
|
625
|
+
| Inconsistent sizing | Perfect typography scale |
|
|
626
|
+
| No design system | Complete theme architecture |
|
|
405
627
|
|
|
406
628
|
---
|
|
407
629
|
|
|
408
630
|
## 🔮 Coming Soon
|
|
409
631
|
|
|
410
|
-
- 🎯 **Spacing System** - Consistent margins and padding tokens
|
|
411
632
|
- 📐 **Layout Utilities** - Flexbox-inspired alignment helpers
|
|
412
|
-
- 🎨 **Theme System** - Easy dark/light mode switching
|
|
413
633
|
- 📱 **Responsive Utilities** - Breakpoint-based design tokens
|
|
414
634
|
- ⚡ **Animation Presets** - Smooth, consistent transitions
|
|
635
|
+
- 🎮 **Component Library** - Pre-built Phaser components with theme support
|
|
636
|
+
- 🔧 **CLI Tool** - Generate themes and components from the command line
|
|
415
637
|
|
|
416
638
|
---
|
|
417
639
|
|