Skip to content

Instantly share code, notes, and snippets.

@code
Created November 1, 2010 07:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save code/657756 to your computer and use it in GitHub Desktop.
Save code/657756 to your computer and use it in GitHub Desktop.
# Compile: coffee -c game.coffee
# Run: coffee game.coffee
# Dependencies: underscore.js / userscore.coffee and backbone.js
# Check if the libs we need are already defined
# When running in browser you will need to bundle or add script tags to include these libs
if not _?
require('underscore')
if Backbone?
Events = Backbone.Events
else
{Events} = require('./backbone.js')
class GameTimer
constructor: (@time, @interval) ->
# when you see @something it really means this.something
# here im extending this object with backbone.js events
# this provides trigger (to fire and event) and bind (to listen to events)
_.extend(this, Events)
# this funny ?= syntax means if its not already defined, set it
@interval ?= 1000
start: ->
# since start takes no arguments, I can drop the ()
@counter = 0
# -> means function and => is a function bound to the local object
# if you want to access this or @something inside the function use =>
# in this example (=> @tick()) is the same as writing function(){ this.tick(); }
@ticker = setInterval( (=> @tick()) , @interval)
# always fire events, more events the better other code can listen
@trigger('start')
tick: ->
@counter++
@trigger('tick', {total: @time, counter: @counter, remaining: @time-@counter})
if @counter >= @time
clearInterval(@ticker)
@trigger('finished')
pause: ->
clearInterval(@ticker)
@trigger('paused')
resume: ->
@ticker = setInterval( (=> @tick()) , @interval)
@trigger('resume')
class Game
constructor: (@data)->
console.log("new game, game has " + @data['levels'].length+ " levels")
startLevel: (level)->
# using underscore to pick the first matching level
@level = _(@data['levels']).select((x)->x['name']==level)[0]
@position = 0
@score = 0
@timer = new GameTimer(@level['time'])
@timer.start()
@timer.pause()
# we want to know when the timer is finished, wire that event to this.outOfTime
@timer.bind('finished', (=> @outOfTime()))
@showQuestion()
showQuestion: ->
@timer.resume()
@question = @level['questions'][@position]
console.log(@question['question'])
# show each possible answer
_(@question['answers']).each (answer) ->
console.log(answer)
answer: (idx)->
if @question['answer'] is idx
console.log('Correct answer!')
@score++ # points mean prizes!
@timer.pause()
else
console.log('Incorrect answer! Try again??')
@timer.pause()
outOfTime: ->
console.log("Too slow!")
@gameOver()
gameOver: ->
console.log("You scored: "+@score)
# json rules.. use json. if forced to use xml then read xml and turn into json like structure
data =
levels: [
{
name: 'easy',
time: 10,
questions: [
{ question: "what is ?", answers: ['foo','boo','coo'], answer: 0 }
{ question: "what are ?", answers: ['foo','boo','coo'], answer: 2 }
{ question: "what do ?", answers: ['foo','boo','coo'], answer: 1 }
]
},{
name: 'medium'
time: 120,
questions: [
{ question: "what is ?", answers: ['foo','boo','coo'], answer: 0 }
{ question: "what are ?", answers: ['foo','boo','coo'], answer: 2 }
{ question: "what do ?", answers: ['foo','boo','coo'], answer: 1 }
],
}
]
game = new Game(data)
# if the window object exists we are in a brower
if window?
# export the game so it can be called
window.game = game
else
# otherwise we are running using console, just start the game
game.startLevel('easy')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment