-- A superclass for all player and AI-controlled units import "CoreLibs/object" import "CoreLibs/graphics" import "CoreLibs/sprites" import "statemachine" local gfx = playdate.graphics local geom = playdate.geometry class("Entity").extends(gfx.sprite) function Entity:init(img, health, armor) Entity.super.init(self, img) self.type = "entity" self.health = health or 10 self.armor = armor or 0 self.introAnimator = nil -- movement direction, every update() the entity will move along this vector and return -- collision data to the subclass self.vector = geom.vector2D.new(0, 0) self:setCollideRect(0, 0, self:getSize()) -- most entities will be enemies, so we configure this mask by default -- We don't set a collider mask because collision is a bit too variable -- (but we should always include 0x2 and handle player collisions) self:setGroupMask(0x4) -- state machine mapping -- this can be extended by subclasses if they need more states using -- StateMachine:addState() local states = { ["INIT"] = { main=self.runInit, transition=self.onInit }, ["INTRO"] = { main=self.runIntro, transition=self.onIntro, }, ["READY"] = { main=self.runReady, transition=self.onReady, }, } self.fsm = StateMachine.new({self}, states) end function Entity:damage(amount) if amount < self.armor then return end self.health = math.max(self.health - (amount - self.armor), 0) if self.health == 0 then self:remove() end end function Entity:add() Entity.super.add(self) if self.introAnimator then self.fsm:changeState("INTRO") else self.fsm:changeState("READY") end end function Entity:update() -- update state machine self.fsm:execute() end -- State machine-controlled functions function Entity:onInit() -- noop end function Entity:runInit() -- noop end function Entity:onIntro() -- noop end function Entity:runIntro() if self.introAnimator and not self.introAnimator:ended() then self:moveTo(self.introAnimator:currentValue()) else self.fsm:changeState("READY") end end function Entity:onReady() -- noop end function Entity:runReady() return select(3, self:moveWithCollisions(self.x + self.vector.dx, self.y + self.vector.dy)) end