Skip to content

Instantly share code, notes, and snippets.

@chrissharkey
Created September 3, 2011 02:14
Show Gist options
  • Save chrissharkey/1190418 to your computer and use it in GitHub Desktop.
Save chrissharkey/1190418 to your computer and use it in GitHub Desktop.
Bislr Pong Game
# $BISLR_APP_NAME Pong
# $BISLR_APP_AUTHOR Chris Sharkey
# $BISLR_APP_DESCRIPTION An exciting game involving two bats and a ball.
BAT_ACCELERATION = 0.40
BAT_TERMINAL_VELOCITY = 5
BAT_FRICTION = 0.10
BALL_ACCELERATION = 10
BALL_TERMINAL_VELOCITY = 10
BALL_FRICTION = 0
LEFT = 0
RIGHT = 1
class Entity
x: 0, y: 0, vx: 0, vy: 0
constructor: (@context, @maxX, @maxY, @minX, @minY, @offsetX, @offsetY, @a, @tv, @f) ->
update: ->
# Apply friction
@vx -= @f if @vx > 0
@vx += @f if @vx < 0
@vy -= @f if @vy > 0
@vy += @f if @vy < 0
# Make sure we don't go faster than terminal velocity
@vx = @tv if @vx > @tv
@vx = -@tv if @vx < -@tv
@vy = @tv if @vy > @tv
@vy = -@tv if @vy < -@tv
# Update the entity's co-ordinates
@x += @vx
@y += @vy
@checkBoundary()
checkBoundary: ->
@x = @maxX-@w if @x+@w > @maxX
@x = @minX if @x < @minX
@y = @maxY-@h if @y+@h > @maxY
@y = @minY if @y < @minY
draw: ->
@context.fillStyle = 'rgba(0,0,0,0.8)'
@context.fillRect @x+@offsetX, @y+@offsetY, @w, @h
accelX: -> @vx += @a
accelY: -> @vy += @a
decelX: -> @vx -= @a
decelY: -> @vy -= @a
class Bat extends Entity
w: 40, h: 175
class Ball extends Entity
w: 40, h: 40, x: 200, y: 200, vx: 2, vy: 2.5, winner: null
checkWinner: -> @winner
checkBoundary: ->
if @x+@w > @maxX
@winner = 1
if @x < @minX
@winner = 2
# If we hit the top or the bottom we need to bounce
@vy = -@vy if @y+@h > @maxY or @y < @minY
checkCollision: (e, bat) ->
x = @x + @offsetX
y = @y + @offsetY
ex = e.x + e.offsetX
ey = e.y + e.offsetY
if y >= ey and y <= ey+e.h
if bat is LEFT and x < ex+e.w
@x += BAT_TERMINAL_VELOCITY / 2
@vx = -@vx
if bat is RIGHT and x+@w > ex
@x -= BAT_TERMINAL_VELOCITY / 2
@vx = -@vx
draw: ->
# @TODO: draw a circle here
@context.fillStyle = 'rgba(0,0,0,0.8)'
@context.fillRect @x+@offsetX, @y+@offsetY, @w, @h
###
Create the pong game as a Bislr App
###
PongApp = Bislr.Admin.App.extend
name: 'Pong'
version: '0.0.1'
startZIndexAt: 100001
# Entry point for the game
main: ->
@notifyCurrentUser "#{@name} version #{@version} loaded."
@createCanvas()
@addKeyObservers()
@appendCanvas()
@startNewGame()
startNewGame: ->
@entities = []
@entities.push(new Bat @context, @canvasWidth, @canvasHeight, 0, 0, 30, 0, BAT_ACCELERATION, BAT_TERMINAL_VELOCITY, BAT_FRICTION)
@entities.push(new Bat @context, @canvasWidth, @canvasHeight, 0, 0, @canvasWidth - 70, 0, BAT_ACCELERATION, BAT_TERMINAL_VELOCITY, BAT_FRICTION)
@entities.push(new Ball @context, @canvasWidth, @canvasHeight, 0, 0, 0, 0, BALL_ACCELERATION, BALL_TERMINAL_VELOCITY, BALL_FRICTION)
@runLoop()
runLoop: ->
setTimeout =>
# Adjust for player key input
@entities[0].decelY() if @aPressed
@entities[0].accelY() if @zPressed
@entities[1].decelY() if @upPressed
@entities[1].accelY() if @downPressed
# Update position of entities
@entities.each (e) -> e.update()
# Check for ball collsions with bats
@entities[2].checkCollision @entities[0], LEFT
@entities[2].checkCollision @entities[1], RIGHT
# Check for winner
player = @entities[2].checkWinner()
if player
@terminateRunLoop = YES
@score = [0, 0] unless @score
@score[player-1]++
@notifyCurrentUser "Player #{player} wins! Score: #{@score[0]} - #{@score[1]}. New game starting in 3 seconds."
setTimeout =>
@terminateRunLoop = NO
@startNewGame()
, 3000
# Clear the Canvas
@context.clearRect 0, 0, @canvasWidth, @canvasHeight
# Redraw game entities
@entities.each (e) -> e.draw()
# Run again unless we have been killed
@runLoop() unless @terminateRunLoop
, 5
# Run when the game is quit to clean up everything we create
cleanup: ->
if @canvas
@canvas.destroy()
@canvas = null
@terminateRunLoop = YES
@destroy()
# Creates an overlay for the sceen and a canvas to draw the game on
createCanvas: ->
@canvas = Bislr.UI.Pane.create
tagName: 'canvas'
absoluteLayout: YES
style:
backgroundColor: 'rgba(255,255,255,0)'
top: 0
left: 0
right: 0
bottom: 0
zIndex: @startZIndexAt+1
canvasElement = @canvas.get 'element'
@context = canvasElement.getContext '2d'
# @TODO: this needs to update dynamically
@canvasWidth = canvasElement.width = document.width
@canvasHeight = canvasElement.height = document.height
addKeyObservers: ->
@canvas.observeEvent 'keydown', (e) =>
switch e.keyCode
when 40 then @downPressed = YES
when 38 then @upPressed = YES
when 90 then @zPressed = YES
when 65 then @aPressed = YES
, document
@canvas.observeEvent 'keyup', (e) =>
switch e.keyCode
when 27 then @cleanup()
when 40 then @downPressed = NO
when 38 then @upPressed = NO
when 90 then @zPressed = NO
when 65 then @aPressed = NO
, document
appendCanvas: ->
@canvas.append()
pong = PongApp.create()
Bislr.get('Apps')['pong'] = pong
pong.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment