cactus source/threejs/ufo.js.coffee

class Ufo
  constructor: (@scene, @cows, @camera) ->
    @tex = THREE.ImageUtils.loadTexture( "ufo.jpeg" )
    @material = new THREE.SpriteMaterial( { map: @tex, color: 0xffffff, fog: true } );
    @sprite = new THREE.Sprite @material
    @sprite.position.y = 3.4
    @light = new THREE.PointLight(0x0033FF, 4.0)
    @light.position.y = 0.6
    @light.castShadow = true
    @scene.add @sprite
    @scene.add @light

    @coneGeo = new THREE.CylinderGeometry(0, 1, 1.0, 32)
    @coneMat = new THREE.MeshBasicMaterial {color: 0x0033FF, transparent: true, opacity: 0.5}
    @cone = new THREE.Mesh @coneGeo, @coneMat
    @cone.scale.y = @sprite.position.y
    @cone.position.y = 3.4 / 2
    @scene.add @cone

    @target = {x: 0, y: 0}

  moveAmmount: (x, y) ->
    @sprite.position.x += x
    @sprite.position.z += y
    @light.position.x += x
    @light.position.z += y
    @cone.position.x += x
    @cone.position.z += y

  move: (x, y) ->
    @target.x += x
    @target.y += y

  update: (step) ->
    v = 4
    x = 0
    y = 0
    px = @sprite.position.x
    py = @sprite.position.z
    if px > @target.x
      x = - v * step
      if px + x < @target.x
        x = @target.x - px
    if @sprite.position.x < @target.x
      x = v * step
      if px + x > @target.x
        x = @target.x - px
    if @sprite.position.z < @target.y
      y = v * step
      if py + y > @target.y
        y = @target.y - py
    if @sprite.position.z > @target.y
      y = - v * step
      if py + y < @target.y
        y = @target.y - py

    @moveAmmount(x, y)

    for p in @cows.meshes
      dx = p.position.x - px
      dy = p.position.z - py
      dist = Math.sqrt(dx * dx + dy * dy)

      if (dist < 1.5) and p.position.y >= 0.0
        # p.velocity.x += ((1.0 / (dx + 0.01)) * step) * (- p.position.y + @sprite.position.y)
        # p.velocity.z += ((1.0 / (dy + 0.01)) * step) * (- p.position.y + @sprite.position.y)
        p.velocity.x += (((-dx)) * step) * (- p.position.y + @sprite.position.y) / p.mass
        p.velocity.z += (((-dy)) * step) * (- p.position.y + @sprite.position.y) / p.mass
        p.angularVelocity.y = Math.max (1.5 - dist) * 3, p.angularVelocity.y


  handleKey: (event) ->
    return if event.repeat
    rscale = 5
    console.log event.which
    keyup = event.type is "keyup"
    keydown = event.type is "keydown"
    switch event.which
      when 38 then @move(0, -1) if keydown
      when 40 then @move(0, 1) if keydown
      when 37 then @move(-1, 0) if keydown
      when 39 then @move(1, 0) if keydown

      #space
      when 32 then @cows.addParticle @sprite.position, {x: 0, y:0, z: 0} if keydown

      # r
      when 82 then @cows.addParticle @sprite.position, {x: (Math.random() - 0.5) * rscale, y:(Math.random() - 0.5) * rscale, z: (Math.random() - 0.5) * rscale} if keydown

      when 97 then @shootCow(-1, -1, keyup)
      when 98 then @shootCow(0, -1, keyup)
      when 99 then @shootCow(1, -1, keyup)

      when 100 then @shootCow(-1, 0, keyup)
      when 102 then @shootCow(1, 0, keyup)

      when 103 then @shootCow(-1, 1, keyup)
      when 104 then @shootCow(0, 1, keyup)
      when 105 then @shootCow(1, 1, keyup)

  shootCow: (x, y, release) ->
    unless release
      @shootTimer = Date.now()
      return

    timeTaken = Date.now() - @shootTimer
    v = timeTaken * 0.01
    @cows.addParticle @sprite.position, {x: x * v, y: y * v, z: 0}
    m = 0.1
    d = - x * v * m
    @move(d, 0) if Math.abs(d) > 1.0


window.Ufo = Ufo