punter.js 1.0.1 → 1.1.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
@@ -14,7 +14,7 @@ A simple, dependency-free 2D game engine for the browser. No build step, no fram
14
14
  - [Install](#install)
15
15
  - [Run the Example](#run-the-example)
16
16
  - [How it Works](#how-it-works)
17
- - [punter.init()](#punter-init)
17
+ - [Setup](#setup)
18
18
  - [Scenes](#scenes)
19
19
  - [Events](#events)
20
20
  - [Sprites](#sprites)
@@ -61,15 +61,15 @@ Then open **http://localhost:3000/games/pong.html** in your browser.
61
61
 
62
62
  Every punter.js game follows the same three-step pattern:
63
63
 
64
- 1. **init** - specify which canvas to use and which images/sounds to preload
64
+ 1. **setup** - specify which canvas to use and which images/sounds to preload
65
65
  2. **scene** - define a named scene (level, menu, etc.) with update/draw logic
66
66
  3. **ready** - switch to a scene once everything has loaded
67
67
 
68
68
  ```js
69
69
  // 1. Load assets
70
- punter.init({
70
+ punter.setup({
71
71
  canvas: '#game',
72
- sprites: { player: 'images/player.png' },
72
+ images: { player: 'images/player.png' },
73
73
  sounds: { jump: 'sounds/jump.mp3' }
74
74
  });
75
75
 
@@ -96,15 +96,15 @@ punter.on('ready', function () {
96
96
  });
97
97
  ```
98
98
 
99
- ## `punter.init()`
99
+ ## Setup
100
100
 
101
101
  Call this once at the start. The `ready` event fires once all assets have loaded.
102
102
 
103
103
  ```js
104
- punter.init({
104
+ punter.setup({
105
105
  canvas: '#game', // CSS selector or HTMLCanvasElement
106
106
  debug: false, // true = show FPS and bounding boxes
107
- sprites: {
107
+ images: {
108
108
  player: 'images/player.png',
109
109
  coin: 'images/coin.png'
110
110
  },
@@ -117,7 +117,7 @@ punter.init({
117
117
  Option | Required | Description
118
118
  ----------|----------|------------------------------------------------
119
119
  `canvas` | Yes | CSS selector (`'#game'`) or `HTMLCanvasElement`
120
- `sprites` | No | Key/path pairs of images to preload
120
+ `images` | No | Key/path pairs of images to preload
121
121
  `sounds` | No | Key/path pairs of audio files to preload
122
122
  `debug` | No | Enables the debug overlay. Default: `false`
123
123
 
@@ -179,7 +179,7 @@ var player = punter.createSprite({
179
179
  Option | Default | Description
180
180
  -----------------|------------|----------------------------------------------------------------------------------------------------
181
181
  `id` | - | **Required.** Unique name for this sprite.
182
- `key` | - | **Required.** Image key from `config.sprites`. Pass an array (`['frame1','frame2']`) for animation.
182
+ `key` | - | **Required.** Image key from `config.images`. Pass an array (`['frame1','frame2']`) for animation.
183
183
  `x` | - | **Required.** Horizontal position in pixels or `'50%'`.
184
184
  `y` | - | **Required.** Vertical position in pixels or `'50%'`.
185
185
  `w` | auto | Width in pixels or percent. Inferred from the image if omitted.
@@ -294,7 +294,7 @@ punter.on('update', function () {
294
294
  ## Sound
295
295
 
296
296
  ```js
297
- punter.init({
297
+ punter.setup({
298
298
  sounds: { jump: 'sounds/jump.mp3', music: 'sounds/theme.mp3' }
299
299
  });
300
300
 
@@ -419,7 +419,7 @@ html:not([data-punter-loading]) #loader { display: none; }
419
419
  ## Debug Mode
420
420
 
421
421
  ```js
422
- punter.init({ canvas: '#game', debug: true }); // enable at startup
422
+ punter.setup({ canvas: '#game', debug: true }); // enable at startup
423
423
  punter.debug = true; // or toggle at runtime
424
424
  ```
425
425
 
package/games/pong.html CHANGED
@@ -1,13 +1,26 @@
1
1
  <!doctype html>
2
2
  <html>
3
3
  <head>
4
+ <title>Pong</title>
4
5
  <meta charset="utf-8">
5
6
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>Pong</title>
7
7
  <style>
8
- * { margin: 0; padding: 0; box-sizing: border-box; }
9
- html, body { width: 100%; height: 100%; background: #1e2230; overflow: hidden; }
10
- canvas { display: block; }
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ html, body {
15
+ width: 100%;
16
+ height: 100%;
17
+ background: #1e2230;
18
+ overflow: hidden;
19
+ }
20
+
21
+ canvas {
22
+ display: block;
23
+ }
11
24
  </style>
12
25
  <script src="../punter.js"></script>
13
26
  </head>
@@ -80,9 +93,9 @@
80
93
  // SETUP
81
94
  // Load the two sprite images before the game starts.
82
95
  // =========================================================
83
- punter.init({
96
+ punter.setup({
84
97
  canvas: '#game',
85
- sprites: {
98
+ images: {
86
99
  paddle: '../images/pong/sprites/paddle.png',
87
100
  ball: '../images/pong/sprites/ball.png'
88
101
  }
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "punter.js",
3
- "version": "1.0.1",
4
- "description": "A lightweight, dependency-free JavaScript 2D game engine for the browser. Drop in a script tag and start building.",
3
+ "version": "1.1.0",
4
+ "description": "A simple, dependency-free 2D game engine for the browser. No build step, no frameworks - just one script tag.",
5
5
  "main": "punter.js",
6
6
  "directories": {
7
7
  "test": "tests"
8
8
  },
9
9
  "scripts": {
10
10
  "start": "npx serve .",
11
+ "start:pong": "npx serve . -l 4000 & npx open-cli http://localhost:4000/games/pong.html",
11
12
  "test": ". \"$NVM_DIR/nvm.sh\" && nvm use && NODE_ENV=test TZ=UTC node_modules/.bin/jasmine --config=tests/jasmine/config.json"
12
13
  },
13
14
  "repository": {
package/punter.js CHANGED
@@ -106,11 +106,11 @@
106
106
  })();
107
107
 
108
108
  /**
109
- * Initialises the engine with canvas, sprites, sounds, and buttons
109
+ * Initialises the engine with canvas, images, sounds, and buttons
110
110
  * @param {Object} config - configuration object
111
111
  * @returns {void}
112
112
  */
113
- function init(config) {
113
+ function setup(config) {
114
114
 
115
115
  config = config || {};
116
116
 
@@ -151,11 +151,11 @@
151
151
  _boundsCanvas = document.createElement('canvas');
152
152
  _boundsCtx = _boundsCanvas.getContext('2d', { willReadFrequently: true });
153
153
 
154
- loadSprites(config.sprites || {}).then(function() {
154
+ loadImages(config.images || {}).then(function() {
155
155
 
156
156
  // precompute bounds for all sprite frames
157
- if (config.sprites) {
158
- for (var key in config.sprites) {
157
+ if (config.images) {
158
+ for (var key in config.images) {
159
159
  var img = images[key];
160
160
  if (img && img.complete && img.naturalWidth) {
161
161
  // this warms up the boundingCache
@@ -182,13 +182,13 @@
182
182
  }
183
183
 
184
184
  /**
185
- * Loads and decodes all sprite images
186
- * @param {Object} sprites - Key-value map of sprite keys to image URLs
185
+ * Loads and decodes all images
186
+ * @param {Object} images - Key-value map of image keys to image URLs
187
187
  * @returns {Promise} - Resolves when all images are loaded and decoded
188
188
  */
189
- function loadSprites(sprites) {
189
+ function loadImages(imageMap) {
190
190
 
191
- var keys = Object.keys(sprites);
191
+ var keys = Object.keys(imageMap);
192
192
  var total = keys.length;
193
193
 
194
194
  if (!total) return Promise.resolve();
@@ -234,7 +234,7 @@
234
234
 
235
235
  for (var i = 0; i < total; i++) {
236
236
  var key = keys[i];
237
- var url = sprites[key];
237
+ var url = imageMap[key];
238
238
  var img = new Image();
239
239
  img.key = key; // for debugging
240
240
  img.onload = handleLoad.bind(img, key);
@@ -1003,7 +1003,7 @@
1003
1003
  */
1004
1004
  function startLoop() {
1005
1005
 
1006
- if (!_initilised) throw new Error('punter.init must be called first');
1006
+ if (!_initilised) throw new Error('punter.setup must be called first');
1007
1007
 
1008
1008
  _canvasCtx = _canvas.getContext('2d', { alpha: true, desynchronized: true });
1009
1009
  _canvasCtx.imageSmoothingEnabled = false;
@@ -1067,7 +1067,7 @@
1067
1067
 
1068
1068
  function pauseLoop() {
1069
1069
 
1070
- if (!_initilised) throw new Error('punter.init must be called first');
1070
+ if (!_initilised) throw new Error('punter.setup must be called first');
1071
1071
 
1072
1072
  if (_loopId !== null) {
1073
1073
  cancelAnimationFrame(_loopId);
@@ -1090,7 +1090,7 @@
1090
1090
  */
1091
1091
  function playSound(name, options) {
1092
1092
 
1093
- if (!_initilised) throw new Error('punter.init must be called first');
1093
+ if (!_initilised) throw new Error('punter.setup must be called first');
1094
1094
 
1095
1095
  var buffer = sounds[name];
1096
1096
  if (!buffer) return;
@@ -1131,7 +1131,7 @@
1131
1131
 
1132
1132
  function stopSound(name) {
1133
1133
 
1134
- if (!_initilised) throw new Error('punter.init must be called first');
1134
+ if (!_initilised) throw new Error('punter.setup must be called first');
1135
1135
 
1136
1136
  var arr = playingSounds[name];
1137
1137
  if (!arr || !arr.length) return;
@@ -1296,7 +1296,7 @@
1296
1296
  var api = {
1297
1297
 
1298
1298
  // initialization
1299
- init: init,
1299
+ setup: setup,
1300
1300
 
1301
1301
  // scene lifecycle
1302
1302
  scene: function (name, handler) {
@@ -1304,7 +1304,7 @@
1304
1304
  },
1305
1305
  go: function (name) {
1306
1306
 
1307
- if (!_initilised) throw new Error('punter.init must be called first');
1307
+ if (!_initilised) throw new Error('punter.setup must be called first');
1308
1308
  if (!_scenes[name]) throw new Error('punter.go: unknown scene "' + name + '"');
1309
1309
 
1310
1310
  // remove existing game loop handlers
@@ -1355,7 +1355,7 @@
1355
1355
 
1356
1356
  // sprite factory
1357
1357
  createSprite: function(opts) {
1358
- if (!_initilised) throw new Error('createSprite: punter.init must be called first');
1358
+ if (!_initilised) throw new Error('createSprite: punter.setup must be called first');
1359
1359
  return new Sprite(opts);
1360
1360
  },
1361
1361
  getSprite: function(id) {
@@ -20,9 +20,9 @@
20
20
  window.__ready = true;
21
21
  });
22
22
 
23
- punter.init({
23
+ punter.setup({
24
24
  canvas: '#game',
25
- sprites: { hero: heroImg },
25
+ images: { hero: heroImg },
26
26
  sounds: { beep: '/tests/fixtures/silence.wav' }
27
27
  });
28
28
  </script>
@@ -19,7 +19,7 @@ describe('Interface', function () {
19
19
  it('exposes the expected methods', async function () {
20
20
  var result = await page.evaluate(function () {
21
21
  return {
22
- init: typeof punter.init,
22
+ setup: typeof punter.setup,
23
23
  scene: typeof punter.scene,
24
24
  go: typeof punter.go,
25
25
  on: typeof punter.on,