Browse Source

Physics stuff; Kinda meh;

bjorn 10 years ago
parent
commit
715f73d6f7
6 changed files with 124 additions and 59 deletions
  1. 6 0
      deps/util.lua
  2. 12 10
      game.lua
  3. 21 0
      map.lua
  4. 17 7
      person.lua
  5. 67 42
      pigeon.lua
  6. 1 0
      require.lua

+ 6 - 0
deps/util.lua

@@ -15,3 +15,9 @@ function math.hlora(x1, y1, x2, y2, rx, ry, rw, rh) -- Hot line on rectangle act
       or math.hlola(x1, y1, x2, y2, rxw, ry, rxw, ryh)
       or math.hlola(x1, y1, x2, y2, rxw, ry, rxw, ryh)
       or math.hlola(x1, y1, x2, y2, rx, ryh, rxw, ryh)
       or math.hlola(x1, y1, x2, y2, rx, ryh, rxw, ryh)
 end
 end
+
+function drawPhysicsObject(how, obj)
+  if obj.shape:typeOf('PolygonShape') then
+    love.graphics.polygon(how, obj.body:getWorldPoints(obj.shape:getPoints()))
+  end
+end

+ 12 - 10
game.lua

@@ -1,8 +1,10 @@
 Game = class()
 Game = class()
 
 
 function Game:load()
 function Game:load()
+  self.world = love.physics.newWorld(0, 98)
+  self.map = Map(ctx)
   self.pigeon = Pigeon()
   self.pigeon = Pigeon()
-  self.people = {Person()}
+  self.people = {}
   self.hud = Hud()
   self.hud = Hud()
 end
 end
 
 
@@ -13,25 +15,25 @@ function Game:update()
   end)
   end)
 
 
   if love.math.random() < .5 * ls.tickrate then
   if love.math.random() < .5 * ls.tickrate then
-    local p = Person()
+    local x, dir
 
 
     if love.math.random() < .5 then
     if love.math.random() < .5 then
-      p.x = 0
-      p.direction = 1
+      x = 0
+      dir = 1
     else
     else
-      p.x = 800
-      p.direction = -1
+      x = 800
+      dir = -1
     end
     end
 
 
-    lume.push(self.people, p)
+    lume.push(self.people, Person(x, 400, dir))
   end
   end
+
+  self.world:update(ls.tickrate)
 end
 end
 
 
 function Game:draw()
 function Game:draw()
-  local g = love.graphics
   flux.update(ls.dt)
   flux.update(ls.dt)
