Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Needs Fewer Pixels - Building A JavaScript Retro Game Engine

Needs Fewer Pixels - Building A JavaScript Retro Game Engine

From my talk at NIDenConf 2017. Non-interactive - demos and engine code will be available in the near future at github.com/njmcode.

As a grizzled old 8-bit fan and staunch supporter of the Web, our protagonist finds himself in a creative and ideological pickle: how can he stop sucking at game dev and enjoy some old-school fun, while still JavaScripting All The Things™ like he knows he should?

Fed up with crashing and burning while writing JavaScript at game jam events every couple of months, our intrepid hero attempts to solve the problem the only way he knows how: writing more JavaScript. The result is the JS-powered, retrogame-tailored, ‘virtual fantasy console’ of his dreams… and nightmares!

How will it all unfold? Will our man break the cycle of failure and ride his low-res, 16-colour, minimal-API vision to victory? Or will he and his abomination be destined to rot amongst the rest of his half-finished GitHub repos? Tune in to find out!

Neil McCallion

June 10, 2017
Tweet

More Decks by Neil McCallion

Other Decks in Programming

Transcript

  1. THE 'ABOUT ME' BIT NEIL McCALLION Senior UI Developer @

    Moola Co-organizer @ BelfastJS njmcode.github.io
  2. THINGS I WANT From A Retro Game Engine / Fantasy

    Console ♥ JavaScript ♥ Limited features / capability Creatively inspiring Easy to work with Retro aesthetics Good performance
  3. NON-INTERACTIVE SLIDES - DEMO UNAVAILABLE N-GINE™ JS-powered 128 x 128

    px 16 colors, 2 fonts 2-button D-pad controls (keys) ~40 FPS Minimal core API
  4. WHAT MAKES A GAME? INPUT EVENTS - KEYBOARD - MOUSE

    - TOUCH GAMEPAD API GYRO / ACCEL + FEEDBACK HTML5 CANVAS WEB AUDIO API + TIME DATE.NOW()
  5. API DESIGN addimg blit button cls color cursor font img

    line plot rect rectf circle circlef rnd text screen start ... const { color, cursor, font, rect, rnd, text } = ngine /* ... */ function render () { cursor(20, 20) color(3) font(1) text('Hello there') rect(20, 50, rnd(2, 8)) }
  6. GAME LOOP // myGame.js ngine.start({ init() { // runs after

    bootup }, update(t) { // input, movement, etc }, render(t) { // draw scene }, }) // ngine.core.js const frameTime = 1000 / 40 let lt = 0 function _frame() { requestAnimationFrame(_frame) const ct = Date.now() if (ct - lt > frameTime) { _update(ct) _render(ct) lt = ct } }
  7. CANVAS ABSTRACTION // HTML5 Canvas ctx.beginPath() ctx.arc(x, y, rad, 0,

    2 * Math.PI, false) ctx.strokeStyle = 'white' ctx.stroke() ctx.fillRect(x, y, w, h) // ngine color(15) circ(x, y, rad) rectf(x, y, w) // h = w PALETTE + FONTS PICO-8 MONO UPPER Press Start P2
  8. CSS SCALING + CANVAS SUB-PIXEL RENDERING NON-INTERACTIVE SLIDES - DEMO

    UNAVAILABLE .ngine-screen { image-rendering: pixelated; } // game.js plot(20.3, 10.75) // ngine.core.js ngine.plot = (x, y) => { x = round(x) y = round(y) // ...draw pixel }
  9. HANDLING IMAGE DATA // game.js function init() { // id,

    data, w, h addimg('ship', [/* data */], 48, 24) } function render(t) { // id, screen x/y, clip x/y img('ship', /* params */) }
  10. CONTROLS // game.js function update(t) { if (button(0)) { player.y

    -= player.speed } if (button(4)) { player.shoot(t) } // etc. } 0 - up 1 - down 2 - left 3 - right 4 - but1 (z) 5 - but2 (x) 6 - start (Enter)
  11. COLLISIONS // game.js // Ball = { x, y, width,

    height, ... } // bricks = [{ ... }, { ... }, { ... }] collide(Ball, bricks, function (ballObj, brickObj) { // destroy brickObj // bounce ball // increase score }) collide(Ball, Bat, function (ballObj, batObj) { // bounce ball })
  12. QUICK PERFORMANCE WINS // Bitwise floor, ceil & round e.g.

    ngine.floor = n => n << 0 // Object pools const Pool = { /* ... */ getNext() { return entities.find(p => !p.alive) }, createEntity(opts) { const newEntity = this.getNext() // init entity if available, // fail or re-use old one if not } }
  13. FUTURE PLANS Go public sound() + music() Editing tools Perf

    boosts (WebGL?) Custom hardware? ... ...make games
  14. FUN