duckie :)
This commit is contained in:
104
data/scripts/classes/duck.lua
Normal file
104
data/scripts/classes/duck.lua
Normal file
@ -0,0 +1,104 @@
|
||||
local Vector3 = require "types.vector3"
|
||||
local Signal = require "types.signal"
|
||||
|
||||
local TEXTURE = "images/duckie.png"
|
||||
|
||||
local States = {
|
||||
IDLE = 1,
|
||||
WANDER = 2,
|
||||
CHASE = 3,
|
||||
}
|
||||
|
||||
local WANDER_TIME = 1.0
|
||||
local IDLE_TIME = 1.0
|
||||
|
||||
local Duck = {
|
||||
position = {},
|
||||
velocity = {},
|
||||
direction = {},
|
||||
|
||||
target = nil,
|
||||
state = States.IDLE,
|
||||
|
||||
wander_timer = 0,
|
||||
|
||||
speed = 0.02,
|
||||
chase_speed = 0.04,
|
||||
accel = 0.5,
|
||||
|
||||
STATES = States,
|
||||
|
||||
AteFeed = Signal.new()
|
||||
}
|
||||
|
||||
Duck.__index = Duck
|
||||
|
||||
function Duck.new(position)
|
||||
local d = util.shallow_copy(Duck)
|
||||
d.position = position
|
||||
d.velocity = Vector3()
|
||||
d.direction = Vector3(0, 0, -1):rotated(Vector3.UP, util.random_float(-math.pi, math.pi))
|
||||
|
||||
return setmetatable(d, Duck)
|
||||
end
|
||||
|
||||
function Duck:tick(ctx)
|
||||
if self.state == States.IDLE then
|
||||
self:idle(ctx.frame_duration)
|
||||
elseif self.state == States.WANDER then
|
||||
self:wander(ctx.frame_duration)
|
||||
elseif self.state == States.CHASE then
|
||||
self:chase(ctx.frame_duration)
|
||||
end
|
||||
draw_billboard{position = self.position, size = {x = 0.4, y = 0.4}, texture = TEXTURE}
|
||||
end
|
||||
|
||||
function Duck:idle(delta)
|
||||
self.wander_timer = self.wander_timer + delta
|
||||
if self.wander_timer >= IDLE_TIME then
|
||||
self.state = States.WANDER
|
||||
self.wander_timer = 0
|
||||
self.direction = Vector3(0, 0, -1):rotated(Vector3.UP, math.random() * (math.pi * 2.0))
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function Duck:wander(delta)
|
||||
self.wander_timer = self.wander_timer + delta
|
||||
if self.wander_timer >= WANDER_TIME then
|
||||
self.state = States.IDLE
|
||||
self.wander_timer = 0
|
||||
return
|
||||
end
|
||||
|
||||
local target_vel = self.direction * self.speed
|
||||
self.velocity = self.velocity:lerp(target_vel, self.accel)
|
||||
self.position = self.position + self.velocity
|
||||
end
|
||||
|
||||
function Duck:chase(delta)
|
||||
local hpos = self.position:horizontal()
|
||||
local fhpos = self.target.position:horizontal()
|
||||
|
||||
local dist = hpos:distance_to(fhpos)
|
||||
if dist <= 0.1 then
|
||||
self.AteFeed:emit(self.target)
|
||||
self.wander_timer = 0
|
||||
self.state = States.IDLE
|
||||
self.target = nil
|
||||
else
|
||||
local dir = self.position:horizontal():direction_to(self.target.position:horizontal())
|
||||
local target_vel = dir * self.chase_speed
|
||||
self.velocity = self.velocity:lerp(target_vel, self.accel)
|
||||
self.position = self.position + self.velocity
|
||||
end
|
||||
end
|
||||
|
||||
function Duck:start_chase(feed)
|
||||
if self.state == States.CHASE then return end
|
||||
self.state = States.CHASE
|
||||
self.target = feed
|
||||
feed.occupied = true
|
||||
end
|
||||
|
||||
return Duck
|
@ -7,6 +7,7 @@ local Feed = {
|
||||
direction = {},
|
||||
velocity = {},
|
||||
landed = false,
|
||||
occupied = false,
|
||||
|
||||
speed = 0.15,
|
||||
}
|
||||
|
Reference in New Issue
Block a user