retro-pong-game 1.1.3 → 3.0.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 CHANGED
@@ -4,7 +4,7 @@ A retro-style Pong game that runs in any browser. Drop it onto your website with
4
4
 
5
5
  **[Live demo](https://chriscreativecode.com/retro-pong-game/)**
6
6
 
7
- ![retro-pong-game screenshot](https://chriscreativecode.com/retro-pong-game/retro-pong-game-screenshot.png)
7
+ ![retro-pong-game screenshot](https://chriscreativecode.com/retro-pong-game/retro-pong-game-screenshot.png?v=3)
8
8
 
9
9
  - Animated starfield or nebular background
10
10
  - Particle effects on paddle hits
@@ -37,9 +37,28 @@ The game appends a `<canvas>` inside this element automatically.
37
37
 
38
38
  ### 2. Import and create the game
39
39
 
40
+ **New to this package?** Start with `isAdmin: true` to configure everything visually first:
41
+
40
42
  ```js
41
43
  import { PongGame } from 'retro-pong-game';
42
44
 
45
+ const game = new PongGame({ isAdmin: true }, '#game');
46
+ ```
47
+
48
+ Open the settings panel (gear icon), adjust colors, sizes, and speeds live, then click **Copy** at the bottom to export your config as JSON. Paste it into your constructor and remove `isAdmin`:
49
+
50
+ ```js
51
+ const game = new PongGame(
52
+ {
53
+ /* paste your copied config here */
54
+ },
55
+ '#game'
56
+ );
57
+ ```
58
+
59
+ If you already know your config, pass it directly:
60
+
61
+ ```js
43
62
  const game = new PongGame(
44
63
  {
45
64
  canvasWidth: 600,
@@ -55,9 +74,9 @@ const game = new PongGame(
55
74
  );
56
75
  ```
57
76
 
58
- ### 3. Clean up when done
77
+ ### 3. Clean up
59
78
 
60
- Always call `destroy()` before removing the element from the page:
79
+ Call `destroy()` before removing the element from the page:
61
80
 
62
81
  ```js
63
82
  game.destroy();
@@ -225,17 +244,19 @@ The config is deep-merged in this order (later layers win):
225
244
  |---|---|---|---|
226
245
  | `autoSize` | `boolean` | `false` | Size the canvas to fill its container element at startup |
227
246
  | `autoResize` | `boolean` | `false` | Automatically resize the canvas when the container changes size (uses `ResizeObserver`) |
228
- | `canvasWidth` | `number` | `400` | Canvas width in px ignored when `autoSize` is `true` |
229
- | `canvasHeight` | `number` | `300` | Canvas height in px ignored when `autoSize` is `true` |
247
+ | `canvasWidth` | `number` | `400` | Canvas width in px (ignored when `autoSize` is true) |
248
+ | `canvasHeight` | `number` | `300` | Canvas height in px (ignored when `autoSize` is true) |
230
249
  | `paddleWidth` | `number` | `70` | Paddle width in px |
231
250
  | `paddleHeight` | `number` | `10` | Paddle height in px |
232
251
  | `ballDiameter` | `number` | `7` | Ball diameter in px |
233
252
  | `ballSpeed` | `number` | `3` | Starting ball speed (px per frame) |
234
253
  | `paddleMoveStep` | `number` | `4` | Paddle speed while an arrow key is held (px per frame) |
235
- | `difficultyLevel` | `number` | `1` | Starting AI difficulty higher = faster and more precise |
254
+ | `difficultyLevel` | `number` | `1` | Starting AI difficulty; higher = faster and more precise AI |
236
255
  | `particleBounce` | `boolean` | `true` | Particle burst when the ball hits a paddle |
237
256
  | `hasSound` | `boolean` | `false` | Enable sound effects |
238
- | `onSoundToggle` | `(enabled: boolean) => void` | | Called when the player toggles the sound icon |
257
+ | `showSettings` | `boolean` | `true` | Show the gear icon that opens the in-game settings panel. Set to `false` to lock the settings from players |
258
+ | `isAdmin` | `boolean` | `false` | Unlock difficulty and timing controls in the settings panel, plus a JSON export of the current config (see [Admin mode](#admin-mode)) |
259
+ | `onSoundToggle` | `(enabled: boolean) => void` | - | Called when the player toggles the sound icon |
239
260
  | `timer` | [`TimerConfig`](#timerconfig) | see below | Countdown timer settings |
240
261
  | `colors` | [`ColorConfig`](#colorconfig) | see below | Colors for game elements |
241
262
  | `animatedBackground` | [`AnimatedBackgroundConfig`](#animatedbackgroundconfig) | see below | Background animation |
@@ -349,16 +370,42 @@ The player controls the **bottom** paddle. The **top** paddle is the AI opponent
349
370
 
350
371
  ## Settings panel
351
372
 
352
- The game includes a built-in settings panel (gear icon in the corner of the canvas). Players can change colors, background effects, difficulty, timer duration, and more. All changes are saved to `localStorage` and restored automatically on the next visit.
373
+ The game includes a built-in settings panel (gear icon in the corner of the canvas). Players can change colors, background effects, and particle settings. All changes are saved to `localStorage` and restored automatically on the next visit.
353
374
 
354
375
  To reset all saved settings back to defaults:
355
376
 
356
377
  ```js
357
- localStorage.removeItem('chriscreativecode.com');
378
+ localStorage.removeItem('chriscreativecode.com-retro-pong-game');
358
379
  ```
359
380
 
360
381
  ---
361
382
 
383
+ ## Admin mode
384
+
385
+ `isAdmin: true` is the recommended starting point when you are setting up the game for the first time. It unlocks the full settings panel so you can configure everything visually before committing to a config object.
386
+
387
+ ```js
388
+ const game = new PongGame({ isAdmin: true }, '#game');
389
+ ```
390
+
391
+ **Workflow:**
392
+
393
+ 1. Start the game with `isAdmin: true`
394
+ 2. Open the settings panel (gear icon) — you will see all configurable fields including sizes, speeds, colors, timer, and difficulty
395
+ 3. Adjust the values and watch the changes live
396
+ 4. Scroll to the bottom of the panel and click **Copy** to copy the full config as JSON
397
+ 5. Paste the JSON into your constructor and remove `isAdmin`
398
+
399
+ In admin mode the settings panel exposes:
400
+
401
+ - **Difficulty fields** — `ballSpeed`, `paddleMoveStep`, `paddleWidth`, `paddleHeight`, `ballDiameter`, `difficultyLevel`
402
+ - **Timer duration** — `timer.duration` (changing match length affects scoring opportunities)
403
+ - **Config JSON export** — a read-only textarea at the bottom of the panel showing the full current config as JSON, with a **Copy** button
404
+
405
+ Without `isAdmin`, these fields are hidden from players so they cannot alter the game balance. Do not ship `isAdmin: true` to end users.
406
+
407
+ ---
408
+
362
409
  ## Resize handling
363
410
 
364
411
  ### Automatic (recommended)
@@ -105,6 +105,21 @@ export interface PongGameConfig {
105
105
  hasSound?: boolean;
106
106
  /** Called whenever the player toggles sound on or off via the in-game icon. */
107
107
  onSoundToggle?: (enabled: boolean) => void;
108
+ /**
109
+ * Show the settings gear button that lets players open the in-game settings panel.
110
+ * Set to `false` to hide it and prevent players from changing game settings.
111
+ * The sound icon repositions to the right edge when this is `false`.
112
+ * Default: `true`
113
+ */
114
+ showSettings?: boolean;
115
+ /**
116
+ * When `true`, the settings panel also shows difficulty-related fields
117
+ * (`ballSpeed`, `paddleMoveStep`, `paddleWidth`, `paddleHeight`, `ballDiameter`,
118
+ * `difficultyLevel`) and a JSON export of the current config.
119
+ * Intended for developers/integrators — set in the constructor config, not by end users.
120
+ * Default: `false`
121
+ */
122
+ isAdmin?: boolean;
108
123
  }
109
124
 
110
125
  /**