--[[ Generally whenever you want to get a position B that is distance units away from position A such that position B is positioned at a specific angle in relation to position A, the pattern is something like: bx = ax + distance*math.cos(angle) and by = ay + distance*math.sin(angle). ]] ---@class Player:GameObject ---@field area Area ---@field x number ---@field y number ---@field opts table|nil local Player = GameObject:extend() function Player:new(area, x, y, opts) Player.super.new(self, area, x, y, opts) self.w, self.h = 12, 12 self.collider = self.area.world:circle(self.x, self.y, math.floor(self.w*0.8)) -- player angle self.r = -math.pi/2 -- velocity of player angle rotation self.rv = 1.66*math.pi -- player velocity self.v = 0 -- max player velocity self.max_v = 100 -- player acceleration self.a = 100 -- attack rate self.ar = 0.24 self.timer:every(self.ar, function() self:shoot() end) end function Player:update(dt) Player.super.update(self, dt) if self:isDead() then return end -- controls if input:down('left') then self.r = self.r - self.rv*dt end if input:down('right') then self.r = self.r + self.rv*dt end -- update velocity self.v = math.min(self.v + self.a*dt, self.max_v) -- update position local vx = self.v * math.cos(self.r) -- velocity X local vy = self.v * math.sin(self.r) -- velocity Y self.x = self.x + vx * dt -- update position X self.y = self.y + vy * dt -- update position Y -- move collision area self.collider:moveTo(self.x, self.y) -- offscreen kill if self.x < 0-self.w then self:kill() end if self.y < 0-self.h then self:kill() end if self.x > gw+self.w then self:kill() end if self.y > gh+self.h then self:kill() end if input:pressed('f11') then self:kill() end end function Player:draw() Player.super.draw(self) if DEBUG then love.graphics.setColor(COLORS.collision) self.collider:draw() love.graphics.setColor(COLORS.debug) love.graphics.line(self.x, self.y, self.x + 2*self.w*math.cos(self.r), self.y + 2*self.w*math.sin(self.r)) end love.graphics.setColor(COLORS.default) love.graphics.circle('line', self.x, self.y, self.w) end function Player:shoot() local d = 1.2*self.w local offset_x, offset_y = self.x + d*math.cos(self.r), self.y + d*math.sin(self.r) self.area:addGameObject('ShootEffect', offset_x, offset_y, {player = self, d = d}) local proj = self.area:addGameObject('Projectile', offset_x, offset_y, {v = 100 ,r = self.r}) proj.timer:tween(0.5, proj, {v = 400}, 'linear') end function Player:kill() self:destroy() for i=1, random(8,12) do self.area:addGameObject('ExplodeParticle', self.x, self.y) end self.area:slow(.15, 1) camera:shake(6, 60, .4) end return Player