-  g.setColor(0, 50, 0)
-  g.rectangle('fill', 0, 0, 800, 600)
+  self.map:draw()
   self.pigeon:draw()
   self.pigeon:draw()
   lume.each(self.people, function(person)
   lume.each(self.people, function(person)
     person:draw()
     person:draw()

+ 21 - 0
map.lua

@@ -0,0 +1,21 @@
+Map = class()
+Map.width = 800
+Map.height = 600
+
+function Map:init()
+  self.ground = {}
+  self.ground.height = 100
+  self.ground.body = love.physics.newBody(ctx.world, self.width / 2, self.height - self.ground.height / 2, 'static')
+  self.ground.shape = love.physics.newRectangleShape(self.width, self.ground.height)
+
+  self.ground.fixture = love.physics.newFixture(self.ground.body, self.ground.shape)
+end
+
+function Map:draw()
+  local g = love.graphics
+  g.setColor(0, 50, 0)
+  g.rectangle('fill', 0, 0, self.width, self.height)
+
+  g.setColor(100, 80, 0)
+  drawPhysicsObject('fill', self.ground)
+end

+ 17 - 7
person.lua

@@ -1,21 +1,31 @@
 Person = class()
 Person = class()
 
 
-function Person:init()
-  self.x = 800
-  self.direction = -1
-  self.y = 500
+function Person:init(x, y, dir)
+  self.x = x
+  self.y = y
+  self.direction = dir
   self.w = 20
   self.w = 20
   self.h = 40
   self.h = 40
+
+  self.body = love.physics.newBody(ctx.world, self.x - self.w / 2, self.y - self.h / 2, 'dynamic')
+  self.shape = love.physics.newRectangleShape(self.w, self.h)
+  self.fixture = love.physics.newFixture(self.body, self.shape)
+
+  self.body:setUserData(self)
+
+  self.body:setMass(10)
 end
 end
 
 
 function Person:update()
 function Person:update()
-  self.x = self.x + 100 * self.direction * ls.tickrate
+  self.body:applyLinearImpulse(300 * self.direction * ls.tickrate, 0)
 end
 end
 
 
 function Person:draw()
 function Person:draw()
   local g = love.graphics
   local g = love.graphics
   g.setColor(255, 255, 255)
   g.setColor(255, 255, 255)
-  g.rectangle('line', self.x - self.w / 2, self.y - self.h / 2, self.w, self.h)
+  drawPhysicsObject('line', self)
 end
 end
 
 
-
+function Person:die()
+  self.body:destroy()
+end

+ 67 - 42
pigeon.lua

@@ -26,60 +26,84 @@ function Pigeon:update()
   self.prevx = self.x
   self.prevx = self.x
   self.prevy = self.y
   self.prevy = self.y
 
 
-  if love.keyboard.isDown('left') then
-    self.x = self.x - self.speed * ls.tickrate
-    self.targetDirection.x = -1
-  elseif love.keyboard.isDown('right') then
-    self.x = self.x + self.speed * ls.tickrate
-    self.targetDirection.x = 1
-  end
+  -- Movement
+  do
+    if love.keyboard.isDown('left') then
+      self.x = self.x - self.speed * ls.tickrate
+      self.targetDirection.x = -1
+    elseif love.keyboard.isDown('right') then
+      self.x = self.x + self.speed * ls.tickrate
+      self.targetDirection.x = 1
+    end
 
 
-  if love.keyboard.isDown('up') then
-    self.targetDirection.y = -1
-    self.y = self.y - self.speed * ls.tickrate
-  elseif love.keyboard.isDown('down') then
-    self.targetDirection.y = 1
-    self.y = self.y + self.speed * ls.tickrate
-  else
-    self.targetDirection.y = 0
-  end
+    if love.keyboard.isDown('up') then
+      self.targetDirection.y = -1
+    elseif love.keyboard.isDown('down') then
+      self.targetDirection.y = 1
+    else
+      self.targetDirection.y = 0
+    end
 
 
-  flux.to(self.direction, .4, self.targetDirection):ease('expoout')
+    flux.to(self.direction, .4, self.targetDirection):ease('expoout')
 
 
-  self.vy = self.vy + self.gravity * ls.tickrate
-  self.y = self.y + self.vy * ls.tickrate
+    self.vy = self.vy + self.gravity * ls.tickrate
+    self.y = self.y + self.vy * ls.tickrate
 
 
-  if self.y + self.h / 2 > 600 then
-    self.vy = math.abs(self.vy) * -1
+    if self.y + self.h / 2 > 600 then
+      self.vy = math.abs(self.vy) * -1
+    end
   end
   end
 
 
-  self.laser = love.keyboard.isDown(' ')
+  local kills = 0
+
+  -- Laser
+  do
+    self.laser = love.keyboard.isDown(' ')
+
+    if self.laser then
+      self.laserTween = flux.to(self, 1, {laserLength = 1000}):ease('expoout')
+
+      if self.laserLength > 0 then
+        local x1, y1 = self.x, self.y - self.h / 2
+        local x2, y2 = self.x + self.direction.x * self.laserLength, self.y + self.direction.y * self.laserLength - self.h / 2
+
+        ctx.world:rayCast(x1, y1, x2, y2, function(fixture)
+          local person = fixture:getBody():getUserData()
+          if person and person.die then
+            person:die()
+            lume.remove(ctx.people, person)
+            kills = kills + 1
+            return 1
+          end
+          return -1
+        end)
+      end
 
 
-  if self.laser then
-    self.laserTween = flux.to(self, 1, {laserLength = 1000}):ease('expoout')
-    local kills = 0
+      --[[for i, person in lume.ripairs(ctx.people) do
 
 
-    local x1, y1 = self.x, self.y
-    local x2, y2 = self.x + self.direction.x * self.laserLength, self.y + self.direction.y * self.laserLength
+        local px, py, px2, py2 = person.body:getWorldPoints(person.shape:getPoints())
+        local pw, ph = px2 - px, py2 - py
+        if math.hlora(x1, y1, x2, y2, px, py, pw, ph) then
+          kills = kills + 1
+          table.remove(ctx.people, i)
+        end
+      end]]
 
 
-    for i, person in lume.ripairs(ctx.people) do
-      if math.hlora(x1, y1, x2, y2, person.x - person.w / 2, person.y - person.h / 2, person.w, person.h) then
-        kills = kills + 1
-        table.remove(ctx.people, i)
+    else
+      if self.laserTween then
+        self.laserTween:stop()
+        self.laserLength = 0
       end
       end
     end
     end
+  end
 
 
-    if kills > 0 then
-      flux.to(self, .6, {w = self.w + 5 * kills, h = self.h + 10 * kills}):ease('elasticout')
-      self.health = math.min(self.health + 15 * kills, self.maxHealth)
-    end
-  else
-    if self.laserTween then
-      self.laserTween:stop()
-      self.laserLength = 0
-    end
+  -- Increase size and health on kill
+  if kills > 0 then
+    flux.to(self, .6, {w = self.w + 5 * kills, h = self.h + 10 * kills}):ease('elasticout')
+    self.health = math.min(self.health + 15 * kills, self.maxHealth)
   end
   end
 
 
+  -- Death
   if self.health < 0 then
   if self.health < 0 then
     if self.lives == 0 then
     if self.lives == 0 then
       print('you lose')
       print('you lose')
@@ -93,6 +117,7 @@ function Pigeon:update()
     self.h = self.h / 2
     self.h = self.h / 2
   end
   end
 
 
+  -- Health decay
   self.health = self.health - 10 * ls.tickrate
   self.health = self.health - 10 * ls.tickrate
 end
 end
 
 
@@ -101,14 +126,14 @@ function Pigeon:draw()
   local x = lume.lerp(self.prevx, self.x, ls.accum / ls.tickrate)
   local x = lume.lerp(self.prevx, self.x, ls.accum / ls.tickrate)
   local y = lume.lerp(self.prevy, self.y, ls.accum / ls.tickrate)
   local y = lume.lerp(self.prevy, self.y, ls.accum / ls.tickrate)
   g.setColor(255, 255, 255)
   g.setColor(255, 255, 255)
-  g.rectangle('line', x - self.w / 2, y - self.h / 2, self.w, self.h)
+  g.rectangle('line', x - self.w / 2, y - self.h, self.w, self.h)
 
 
   if self.laser then
   if self.laser then
     local x2, y2 = x + self.direction.x * self.laserLength, y + self.direction.y * self.laserLength
     local x2, y2 = x + self.direction.x * self.laserLength, y + self.direction.y * self.laserLength
 
 
     g.setColor(255, 0, 0)
     g.setColor(255, 0, 0)
     g.setLineWidth(self.w / 5)
     g.setLineWidth(self.w / 5)
-    g.line(x, y, x2, y2)
+    g.line(x, y - self.h / 2, x2, y2 - self.h / 2)
     g.setLineWidth(1)
     g.setLineWidth(1)
   end
   end
 end
 end

+ 1 - 0
require.lua

@@ -9,5 +9,6 @@ require 'context'
 require 'game'
 require 'game'
 require 'person'
 require 'person'
 require 'pigeon'
 require 'pigeon'
+require 'map'
 
 
 require 'hud'
 require 'hud'