aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Cholewiński <harry666t@gmail.com>2016-02-21 21:54:54 +0100
committerKamil Cholewiński <harry666t@gmail.com>2016-02-21 21:54:54 +0100
commit607ac903604a655204faa57740e2d4734ea8e4be (patch)
treeeb475cf83e43d7e32cbd8c587cf892d229ed50f9
parent1e5e9d1e03c247e08ed488be9c077d2ecd91c590 (diff)
downloadkittenlanding-607ac903604a655204faa57740e2d4734ea8e4be.zip
kittenlanding-607ac903604a655204faa57740e2d4734ea8e4be.tar.gz
kittenlanding-607ac903604a655204faa57740e2d4734ea8e4be.tar.bz2
BIRDS!!!
-rw-r--r--data/shapes.json30
-rw-r--r--game/Bird.lua75
-rw-r--r--game/Entity.lua1
-rw-r--r--game/Game.lua56
-rw-r--r--game/Kitten.lua8
-rw-r--r--game/Parachute.lua5
-rw-r--r--game/utils.lua21
7 files changed, 183 insertions, 13 deletions
diff --git a/data/shapes.json b/data/shapes.json
index 4ae62d4..7bfebe2 100644
--- a/data/shapes.json
+++ b/data/shapes.json
@@ -76,5 +76,35 @@
{"type": "ref", "ref": "parachute-det2l", "translate": [-60, 0]},
{"type": "ref", "ref": "parachute-det2r", "translate": [ 60, 0]}
]
+ },
+ "bird-eye": {"type": "circle", "radius": 3,
+ "data": {"color": [0, 0, 0], "tags": ["eyes"]}},
+ "bird-beak": {"type": "polygon", "points": [5, 0, 0, 15, -5, 0],
+ "data": {"color": [160, 160, 80]}},
+ "bird-head": {
+ "type": "composite",
+ "shapes": [
+ {"type": "circle", "radius": 15},
+ {"type": "ref", "ref": "bird-eye", "translate": [7, 7]},
+ {"type": "ref", "ref": "bird-eye", "translate": [-7, 7]},
+ {"type": "ref", "ref": "bird-beak", "translate": [0, 15]}
+ ]
+ },
+ "bird-body": {
+ "type": "composite",
+ "shapes": [
+ {"type": "polygon", "points": [0, 5, 40, -55, 0, -40]},
+ {"type": "polygon", "points": [0, 5, -40, -55, 0, -40]},
+ {"type": "polygon", "points": [ 10, -40, 15, -60, 5, -55]},
+ {"type": "polygon", "points": [-10, -40, -15, -60, -5, -55]},
+ {"type": "polygon", "points": [0, -65, -10, -40, 10, -40]}
+ ]
+ },
+ "bird": {
+ "type": "composite",
+ "shapes": [
+ {"type": "ref", "ref": "bird-head", "translate": [0, 0]},
+ {"type": "ref", "ref": "bird-body", "translate": [0, 0]}
+ ]
}
}
diff --git a/game/Bird.lua b/game/Bird.lua
new file mode 100644
index 0000000..8d20e64
--- /dev/null
+++ b/game/Bird.lua
@@ -0,0 +1,75 @@
+local class = require "class"
+
+local Entity = require "Entity"
+
+local Bird = class(Entity)
+Bird:extend {
+ color = {92, 220, 80},
+ shape = "bird",
+ draw_priority = 4,
+ ok = true,
+ life = 10, -- seconds until removed
+}
+
+function Bird:init(args)
+ Entity.init(self, args)
+ self.body:setLinearDamping(1)
+ self.body:setAngularDamping(1)
+
+ if args.colorname == "black" then -- black bird, make eyes evil
+ local eyes = self:getEyes()
+ local data = eyes:getUserData()
+ data.color = {255, 0, 0}
+ eyes:setUserData(data)
+ end
+
+ self.getKittenFallSpeed = function()
+ return args.game.fall_speed
+ end
+
+ self.die = function(self) args.game:kill(self) end
+end
+
+function Bird:getEyes()
+ for _, fixture in pairs(self.fixtures) do
+ local data = fixture:getUserData()
+ if data and data.tags then
+ for _, tag in ipairs(data.tags) do
+ if tag == "eyes" then
+ return fixture
+ end
+ end
+ end
+ end
+end
+
+function Bird:update(dt)
+ local speed = self.getKittenFallSpeed() * 100
+ local angle = math.rad(math.deg(self.body:getAngle()) % 360)
+ if self.ok then
+ self.body:applyForce(math.sin(angle) * speed,
+ math.cos(angle) * -speed)
+ self.body:applyTorque(speed / 2)
+ else
+ self.body:applyTorque(1000)
+ self.body:applyForce(0, 500)
+ end
+ self.life = self.life - dt
+ if self.life < 0 then self:die() end
+end
+
+function Bird:faint()
+ self.ok = false
+ self.life = 1
+ self.color = {220, 92, 80}
+end
+
+Bird.color_choices = {
+ black = {0, 0, 20},
+ blue = {92, 80, 220},
+ green = {92, 220, 80},
+ teal = {92, 220, 220},
+ yellow = {220, 220, 92},
+}
+
+return Bird
diff --git a/game/Entity.lua b/game/Entity.lua
index 92da4b0..8f32240 100644
--- a/game/Entity.lua
+++ b/game/Entity.lua
@@ -13,6 +13,7 @@ function Entity:init(args)
assert(args.game.world)
assert(args.game.shapelib)
self.shape = args.shape or self.shape
+ self.color = args.color or self.color
assert(self.shape)
self.body = love.physics.newBody(
args.game.world, args.x or 0, args.y or 0, "dynamic"
diff --git a/game/Game.lua b/game/Game.lua
index 12de058..54cf661 100644
--- a/game/Game.lua
+++ b/game/Game.lua
@@ -1,6 +1,7 @@
local class = require "class"
local utils = require "utils"
+local Bird = require "Bird"
local Building = require "Building"
local Camera = require "Camera"
local FpsLimiter = require "FpsLimiter"
@@ -50,7 +51,7 @@ function Game:init(args)
table.insert(self.background_layers, Sky.new(background_args))
table.insert(self.background_layers, Building.new(background_args))
- self.status = Status.new{metrics={"speed", "altitude"}}
+ self.status = Status.new{metrics={"score", "speed", "altitude"}}
for _, p in ipairs(args.players or {}) do
self:attach_player(p)
@@ -58,9 +59,33 @@ function Game:init(args)
p:attach_entity(kitten)
end
+ self.hitchcock_mode = false
+
self.camera:follow()
self:resize()
+ local function beginContact(a, b, con)
+ if not con:isTouching() then return end
+ local a = a:getBody():getUserData()
+ local b = b:getBody():getUserData()
+ local bird, kitten
+ for _, e in ipairs({a, b}) do
+ if e.cls == Kitten then
+ kitten = e
+ elseif e.cls == Bird then
+ bird = e
+ end
+ end
+ if kitten and bird then
+ if bird.ok then
+ local p = self:player_for(kitten)
+ p.score = p.score + 1
+ bird:faint()
+ end
+ end
+ end
+ self.world:setCallbacks(beginContact, nil, nil, nil)
+
for i = 1, 1 do
local ctl = control.KeyboardController.new {
keymap=self.players[i].cfg.keymap
@@ -134,17 +159,42 @@ end
function Game:update(dt)
local kitten = self.players[1].entity
if kitten.controls.brake then
- self.fall_speed = math.max(1, self.fall_speed - dt * 2.71)
+ self.fall_speed = math.max(1, self.fall_speed - dt * 8)
else
- self.fall_speed = math.min(self.terminal_velocity, self.fall_speed + dt)
+ self.fall_speed = math.min(self.terminal_velocity,
+ self.fall_speed + dt * 4)
end
+ local old_altitude = self.altitude
self.altitude = math.max(0, self.altitude - self.fall_speed * dt)
+ self.status:set("score", self.players[1].score)
self.status:set("speed", self.fall_speed)
self.status:set("altitude", math.floor(self.altitude))
for _, layer in ipairs(self.background_layers) do
layer.altitude = self.altitude
end
+
+ local bfq -- bird frequency
+ if self.hitchcock_mode then bfq = 1 else bfq = 10 end
+ if math.floor(old_altitude / bfq) > math.floor(self.altitude / bfq) then
+ local x = math.random(-400, 400)
+ local color, colorname
+ local args
+ if self.hitchcock_mode then
+ colorname, color = "black", Bird.color_choices.black
+ else
+ colorname, color = utils.random_choice(Bird.color_choices)
+ end
+ if math.random(0, 1) == 0 then
+ args = {x=x, y=700, angle=math.tau * 0,
+ color=color, colorname=colorname}
+ else
+ args = {x=x, y=-700, angle=math.tau * 0.5,
+ color=color, colorname=colorname}
+ end
+ local bird = self:spawn(Bird, args)
+ end
+
self.fps:update(dt)
self.messages:update()
for _, p in ipairs(self.players) do
diff --git a/game/Kitten.lua b/game/Kitten.lua
index bed22af..cd59141 100644
--- a/game/Kitten.lua
+++ b/game/Kitten.lua
@@ -77,13 +77,11 @@ function Kitten:update(dt)
self:rightingReflex()
local x = self.body:getX()
+ local y = self.body:getY()
if x > 500 then self.body:applyForce(-1000 - (x*10), 0) end
if x < -500 then self.body:applyForce( 1000 - (x*10), 0) end
-
- local y = self.body:getY()
- if y < 50 then
- self.body:applyForce(0, 100-y)
- end
+ if y > 200 then self.body:applyForce(0, -1000 - (y*10)) end
+ if y < -200 then self.body:applyForce(0, 1000 - (y*10)) end
end
function Kitten:rightingReflex(factor)
diff --git a/game/Parachute.lua b/game/Parachute.lua
index 3561ad5..fd84dff 100644
--- a/game/Parachute.lua
+++ b/game/Parachute.lua
@@ -17,11 +17,6 @@ function Parachute:init(args)
self.body:setAngularDamping(1)
end
-function Parachute:update(dt)
- local angle = math.rad(math.deg(self.body:getAngle()) % 360)
- self.body:applyTorque(-angle)
-end
-
function Parachute:setState(state)
self.open = state
end
diff --git a/game/utils.lua b/game/utils.lua
index 5a20c08..dcceb7b 100644
--- a/game/utils.lua
+++ b/game/utils.lua
@@ -164,6 +164,26 @@ local function iter(xs)
end
end
+local function keys(t)
+ local tmp = {}
+ for k, _ in pairs(t) do
+ table.insert(tmp, k)
+ end
+ return tmp
+end
+
+local function _random_choice(xs)
+ assert(#xs > 0)
+ local i = math.random(1, #xs)
+ return xs[i]
+end
+
+local function random_choice(xs)
+ local ks = keys(xs)
+ local k = _random_choice(ks)
+ return k, xs[k]
+end
+
return {
avg=avg,
cartesian=cartesian,
@@ -179,4 +199,5 @@ return {
neighbors=neighbors,
pairwise=pairwise,
partial=partial,
+ random_choice=random_choice,
}