Today I felt like making a game, so I learnt about Phaser and set myself the task/challenge of recreating a simple game from my childhood. Phaser is incredibly fun and easy to get started, I’d recommend giving it a go!

The game I chose was Tanx.

I started with the excellent Phaser tutorial and converted it to CoffeeScript. It’s perfectly fine to use CoffeeScript with Phaser, or I guess any other language that compiles to JavaScript.

It’s very rough and I only spent a few hours on it, but it gives you an idea of what you can make with this framework, even without any prior knowledge!

Instructions:

Try to shoot the other player by adjusting the angle and power. From the left, try an angle of about -30. From the right, try an angle of about 210.

Keys:

UP/DOWN: adjust angle
A/Z: adjust power
LEFT/RIGHT: pan screen
SPACE: fire / start new game

Full source code:

GAME_WIDTH = 1200

currentAngle = 0
currentPower = 500
maxPower = 600

cursors = null
current_player = null
font = null
win_message = null
tanks = null

firing = false

game_over = false

toRad = (angle) ->
  angle * Math.PI / 180

loadFonts = =>
  @angle = game.add.retroFont 'knightHawks', 31, 25, Phaser.RetroFont.TEXT_SET6, 10, 1, 1
  @power = game.add.retroFont 'knightHawks', 31, 25, Phaser.RetroFont.TEXT_SET6, 10, 1, 1

bulletHit = (body, shapeA, shapeB, equation) ->
  firing = false
  this.kill()
  if body.sprite.parent == tanks
    game_over = true
    win = game.add.retroFont 'knightHawks', 31, 25, Phaser.RetroFont.TEXT_SET6, 10, 1, 1
    win.text = current_player.name + ' wins!'
    win_message = game.add.image 60, 300, win
    win_message.fixedToCamera = true
    win_message.cameraOffset.x = 60
  else
    nextTurn()

changeAngle = (diff) ->
  setAngle(currentAngle + diff)

setAngle = (angle) =>
  currentAngle = angle
  @angle.text = 'angle: ' + currentAngle

changePower = (diff) ->
  setPower(currentPower + diff)

setPower = (power) =>
  currentPower = power
  @power.text = 'power: ' + currentPower

resetAngleAndPower = ->
  setAngle 0
  setPower 200

nextTurn = ->
  resetAngleAndPower()
  current_player = if current_player == @player
    setAngle 180
    @player2
  else
    setAngle 0
    @player
  resetCamera()

resetCamera = ->
  game.camera.target = current_player

resetGame = ->
  game_over = false
  current_player = @player
  resetCamera()
  resetAngleAndPower()
  win_message.destroy()

fireBullet = =>
  unless firing
    # create a bullet
    angle = currentAngle
    power = currentPower
    # calculate velocity
    x_velocity = Math.cos(toRad(angle)) * power
    y_velocity = Math.sin(toRad(angle)) * power
    cp = current_player
    #offset to avoid shooting self
    offset_x = if angle > 90 || angle < -90
      -32
    else
      32

    # create the sprite and set it going
    bullet = game.add.sprite cp.x + offset_x, cp.y, 'bullet'
    game.physics.p2.enable bullet
    bullet.body.velocity.x = x_velocity
    bullet.body.velocity.y = y_velocity
    bullet.body.onBeginContact.add bulletHit, bullet
    game.camera.follow bullet
    firing = true

@preload = ->
  game.load.image 'sky', '/games/assets/sky.png'
  game.load.image 'ground', '/games/assets/platform.png'
  game.load.image 'bullet', '/games/assets/ball.gif'
  game.load.spritesheet 'dude', '/games/assets/dude.png', 32, 48
  game.load.image 'knightHawks', '/games/assets/fonts/KNIGHT3.png'

@create = =>
  game.world.setBounds 0, 0, GAME_WIDTH, 600

  game.physics.startSystem Phaser.Physics.P2JS
  game.physics.p2.gravity.y = 100
  game.physics.p2.defaultRestitution = 0.9
  game.physics.p2.setImpactEvents true

  sky = game.add.tileSprite 0, 0, 2000, 600, 'sky'

  # create the ground sprite and set to static
  @ground = game.add.sprite 0, game.world.height - 48, 'ground'
  @ground.scale.setTo 6,3

  game.physics.p2.enable @ground
  @ground.body.static = true

  # create the 'tanks'
  tanks = game.add.group()
  @player = tanks.create 32, game.world.height - 150, 'dude'
  @player.frame = 5
  @player.name = 'Player 1'
  @player2 = tanks.create GAME_WIDTH - 120, game.world.height - 150, 'dude'
  @player2.name = 'Player 2'

  # angle / power text
  loadFonts()

  @ang = game.add.image 30, 30, @angle
  ang.fixedToCamera = true
  ang.cameraOffset.x = 30

  pow = game.add.image 30, 60, @power
  pow.fixedToCamera = true
  pow.cameraOffset.x = 30

  setPower currentPower
  setAngle currentAngle

  # enable physics!
  tanks.forEach (thing) ->
    game.physics.p2.enable(thing)
    thing.body.gravity.y = 100

  # set first player 
  current_player = @player

  game.physics.p2.setImpactEvents true

  cursors = game.input.keyboard.createCursorKeys()
  game.input.keyboard.addKeyCapture Phaser.Keyboard.SPACEBAR

@update = ->
  if game_over
    if game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)
      resetGame()
  else
    if cursors.right.isDown
      game.camera.target = null
      game.camera.x += 8 
    if cursors.left.isDown
      game.camera.target = null
      game.camera.x -= 8 
    if cursors.up.isDown
      changeAngle -1
    if cursors.down.isDown
      changeAngle 1
    if game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)
      fireBullet()
    if game.input.keyboard.isDown(Phaser.Keyboard.A)
      changePower 1
    if game.input.keyboard.isDown(Phaser.Keyboard.Z)
      changePower -1
@game = game = new Phaser.Game(800, 600, Phaser.CANVAS, 'tanks', { preload: preload, create: create, update: update })
Making a game with Phaser

Post navigation


Leave a Reply

Your email address will not be published. Required fields are marked *