BlicblockJS

Building a Game with AngularJS

How is it built?

Client-side game:

  • AngularJS
  • Yeoman
  • Bower

Server-side API:

  • Ruby on Rails
  • PostgreSQL

AngularJS Setup

Controllers

  • MainCtrl with game loop
  • ScoresCtrl with scoreboard
  • NotificationsCtrl

Services

  • Tetromino
  • Notifications
  • Config
  • Score

Directives

  • ngLeft
  • ngDown
  • ngRight
  • ngSpace

Models

  • Block

What's a service?

  • https://docs.angularjs.org/guide/services
  • Singleton: only one instance in the whole app
  • e.g., Tetromino service for game state:
    • Current score
    • Tick length for game loop
    • Has the user submitted their score for this game yet?
    • Is the game in progress?
    • Is the game over?
    • Is any block sliding or plummetting?

What's a directive?

  • https://docs.angularjs.org/guide/directive
  • Attach functionality to an HTML element
  • e.g., ngLeft:
    • ngLeft defined to listen for keypresses of a and
    • Add ng-left="neat_js()" to an HTML element
      When triggered, it will call neat_js()
    • ng-left on <body> in BlicblockJS
      How user is able to slide blocks left

What's happening??

  • game_loop() talks to Tetromino service to drop blocks, remove tetrominos, increment score
  • $interval used to run game_loop() every few ms
    https://docs.angularjs.org/api/ng/service/$interval
  • Tetromino holds logic for detecting tetrominos, dropping blocks, looking for nearby blocks
  • MainCtrl handles events like pause, resume, move active block, submit score

How are the blocks drawn?

AngularJS loop in HTML:

<div ng-repeat="block in blocks" ng-id="{{block.id}}" class="animate block {{block.color}} pos-{{block.x}}{{block.y}}"></div>

Loop in SCSS:

@for $x from 0 through $rows {
  @for $y from 0 through $columns {
    &.pos-#{$x}#{$y} {
      left: $block-width * $y;
      top: $block-height * $x; } } }

How do the blocks move?

  • AngularJS notices when your stuff changes
  • So, change x or y position on an instance of Block model...
    And its class attribute changes in HTML
  • e.g., pos-0-1 becomes pos-1-1
  • So different CSS applies
  • Use CSS3 transitions to make block smoothly slide around

How does scoring work?

  • A block falls into place
  • Tetromino service loops through blocks, looking for tetrominos
  • Remove tetromino, increment score by 1,000
  • Level incremented every 4,000 points
  • Tick length reduced by a percentage every level increase
  • Shorter tick length = faster falling blocks

What does Rails do?

  • Rails app = REST API
  • Game over in client side, show user a form to submit their score
  • Score service is a resource for talking to REST API
    https://docs.angularjs.org/api/ngResource/service/$resource
  • POST to create new score via Score service
  • Rails saves user's IP address, initials, score, date
  • ScoresCtrl users Score service to get a list of top scores from Rails

How is it deployed?

  • Heroku Rails app with PostgreSQL
  • Grunt builds client-side app, puts in Rails public/
  • Rails production serves static assets
  • Compiled public/ stored in repo, shove to Heroku

Any security?

  • No authentication
  • Rate limiting: only one score per IP address per minute
  • Three-letter initials only, filtered for rude language
  • No CORS, so only same-server AJAX requests

Links

Questions?