92 lines
2.8 KiB
Lua
92 lines
2.8 KiB
Lua
--[[
|
|
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()
|
|
for i=1, random(8,12) do
|
|
self.area:addGameObject('ExplodeParticle', self.x, self.y)
|
|
end
|
|
self:destroy()
|
|
end
|
|
|
|
return Player
|