Sfoglia il codice sorgente

Building updates; People update; Laser; Flying fixes;

bjorn 10 anni fa
parent
commit
02fe319b3f
8 ha cambiato i file con 113 aggiunte e 28 eliminazioni
  1. 18 7
      building.lua
  2. 4 4
      caveman.lua
  3. 4 0
      conf.lua
  4. 2 2
      data/animation/pigeon.lua
  5. 1 1
      deps/view.lua
  6. 6 2
      game.lua
  7. 2 2
      person.lua
  8. 76 10
      pigeon.lua

+ 18 - 7
building.lua

@@ -9,7 +9,7 @@ function Building:activate()
 
   -- Roof
   local piece = {}
-  piece.body = love.physics.newBody(ctx.world, self.x, self.y - self.height - self.wallWidth / 2, 'kinematic')
+  piece.body = love.physics.newBody(ctx.world, self.x, self.y - self.height - self.wallWidth / 2, 'dynamic')
   piece.body:setUserData(self)
   piece.shape = love.physics.newRectangleShape(self.width, self.wallWidth)
   piece.fixture = love.physics.newFixture(piece.body, piece.shape)
@@ -20,7 +20,7 @@ function Building:activate()
 
   -- Left wall
   piece = {}
-  piece.body = love.physics.newBody(ctx.world, self.x - self.width / 2 + self.wallWidth / 2, self.y - self.height / 2, 'kinematic')
+  piece.body = love.physics.newBody(ctx.world, self.x - self.width / 2 + self.wallWidth / 2, self.y - self.height / 2, 'dynamic')
   piece.body:setUserData(self)
   piece.shape = love.physics.newRectangleShape(self.wallWidth, self.height)
   piece.fixture = love.physics.newFixture(piece.body, piece.shape)
@@ -31,7 +31,7 @@ function Building:activate()
 
   -- Right wall
   piece = {}
-  piece.body = love.physics.newBody(ctx.world, self.x + self.width / 2 - self.wallWidth / 2, self.y - self.height / 2, 'kinematic')
+  piece.body = love.physics.newBody(ctx.world, self.x + self.width / 2 - self.wallWidth / 2, self.y - self.height / 2, 'dynamic')
   piece.body:setUserData(self)
   piece.shape = love.physics.newRectangleShape(self.wallWidth, self.height)
   piece.fixture = love.physics.newFixture(piece.body, piece.shape)
@@ -40,6 +40,8 @@ function Building:activate()
   piece.phlerp = PhysicsInterpolator(piece.body)
   table.insert(self.pieces, piece)
 
+  self.destroyed = false
+
   ctx.event:emit('view.register', {object = self})
 end
 
@@ -49,9 +51,9 @@ function Building:update()
   end)
 
   if ctx.pigeon.body:getY() + ctx.pigeon.shapeSize / 2 > self.pieces[1].body:getY() - self.wallWidth / 2 then
-    self.pieces[1].fixture:setCategory(ctx.categories.oneWayPlatform)
+    --self.pieces[1].fixture:setCategory(ctx.categories.oneWayPlatform)
   else
-    self.pieces[1].fixture:setCategory(ctx.categories.building)
+    --self.pieces[1].fixture:setCategory(ctx.categories.building)
   end
 end
 
@@ -67,10 +69,19 @@ function Building:draw()
   end)
 end
 
+function Building:collideWith(other)
+  if isa(other, Building) then return true
+  elseif isa(other, Pigeon) then self:destroy() end
+end
+
 function Building:destroy()
+  if self.destroyed then return end
+
+  self.destroyed = true
+
   table.each(self.pieces, function(piece)
-    piece.body:setType('dynamic')
-    piece.body:applyTorque(lume.random(50000, 100000) * (love.math.random() > .5 and 1 or -1))
+    --piece.body:setType('dynamic')
+    piece.body:applyAngularImpulse(lume.random(1000, 2000) * (love.math.random() > .5 and 1 or -1))
     piece.fixture:setCategory(ctx.categories.debris)
   end)
 end

+ 4 - 4
caveman.lua

@@ -11,7 +11,7 @@ function Caveman:activate()
   self.image = data.media.graphics.dinoland[self.gender].normal
   self.direction = 1
 
-  self.state = self.attack
+  self.state = self.panic
   self.hasSpear = true
   self.walkTimer = 1
   self.reloadTimer = 0
@@ -44,9 +44,9 @@ end
 -- States
 ----------------
 Caveman.panic = {}
-Caveman.panic.walkRate = {.28, .30}
+Caveman.panic.walkRate = {.3, .4}
 function Caveman.panic:update()
-  self.direction = -self:directionTo(ctx.pigeon)
+  self.direction = 1 -- -self:directionTo(ctx.pigeon)
   self.image = data.media.graphics.dinoland[self.gender].panic
 
   if self.walkTimer == 0 then
@@ -57,7 +57,7 @@ function Caveman.panic:update()
   self:reloadSpear()
 
   if self.hasSpear then
-    self:changeState('attack')
+    --self:changeState('attack')
   end
 end
 

+ 4 - 0
conf.lua

@@ -0,0 +1,4 @@
+function love.conf(t)
+  t.window.width = 1067
+  t.window.height = 600
+end

+ 2 - 2
data/animation/pigeon.lua

@@ -1,6 +1,6 @@
 local Pigeon = extend(Animation)
 
-Pigeon.scale = .6
+Pigeon.scale = .3
 Pigeon.default = 'idle'
 Pigeon.states = {}
 
@@ -10,7 +10,7 @@ Pigeon.states.idle = {
 
 Pigeon.states.walk = {
   loop = true,
-  speed = .75
+  speed = .85
 }
 
 Pigeon.states.peck = {

+ 1 - 1
deps/view.lua

@@ -5,7 +5,7 @@ local g = love.graphics
 function View:init()
   self.x = 0
   self.y = 0
-  self.width = 800
+  self.width = 1067
   self.height = 600
   self.xmin = 0
   self.ymin = 0

+ 6 - 2
game.lua

@@ -21,14 +21,18 @@ function Game:load()
   self.hud = Hud()
   self.goal = Goal()
 
-  self.enemies:add(Caveman, {x = 500, y = 300})
-  self.buildings:add(Building, {x = 600, width = 200, height = 80})
+  for i = 1, 50 do
+    self.enemies:add(Caveman, {x = 300 + love.math.random() * 500, y = 300})
+  end
+
+  --self.buildings:add(Building, {x = 300, width = 200, height = 80})
 
   self.world:setContactFilter(function(fixtureA, fixtureB)
     local a, b = fixtureA:getBody():getUserData(), fixtureB:getBody():getUserData()
     if not a or not b then return true end
     f.exe(a.collideWith, a, b, fixtureA, fixtureB)
     f.exe(b.collideWith, b, a, fixtureB, fixtureA)
+    return true
   end)
 end
 

+ 2 - 2
person.lua

@@ -5,7 +5,7 @@ Person = extend(Enemy)
 ----------------
 function Person:activate()
   local widthRatio = self.image:getWidth() / self.image:getHeight()
-  self.h = 45
+  self.h = 35
   self.w = self.h * widthRatio
   self.scale = self.h / self.image:getHeight()
 
@@ -51,7 +51,7 @@ end
 -- Helpers
 ----------------
 function Person:hop(direction)
-  self.body:applyLinearImpulse(60 * direction, -90)
+  self.body:applyLinearImpulse(30 * direction, -45)
 end
 
 function Person:directionTo(object)

+ 76 - 10
pigeon.lua

@@ -6,9 +6,13 @@ Pigeon = class()
 Pigeon.walkForce = 600
 Pigeon.maxSpeed = 350
 Pigeon.jumpForce = 3000
+Pigeon.flySpeed = 10000
 Pigeon.rocketForce = 500
 Pigeon.maxFlySpeed = 300
 Pigeon.maxFuel = 50
+Pigeon.laserTurnSpeed = 1
+Pigeon.laserChargeDuration = 2
+Pigeon.laserDuration = 2
 
 ----------------
 -- Core
@@ -43,9 +47,9 @@ function Pigeon:init()
   self.animation:on('event', function(event)
     local name = event.data.name
     if name == 'rightstep' then
-      self.slide = 'left'
-    elseif name == 'leftstep' then
       self.slide = 'right'
+    elseif name == 'leftstep' then
+      self.slide = 'left'
     elseif name == 'leftstop' or name == 'rightstop' then
       self.slide = nil
     elseif name == 'jump' then
@@ -89,11 +93,13 @@ function Pigeon:draw()
   g.setColor(self.grounded and {0, 255, 0} or {255, 0, 0})
   g.line(x1, y1, x2, y2)
 
-  local points = {self.beak.bottom.body:getWorldPoints(self.beak.bottom.shape:getPoints())}
-  g.setColor(255, 255, 255)
-  g.polygon('line', points)
-  local points = {self.beak.top.body:getWorldPoints(self.beak.top.shape:getPoints())}
-  g.polygon('line', points)
+  if self.state == self.laser and self.laser.active then
+    local x1, y1, x2, y2 = self:getLaserRaycastPoints()
+    g.setColor(255, 0, 0)
+    g.setLineWidth(10)
+    g.line(x1, y1, x2, y2)
+    g.setLineWidth(1)
+  end
 
   self.phlerp:delerp()
 end
@@ -103,6 +109,10 @@ function Pigeon:collideWith(other, myFixture)
     if self.state == self.peck and (myFixture == self.beak.top.fixture or myFixture == self.beak.bottom.fixture) and other.state ~= other.dead then
       other:changeState('dead')
     end
+  elseif isa(other, Building) then
+    if self.state == self.peck and (myFixture == self.beak.top.fixture or myFixture == self.beak.bottom.fixture) then
+      --other:destroy()
+    end
   end
 end
 
@@ -124,6 +134,13 @@ function Pigeon:getGroundRaycastPoints()
   return x1, y1, x2, y2
 end
 
+function Pigeon:getLaserRaycastPoints()
+  local x1, y1 = self.animation.spine.skeleton.x + self.animation.spine.skeleton:findBone('beakbottom').worldX, self.animation.spine.skeleton.y - self.animation.spine.skeleton:findBone('beakbottom').worldY
+  local dir = self.laser.direction
+  local x2, y2 = x1 + math.cos(dir) * 500, y1 + math.sin(dir) * 500
+  return x1, y1, x2, y2
+end
+
 function Pigeon:getGrounded()
   local grounded = false
   local x1, y1, x2, y2 = self:getGroundRaycastPoints()
@@ -153,9 +170,9 @@ function Pigeon:initBeak()
       polygon[i + 1] = polygon[i + 1] * self.animation.scale
     end
     beak.shape = love.physics.newPolygonShape(unpack(polygon))
-    beak.body = love.physics.newBody(ctx.world, 0, 0)
+    beak.body = love.physics.newBody(ctx.world, 0, 0, 'kinematic')
     beak.fixture = love.physics.newFixture(beak.body, beak.shape)
-    beak.fixture:setSensor(true)
+    beak.fixture:setCategory(ctx.categories.pigeon)
     beak.body:setUserData(self)
 
     self.beak[name] = beak
@@ -175,7 +192,7 @@ function Pigeon:updateBeak()
     local bone = skeleton:findBone('beak' .. name)
     beak.body:setX(skeleton.x + bone.worldX)
     beak.body:setY(skeleton.y + bone.worldY)
-    beak.body:setAngle(math.rad(-bone.worldRotation))
+    beak.body:setAngle(math.rad(bone.worldRotation * (self.animation.flipped and 1 or -1) + (self.animation.flipped and 180 or 0)))
 
     slot:setAttachment(skeleton:getAttachment(slot.data.name, slot.data.name))
   end)
@@ -194,12 +211,16 @@ function Pigeon:move()
 
     if self.slide then
       self.body:setX(self.body:getX() - self.slideSpeeds[self.slide] * ls.tickrate * (self.animation.state.speed or 1) * self.animation.scale)
+    elseif not self.grounded then
+      self.body:applyForce(self.body:getX() - self.flySpeed * ls.tickrate, 0)
     end
   elseif right then
     self.animation.flipped = false
 
     if self.slide then
       self.body:setX(self.body:getX() + self.slideSpeeds[self.slide] * ls.tickrate * (self.animation.state.speed or 1) * self.animation.scale)
+    elseif not self.grounded then
+      self.body:applyForce(self.body:getX() + self.flySpeed * ls.tickrate, 0)
     end
   end
 
@@ -240,6 +261,8 @@ function Pigeon.idle:update()
     self:changeState('air')
   elseif love.keyboard.isDown('down') then
     self:changeState('peck')
+  elseif love.keyboard.isDown(' ') then
+    self:changeState('laser')
   else
     local vx, vy = self.body:getLinearVelocity()
     self.body:setLinearVelocity(vx / 1.2, vy)
@@ -319,3 +342,46 @@ function Pigeon.peck:impact()
     --
   end)
 end
+
+Pigeon.laser = {}
+function Pigeon.laser:enter()
+  self.laser.active = false
+  self.laser.charge = 0
+  self.laser.direction = self.animation.flipped and 3 * math.pi / 4 or math.pi / 4
+end
+
+function Pigeon.laser:update()
+  if not self.laser.active then
+    if love.keyboard.isDown(' ') then
+      self.laser.charge = self.laser.charge + ls.tickrate
+    else
+      if self.laser.charge > self.laserChargeDuration then
+        self.laser.active = true
+        self.laser.charge = self.laserDuration
+      else
+        self:changeState('idle')
+      end
+    end
+  else
+    local x1, y1, x2, y2 = self:getLaserRaycastPoints()
+    ctx.world:rayCast(x1, y1, x2, y2, function(fixture)
+      local object = fixture:getBody():getUserData()
+      if object and isa(object, Person) and object.state ~= object.dead then
+        object:changeState('dead')
+      end
+
+      return 1
+    end)
+
+    if love.keyboard.isDown('up', 'right') then
+      self.laser.direction = self.laser.direction - self.laserTurnSpeed * ls.tickrate
+    elseif love.keyboard.isDown('down', 'left') then
+      self.laser.direction = self.laser.direction + self.laserTurnSpeed * ls.tickrate
+    end
+
+    self.laser.charge = timer.rot(self.laser.charge, function()
+      self:changeState('idle')
+    end)
+  end
+end
+