-- Chase behavior: chase nearest opposing team member and attack when in range local BaseBehavior = require("behaviors.enemy") local Behavior = {} Behavior.__index = Behavior setmetatable(Behavior, { __index = BaseBehavior }) local flashShader = love.graphics.newShader [[ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords) { vec4 pixel = Texel(texture, texture_coords); if (pixel.a > 0.0) { return vec4(1.0, 1.0, 1.0, pixel.a) * color; } return vec4(0.0, 0.0, 0.0, 0.0); } ]] local moveDelayTime = 1.25 local attackWindUpTime = .35 function Behavior:new(combatant) self = setmetatable(BaseBehavior:new(combatant), Behavior) self.moveNextTimer = 0 self.attackTimer = attackWindUpTime self.wasGrounded = true self.squashTimer = 0 self.squashScaleY = 1 self.combatant.facing = -1 self.attackSkill = self.context.assetLoader:loadSkill("attack") return self end function Behavior:update(dt) BaseBehavior.update(self, dt) if not self:isAlive() then return end if not self:isDisabled() then local opponents = self:getOpponents() local nearest, nearestDist = self:getNearestCombatant(opponents) if not nearest then return end local dx = nearest.x - self.combatant.x local dy = nearest.y - self.combatant.y if self.moveNextTimer > 0 then self.moveNextTimer = self.moveNextTimer - dt self.combatant.velX = self.combatant.facing * (self.combatant.speed * self.moveNextTimer) if self.combatant.grounded then self.combatant.moveX = 0 self.combatant.velX = 0 end end if self.moveNextTimer <= 0 and self.combatant.knockbackTimer <= 0 then if nearestDist > self.attackRange then self.attackTimer = attackWindUpTime self.combatant.hitFlash = 0 if dx > self.attackRange then self.combatant.moveX = 1 self.combatant.facing = 1 elseif dx < -self.attackRange then self.combatant.moveX = -1 self.combatant.facing = -1 end if self.combatant.grounded and nearestDist > 50 then self.combatant.velY = -250 self.combatant.velX = self.combatant.facing * (self.combatant.speed * 8) self.moveNextTimer = moveDelayTime end else self.combatant.moveX = 0 if dx > 0 then self.combatant.facing = 1 elseif dx < 0 then self.combatant.facing = -1 end end if nearestDist <= self.attackRange then self.attackTimer = self.attackTimer - dt self.combatant.hitFlash = (math.floor(self.attackTimer * 10) % 2 == 0) and 1 or 0 if self.attackTimer <= 0 then self.combatant:activateSkillByAsset(self.attackSkill, opponents, {}) self.moveNextTimer = moveDelayTime self.attackTimer = attackWindUpTime self.combatant.hitFlash = 0 end end end end -- Squash/stretch on jump and land if not self.wasGrounded and self.combatant.grounded then -- landing self.squashTimer = 0.1 self.squashScaleY = 1.1 elseif self.wasGrounded and not self.combatant.grounded and self.combatant.velY < 0 then -- jumping self.squashTimer = 0.1 self.squashScaleY = 0.7 end self.wasGrounded = self.combatant.grounded if self.squashTimer > 0 then self.squashTimer = self.squashTimer - dt end -- Animation: skill > charging > jump > walk > idle local targetAnim = "idle" if self.combatant.velX ~= 0 then targetAnim = "walk" end if self.combatant.velY < 0 then targetAnim = "jump" end if self.combatant.velY > 0 then targetAnim = "fall" end if self.combatant.skillAnimation then targetAnim = self.combatant.skillAnimation end self.combatant.sprite:setAnimation(targetAnim) end function Behavior:draw() local oy = self.combatant.visualOffsetY or 0 local scaleX = self.combatant.facing local scaleY = 1 if self.squashTimer > 0 then scaleY = 1 + (self.squashScaleY - 1) * (self.squashTimer / 0.33) end local drawY = self.combatant.y + self.combatant.visualOffsetY if scaleY ~= 1 then drawY = drawY + self.combatant.height - (self.combatant.height * scaleY) end local drawX = self.combatant.x if self.combatant.facing == -1 then drawX = drawX + self.combatant.width end if self.combatant.hitFlash > 0 then love.graphics.setShader(flashShader) end self.combatant.sprite:drawAnimationFrame(drawX, drawY, { scale = { scaleX, scaleY } }) love.graphics.setShader() if self.combatant.health < self.combatant.maxHealth then self.combatant:drawHealthBar(self.combatant.x, self.combatant.y + oy - 5, self.combatant.width, 3, { 0.8, 0.2, 0.2 }) end end return Behavior