Build a Game in Ember Starring Your Cat

Build a Game in Ember Starring Your Cat

Ember is generally used to build ambitious web applications, but what about ambitious web games starring your cat? In this talk, I'll go over how to use Ember to build, organize, and deploy HTML5-canvas based games.

Using Ember to develop games shares the same benefits of using Ember to develop applications—both the toolchain and the conventions alleviate decision fatigue. For example, route-driven paths are great at handling levels, Liquid Fire provides lovely transitions for menus, and adapters provide a standard way to connect to backends for saving high scores.

Fbf1757de2e4b442a65273b6d0469dbd?s=128

Matt McKenna

March 30, 2016
Tweet

Transcript

  1. Build a Game in Ember Starring Your Cat Emberconf March

    30, 2016 1 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > https://speakerdeck.com/mtmckenna/build-a-game-in-ember-starring-your-cat matt@mtmckenna.com @mattmckenna
  2. Why Build a Game in JS? • Haven't you always

    wanted to make a game? • You probably already know JS, so you can get started right away. • JS apps are relatively easy to deploy. • JS apps work on all devices (hahahahahaha). 2 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Croissant!
  3. But Why Build a Game in Ember? 3 > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Incredulous Croissant!
  4. You Are Special You are my friend You are special

    You are my friend You're special to me. You are the only one like you. Like you, my friend, I like you. 4 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > https://commons.wikimedia.org/wiki/File:Fred_Rogers,_late_1960s.jpg
  5. Your JS App Is Probably Less Special 5 > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thing Your JS App Needs Ember's Way of Handling that Need An asset pipeline ember-cli Remotely persisted data adapters / emberfire App state maintained between routes services tests ember-qunit, ember-cli-mirage a deploy and rollback strategy ember-cli-deploy • Even if your JS app seems unique, it probably still needs...
  6. Let Ember Handle the Boring Parts 6 > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > • It may feel like your app requires freedom from Ember and its conventions, but... • "With freedom comes responsibility maintenance."- Eleanor Roosevelt • How bad do you want to maintain that glue code?
  7. The Boring Parts of Game Development 7 > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > • The non-game UI (e.g. menus, scores, etc.) • Testing • Deploying to the web, mobile, and desktop environments.
  8. Croissant -- this is you! Pizzas -- touch these for

    points! Cat beds -- jump to avoid these! 8 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > • Here's a screenshot of a game made in JavaScript, starring Croissant: Croissant the Pizza Cat
  9. Croissant the Pizza Cat • Let's play real quick! •

    https://www.CroissantThePizzaCat.com • https://github.com/mtmckenna/croissant-runner-ember 9 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
  10. 10 > > > > > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Building Game Menus in Ember
  11. Menus through Routes 11 > > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Router.map(function() { this.route('play', { path: 'play/:level_id' }, function() { this.route('menu', function() { this.route('hi-scores'); }); }); }); /# /#/play/1 /#/play/1/menu /#/play/1/menu/hi-scores
  12. Nested Templates in Ember 12 > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > • In Ember, templates are rendered into the parent route's template's {{outlet}}. <div class='game-menu'> {{outlet}} </div> play/menu/template.hbs: ... <span class='game-menu__header'>LATEST HI SCORES</span> <table class='hi-scores-table'> {{sorted-scores scores=model}} </table> play/menu/hi-scores/template.hbs:
  13. Animating Full Screen Menus 1/2 13 > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > • Use liquid-fire to create full screen animated menus. .liquid-container--full-screen { position: absolute; height: 100%; width: 100%; top: 0; left: 0; } .liquid-container--full-screen .liquid-child { height: 100%; width: 100%; overflow-y: auto; } {{liquid-outlet class='liquid-container--full-screen'}} app.scss: *.hbs:
  14. Animating Full Screen Menus 2/2 14 > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > • Use liquid-fire to create full screen animated menus. transitions.js: ... this.transition( this.fromRoute('play.menu.index'), this.toRoute(function(routeName){ return /^play\.menu/.test(routeName); }), this.use('toLeft'), this.reverse('toRight') ); ...
  15. Pausing the Game 15 > > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > /#/play/1 Play Pause /#/play/1/menu
  16. The Game Loop 16 > > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > gameLoop() { this.animReq = window.requestAnimationFrame(this.gameLoop.bind(this)); this.update(); this.draw(); } • The game loop... • ... calculates the position of sprites (Croissant, pizzas, etc.). • ... draws the sprites to the screen. What's this thing? Find out on the next slide!
  17. requestAnimationFrame • Supported in modern browsers. • Calls the gameLoop

    function when the browser is ready to repaint the screen. • The browser will attempt to call gameLoop 60 times a second (i.e. 60 FPS). No promises though. • requestAnimationFrame is better than setInterval. 17 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
  18. The Game Service 18 > > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > • Services are long-lived JS objects that can maintain state between routes. • The game loop and logic can live in this service so the game will maintain its state even when transitioning into the menu route. • The game service can be used to play and pause the game. $ ember generate service game ... installing service create app/game/service.js installing service-test create tests/unit/game/service-test.js
  19. /game/service.js 19 > > > > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ... gameLoop() { this.animReq = window.requestAnimationFrame(this.gameLoop.bind(this)); this.update(); this.draw(); }, play() { this.paused = false; this.gameLoop(); this.addEventListeners(); }, pause() { this.paused = true; window.cancelAnimationFrame(this.animReq); this.animReq = null; this.removeEventListeners(); }, ...
  20. Playing and Pausing the Game 20 > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > export default Ember.Route.extend({ game: Ember.inject.service(), pauseGame: function(){ this.get('game').pause(); }.on('activate'), playGame: function(){ this.get('game').play(); }.on('deactivate') }); play/menu/route.js:
  21. Testing the Game in Ember 21 > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
  22. UI/Menu Component Tests 22 > > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > test('toggle audio', function(assert) { this.render(hbs`{{game-menu}}`); $('div:contains("AUDIO OFF")').click(); assert.notEqual(this.$().text().indexOf('AUDIO ON'), -1); $('div:contains("AUDIO ON")').click(); assert.notEqual(this.$().text().indexOf('AUDIO OFF'), -1); }); • Test UI components as you would any Ember component. tests/integration/components/game-menu/component-test.js:
  23. Acceptance Testing the Game Mechanics 23 > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > test('touching pizzas means points', function(assert) { visit('/play/1'); andThen(function() { assert.equal(currentURL(), '/play/1'); var pizzaCount = parseInt($('.js-pizza-count').text()); assert.equal(pizzaCount, 0); spewPizzasLikeCrazy(); var done = assert.async(); Ember.run.later(function() { pizzaCount = parseInt($('.js-pizza-count').text()); assert.ok(pizzaCount > 0); done(); }, 1000); }); }); What does this test helper do? Find out on the next slide!
  24. 24 > > > > > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > export default Ember.Test.registerHelper('spewPizzasLikeCrazy', function(app) { var game = app.__container__.lookup('service:game'); game.spriteEmitter.emitSprites = function() { if (!game.spriteEmitter.shouldCreateSprite(5)) { return; } var pizza = new Pizza(this.context, 200, -10.0); this.sprites.push(pizza); }; }); spewPizzasLikeCrazy Test Helper Pizzas all lined up No cat beds Croissant moves fast
  25. Deploying the Game with Ember 25 > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Web Mobile Desktop
  26. Deploying to the Web 26 > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > • ember-cli-deploy provides a supported way to deploy and rollback revisions. $ ember deploy production ... - ✔ index.html:d8608b8abdc7dd4f7f622a058e3ecd97 => index.html
  27. Deploying to Mobile and Desktop Apps 27 > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > • Building Mobile Applications with Ember
 by Alex Blom (@alexblom) • ember-cli-cordova • Building Desktop Apps with Ember and Electron 
 by Felix Rieseberg (@felixrieseberg) • ember-electron
  28. Croissant on Mobile and Desktop 28 > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > • iOS • Android • Mac OS X
  29. Takeaways • Let Ember handle the boring parts: • Build

    your game's UI • House your game logic in a service • Test game mechanics in acceptance tests • Deploy to the web and mobile/desktop environments using addons 29 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
  30. Links • https://developer.mozilla.org/en-US/docs/Games • http://ludumdare.com/compo/tools/ 30 > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
  31. Graphics/Audio Tools • Dots (iOS) • Pixen (OS X) •

    Pixelmator (OS X) • bfxr (web) • Audacity (OS X / Windows) 31 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
  32. Croissant Stickers 32 > > > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
  33. Thank You! 33 > > > > > > >

    > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >