master
a327ex 2021-02-19 00:50:27 -03:00
parent 015afe0459
commit 30b10c0bd4
5 changed files with 323 additions and 167 deletions

View File

@ -8,13 +8,18 @@ function Arena:init(name)
self.effects = Group() self.effects = Group()
self.ui = Group():no_camera() self.ui = Group():no_camera()
self.main:disable_collision_between('player', 'player') self.main:disable_collision_between('player', 'player')
self.main:disable_collision_between('player', 'enemy')
self.main:disable_collision_between('enemy', 'enemy') self.enemies = {Seeker}
self.main:enable_trigger_between('player', 'enemy')
self.x1, self.y1 = gw/2 - 0.8*gw/2, gh/2 - 0.8*gh/2 self.x1, self.y1 = gw/2 - 0.8*gw/2, gh/2 - 0.8*gh/2
self.x2, self.y2 = gw/2 + 0.8*gw/2, gh/2 + 0.8*gh/2 self.x2, self.y2 = gw/2 + 0.8*gw/2, gh/2 + 0.8*gh/2
self.spawn_points = {{x = self.x1 + 32, y = self.y1 + 32}, {x = self.x1 + 32, y = self.y2 - 32}, {x = self.x2 - 32, y = self.y1 + 32}, {x = self.x2 - 32, y = self.y2 - 32}, {x = gw/2, y = gh/2}} self.spawn_points = {
{x = self.x1 + 32, y = self.y1 + 32, r = math.pi/4},
{x = self.x1 + 32, y = self.y2 - 32, r = -math.pi/4},
{x = self.x2 - 32, y = self.y1 + 32, r = 3*math.pi/4},
{x = self.x2 - 32, y = self.y2 - 32, r = -3*math.pi/4},
{x = gw/2, y = gh/2, r = random:float(0, 2*math.pi)}
}
self.spawn_offsets = {{x = -12, y = -12}, {x = 12, y = -12}, {x = 12, y = 12}, {x = -12, y = 12}, {x = 0, y = 0}} self.spawn_offsets = {{x = -12, y = -12}, {x = 12, y = -12}, {x = 12, y = 12}, {x = -12, y = 12}, {x = 0, y = 0}}
Wall{group = self.main, vertices = math.to_rectangle_vertices(-40, -40, self.x1, gh + 40), color = bg[-1]} Wall{group = self.main, vertices = math.to_rectangle_vertices(-40, -40, self.x1, gh + 40), color = bg[-1]}
@ -22,8 +27,13 @@ function Arena:init(name)
Wall{group = self.main, vertices = math.to_rectangle_vertices(self.x1, -40, self.x2, self.y1), color = bg[-1]} Wall{group = self.main, vertices = math.to_rectangle_vertices(self.x1, -40, self.x2, self.y1), color = bg[-1]}
Wall{group = self.main, vertices = math.to_rectangle_vertices(self.x1, self.y2, self.x2, gh + 40), color = bg[-1]} Wall{group = self.main, vertices = math.to_rectangle_vertices(self.x1, self.y2, self.x2, gh + 40), color = bg[-1]}
self.player = Unit{group = self.main, x = gw/2, y = gh/2, player = true, leader = true, character = 'vagrant'} self.player = Player{group = self.main, x = gw/2, y = gh/2, leader = true, character = 'vagrant'}
-- self.player:add_follower(Unit{group = self.main, player = true, character = 'seeker'}) self.player:add_follower(Player{group = self.main, character = 'vagrant'})
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
end end
@ -39,7 +49,7 @@ function Arena:update(dt)
self.ui:update(dt*slow_amount) self.ui:update(dt*slow_amount)
if input.k.pressed then if input.k.pressed then
self:spawn_enemy() self:spawn_enemy(4)
end end
end end
@ -51,10 +61,13 @@ function Arena:draw()
end end
function Arena:spawn_enemy() function Arena:spawn_enemy(n)
n = n or 1
local p = table.random(self.spawn_points) local p = table.random(self.spawn_points)
local o = table.random(self.spawn_offsets) for i = 1, n do
local leader = Unit{group = self.main, x = p.x + o.x, y = p.y + o.y, enemy = true, leader = true, character = 'seeker'} self.t:after((i-1)*0.1, function()
leader:add_follower(Unit{group = self.main, x = p.x + o.x, y = p.y + o.y, enemy = true, character = 'seeker'}) local o = table.random(self.spawn_offsets)
leader:add_follower(Unit{group = self.main, x = p.x + o.x, y = p.y + o.y, enemy = true, character = 'seeker'}) SpawnEffect{group = self.effects, x = p.x + o.x, y = p.y + o.y, action = function(x, y) Seeker{group = self.main, x = x, y = y, character = 'seeker'} end}
end)
end
end end

View File

@ -28,3 +28,18 @@ Ideaguyed the basics of the game's classes and mechanics, and implemented basic
* Cycle speed: stacks additively, starts at 2 and capped at minimum 0.5s or +300% * Cycle speed: stacks additively, starts at 2 and capped at minimum 0.5s or +300%
Perhaps I'm overengineering it already with the stats but I wanna see where this goes. From SHOOTRX it seems like figuring out stats earlier is better than later, and these seem like they have enough flexibility. Perhaps I'm overengineering it already with the stats but I wanna see where this goes. From SHOOTRX it seems like figuring out stats earlier is better than later, and these seem like they have enough flexibility.
# Day 2 - 18/02/21
Went through like 3 small refactors of how I was laying out Unit, Player and Enemy classes and how I wanted enemies to behave.
Settled on just copying enemy behavior 100% from SHOOTRX, which is likely the more correct decision since it saves a lot of time.
Right now basic player and enemy movement works, as well as melee collisions between player and enemy. To do for tomorrow:
* HP bar should be drawn on top of all player units
* Projectiles
* Areas
* Stats: attack speed, damage, cycle
* One or a few of the characters
* Port over enemy spawn logic from SHOOTRX
* Sounds

View File

@ -143,6 +143,18 @@ function Physics:set_as_triangle(w, h, body_type, tag)
end end
function Physics:connect(other, direction)
if not self.joints then self.joints = {} end
local d = Vector(0, 0)
if direction == 'right' then d:set(1, 0)
elseif direction == 'left' then d:set(-1, 0)
elseif direction == 'up' then d:set(0, -1)
elseif direction == 'down' then d:set(0, 1) end
self.joints[direction] = love.physics.newRevoluteJoint(self.body, other.body, self.x + 0.5*d.x*self.shape.w, self.y + 0.5*d.y*self.shape.h)
return self
end
-- Automatically called by the group instance this game object belongs to whenever it dies. -- Automatically called by the group instance this game object belongs to whenever it dies.
function Physics:destroy() function Physics:destroy()
if self.body then if self.body then

View File

@ -1,169 +1,62 @@
Unit = Object:extend() Unit = Object:extend()
Unit:implement(GameObject) function Unit:init_unit()
Unit:implement(Physics)
function Unit:init(args)
self:init_game_object(args)
self:set_as_rectangle(9, 9, 'dynamic', (self.player and 'player') or (self.enemy and 'enemy'))
if self.character == 'vagrant' then
self.color = fg[0]
self.visual_shape = 'rectangle'
self.classes = {'ranger', 'warrior', 'mage'}
elseif self.character == 'seeker' then
self.color = red[0]
self.visual_shape = 'capsule'
self.classes = {'seeker'}
if self.enemy then
self.enemy_behavior = 'seek'
self:calculate_stats()
self:set_as_steerable(self.v)
end
end
self:calculate_stats()
self.r = 0
self.hfx:add('hit', 1) self.hfx:add('hit', 1)
self.hp = self.max_hp
if self.leader then
self.previous_positions = {}
self.followers = {}
self.t:every(0.01, function()
table.insert(self.previous_positions, 1, {x = self.x, y = self.y, r = self.r})
if #self.previous_positions > 256 then self.previous_positions[257] = nil end
end)
end
end end
function Unit:update(dt) function Unit:draw_hp()
self:update_game_object(dt)
self:calculate_stats()
if self.player and self.leader then
if input.move_left.down then self.r = self.r - 1.66*math.pi*dt end
if input.move_right.down then self.r = self.r + 1.66*math.pi*dt end
self:set_velocity(self.v*math.cos(self.r), self.v*math.sin(self.r))
local vx, vy = self:get_velocity()
local hd = math.remap(math.abs(self.x - gw/2), 0, 192, 1, 0)
local vd = math.remap(math.abs(self.y - gh/2), 0, 108, 1, 0)
camera.x = camera.x + math.remap(vx, -100, 100, -24*hd, 24*hd)*dt
camera.y = camera.y + math.remap(vy, -100, 100, -8*vd, 8*vd)*dt
if input.move_right.down then camera.r = math.lerp_angle_dt(0.01, dt, camera.r, math.pi/256)
elseif input.move_left.down then camera.r = math.lerp_angle_dt(0.01, dt, camera.r, -math.pi/256)
elseif input.move_down.down then camera.r = math.lerp_angle_dt(0.01, dt, camera.r, math.pi/256)
elseif input.move_up.down then camera.r = math.lerp_angle_dt(0.01, dt, camera.r, -math.pi/256)
else camera.r = math.lerp_angle_dt(0.005, dt, camera.r, 0) end
end
if not self.player and self.leader then
local player = main.current.player
if self.enemy_behavior == 'seek' then
if self.being_pushed then
local v = math.length(self:get_velocity())
if v < 25 then
self.being_pushed = false
self.steering_enabled = true
self:set_damping(0)
self:set_angular_damping(0)
end
self.r = self:get_angle()
else
self:seek_point(player.x, player.y)
self:wander(25, 100, 20)
self:rotate_towards_velocity(0.5)
self.r = self:get_angle()
end
end
end
if not self.leader then
local ds
if self.parent.v >= 80 and self.parent.v <= 90 then ds = 8 end
if self.parent.v >= 20 and self.parent.v <= 30 then ds = 12 end
if not ds then error('undefined unit distance for parent velocity: ' .. self.parent.v) end
local d = ds*self.follower_index
local p = self.parent.previous_positions[d]
if p then
self:set_position(p.x, p.y)
self.r = p.r
end
end
self:set_angle(self.r)
end
function Unit:on_trigger_enter(other)
if other:is(Unit) and other.enemy then
other:push(math.length(self:get_velocity())/3.5, self:angle_to_object(other))
end
end
function Unit:push(f, r)
self.being_pushed = true
self.steering_enabled = false
self:apply_impulse(f*math.cos(r), f*math.sin(r))
self:apply_angular_impulse(random:float(-12*math.pi, 12*math.pi))
self:set_damping(1.5)
self:set_angular_damping(1.5)
end
function Unit:draw()
graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x)
if self.visual_shape == 'triangle' then
graphics.triangle(self.x, self.y, self.shape.w, self.shape.h, self.hfx.hit.f and fg[0] or self.color)
elseif self.visual_shape == 'rectangle' then
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color)
elseif self.visual_shape == 'capsule' then
graphics.rectangle(self.x, self.y, self.shape.w, 0.525*self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color)
end
graphics.pop()
graphics.push(self.x, self.y, 0, self.hfx.hit.x, self.hfx.hit.x) graphics.push(self.x, self.y, 0, self.hfx.hit.x, self.hfx.hit.x)
if self.show_hp then if self.show_hp_bar then
graphics.line(self.x - 0.5*self.shape.w, self.y - self.shape.h, self.x + 0.5*self.shape.w, self.y - self.shape.h, bg[-3], 2) graphics.line(self.x - 0.5*self.shape.w, self.y - self.shape.h, self.x + 0.5*self.shape.w, self.y - self.shape.h, bg[-3], 2)
local n = math.remap(self.hp, 0, self.max_hp, 0, 1) local n = math.remap(self.hp, 0, self.max_hp, 0, 1)
graphics.line(self.x - 0.5*self.shape.w, self.y - self.shape.h, self.x - 0.5*self.shape.w + n*self.shape.w, self.y - self.shape.h, self.hfx.hit.f and fg[0] or ((self.player and green[0]) or (self.enemy and red[0])), 2) graphics.line(self.x - 0.5*self.shape.w, self.y - self.shape.h, self.x - 0.5*self.shape.w + n*self.shape.w, self.y - self.shape.h,
self.hfx.hit.f and fg[0] or ((self:is(Player) and green[0]) or (table.any(main.current.enemies, function(v) return self:is(v) end) and red[0])), 2)
end end
graphics.pop() graphics.pop()
end end
function Unit:on_collision_enter(other, contact) function Unit:bounce(nx, ny)
if other:is(Wall) and self.leader then local vx, vy = self:get_velocity()
self.hfx:use('hit', 0.5, 200, 10, 0.1) if nx == 0 then
camera:spring_shake(2, math.pi - self.r) self:set_velocity(vx, -vy)
self.r = 2*math.pi - self.r
for i, unit in ipairs(self.followers) do end
self.t:after((i-1)*self.v*0.00185, function() if ny == 0 then
unit.hfx:use('hit', 0.25, 200, 10, 0.1) self:set_velocity(-vx, vy)
end) self.r = math.pi - self.r
end
local nx, ny = contact:getNormal()
local vx, vy = self:get_velocity()
if nx == 0 then
self:set_velocity(vx, -vy)
self.r = 2*math.pi - self.r
end
if ny == 0 then
self:set_velocity(-vx, vy)
self.r = math.pi - self.r
end
end end
end end
function Unit:add_follower(unit) function Unit:show_hp(n)
table.insert(self.followers, unit) self.show_hp_bar = true
unit.parent = self self.t:after(n or 2, function() self.show_hp_bar = false end, 'show_hp_bar')
unit.follower_index = #self.followers end
function Unit:hit(damage)
if self.dead then return end
self.hfx:use('hit', 0.25, 200, 10)
self:show_hp()
local actual_damage = self:calculate_damage(damage)
self.hp = self.hp - actual_damage
if self:is(Player) then
if actual_damage >= 20 then
camera:shake(2, 1)
slow(0.25, 1)
else
camera:shake(2, 0.5)
end
end
if self.hp <= 0 then
self.dead = true
for i = 1, random:int(4, 6) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 12}:scale_down(0.3):change_color(0.5, self.color)
end
end end
@ -174,7 +67,7 @@ function Unit:calculate_damage(dmg)
end end
function Unit:calculate_stats() function Unit:calculate_stats(first_run)
self.base_hp = 100 self.base_hp = 100
self.base_dmg = 10 self.base_dmg = 10
self.base_aspd = 1 self.base_aspd = 1
@ -214,6 +107,7 @@ function Unit:calculate_stats()
elseif class == 'seeker' then self.class_hp_m = self.class_hp_m*0.5 end elseif class == 'seeker' then self.class_hp_m = self.class_hp_m*0.5 end
end end
self.max_hp = (self.base_hp + self.class_hp_a + self.buff_hp_a)*self.class_hp_m*self.buff_hp_m self.max_hp = (self.base_hp + self.class_hp_a + self.buff_hp_a)*self.class_hp_m*self.buff_hp_m
if first_run then self.hp = self.max_hp end
for _, class in ipairs(self.classes) do for _, class in ipairs(self.classes) do
if class == 'warrior' then self.class_dmg_m = self.class_dmg_m*1.1 if class == 'warrior' then self.class_dmg_m = self.class_dmg_m*1.1
@ -251,3 +145,196 @@ function Unit:calculate_stats()
end end
self.v = (self.base_mvspd + self.class_mvspd_a + self.buff_mvspd_a)*self.class_mvspd_m*self.buff_mvspd_m self.v = (self.base_mvspd + self.class_mvspd_a + self.buff_mvspd_a)*self.class_mvspd_m*self.buff_mvspd_m
end end
Player = Object:extend()
Player:implement(GameObject)
Player:implement(Physics)
Player:implement(Unit)
function Player:init(args)
self:init_game_object(args)
self:init_unit()
if self.character == 'vagrant' then
self.color = blue[0]
self:set_as_rectangle(9, 9, 'dynamic', 'player')
self.visual_shape = 'rectangle'
self.classes = {'ranger', 'warrior', 'mage'}
end
self:calculate_stats(true)
if self.leader then
self.previous_positions = {}
self.followers = {}
self.t:every(0.01, function()
table.insert(self.previous_positions, 1, {x = self.x, y = self.y, r = self.r})
if #self.previous_positions > 256 then self.previous_positions[257] = nil end
end)
end
end
function Player:update(dt)
self:update_game_object(dt)
self:calculate_stats()
if self.leader then
if input.move_left.down then self.r = self.r - 1.66*math.pi*dt end
if input.move_right.down then self.r = self.r + 1.66*math.pi*dt end
self:set_velocity(self.v*math.cos(self.r), self.v*math.sin(self.r))
local vx, vy = self:get_velocity()
local hd = math.remap(math.abs(self.x - gw/2), 0, 192, 1, 0)
local vd = math.remap(math.abs(self.y - gh/2), 0, 108, 1, 0)
camera.x = camera.x + math.remap(vx, -100, 100, -24*hd, 24*hd)*dt
camera.y = camera.y + math.remap(vy, -100, 100, -8*vd, 8*vd)*dt
if input.move_right.down then camera.r = math.lerp_angle_dt(0.01, dt, camera.r, math.pi/256)
elseif input.move_left.down then camera.r = math.lerp_angle_dt(0.01, dt, camera.r, -math.pi/256)
elseif input.move_down.down then camera.r = math.lerp_angle_dt(0.01, dt, camera.r, math.pi/256)
elseif input.move_up.down then camera.r = math.lerp_angle_dt(0.01, dt, camera.r, -math.pi/256)
else camera.r = math.lerp_angle_dt(0.005, dt, camera.r, 0) end
self:set_angle(self.r)
else
local target_distance = 10.6*self.follower_index
local distance_sum = 0
local p
local previous = self.parent
for i, point in ipairs(self.parent.previous_positions) do
local distance_to_previous = math.distance(previous.x, previous.y, point.x, point.y)
distance_sum = distance_sum + distance_to_previous
if distance_sum >= target_distance then
p = point
break
end
previous = point
end
if p then
self:set_position(p.x, p.y)
self.r = p.r
if not self.following then
for i = 1, random:int(3, 4) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 10, color = fg[0]}:scale_down(0.3):change_color(0.5, self.color)
self.following = true
end
else
self.r = self:get_angle()
end
end
end
function Player:draw()
graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x)
if self.visual_shape == 'rectangle' then
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, self.hfx.hit.f and fg[0] or self.color)
end
graphics.pop()
self:draw_hp()
end
function Player:on_collision_enter(other, contact)
local x, y = contact:getPositions()
if other:is(Wall) then
self.hfx:use('hit', 0.5, 200, 10, 0.1)
camera:spring_shake(2, math.pi - self.r)
self:bounce(contact:getNormal())
elseif table.any(main.current.enemies, function(v) return other:is(v) end) then
other:push(random:float(25, 35), self:angle_to_object(other))
other:hit(20)
self:hit(20)
HitCircle{group = main.current.effects, x = x, y = y, rs = 6, color = fg[0], duration = 0.1}
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = self.color} end
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = other.color} end
end
end
function Player:add_follower(unit)
table.insert(self.followers, unit)
unit.parent = self
unit.follower_index = #self.followers
end
Seeker = Object:extend()
Seeker:implement(GameObject)
Seeker:implement(Physics)
Seeker:implement(Unit)
function Seeker:init(args)
self:init_game_object(args)
self:init_unit()
self:set_as_rectangle(14, 6, 'dynamic', 'enemy')
self:set_restitution(0.5)
self.color = red[0]
self.classes = {'seeker'}
self:calculate_stats(true)
self:set_as_steerable(self.v, 2000, 4*math.pi, 4)
end
function Seeker:update(dt)
self:update_game_object(dt)
self:calculate_stats()
if self.being_pushed then
local v = math.length(self:get_velocity())
if v < 25 then
self.being_pushed = false
self.steering_enabled = true
self:set_damping(0)
self:set_angular_damping(0)
end
else
local player = main.current.player
self:seek_point(player.x, player.y)
self:wander(50, 100, 20)
self:separate(16, main.current.enemies)
self:rotate_towards_velocity(0.5)
end
self.r = self:get_angle()
end
function Seeker:draw()
graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x)
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 3, 3, self.hfx.hit.f and fg[0] or self.color)
graphics.pop()
self:draw_hp()
end
function Seeker:on_collision_enter(other, contact)
local x, y = contact:getPositions()
if other:is(Wall) then
self.hfx:use('hit', 0.15, 200, 10, 0.1)
self:bounce(contact:getNormal())
elseif table.any(main.current.enemies, function(v) return other:is(v) end) then
if self.being_pushed and math.length(self:get_velocity()) > 60 then
other:hit(5)
self:hit(10)
other:push(random:float(10, 15), other:angle_to_object(self))
HitCircle{group = main.current.effects, x = x, y = y, rs = 6, color = fg[0], duration = 0.1}
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = self.color} end
end
end
end
function Seeker:push(f, r)
self.being_pushed = true
self.steering_enabled = false
self:apply_impulse(f*math.cos(r), f*math.sin(r))
self:apply_angular_impulse(random:table{random:float(-12*math.pi, -4*math.pi), random:float(4*math.pi, 12*math.pi)})
self:set_damping(1.5)
self:set_angular_damping(1.5)
end

View File

@ -291,6 +291,35 @@ end
SpawnEffect = Object:extend()
SpawnEffect:implement(GameObject)
function SpawnEffect:init(args)
self:init_game_object(args)
self.target_color = self.color or red[0]
self.color = fg[0]
self.rs = 0
self.t:tween(0.1, self, {rs = 6}, math.cubic_in_out, function()
if self.action then self.action(self.x, self.y) end
self.spring:pull(1)
for i = 1, random:int(6, 8) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.target_color, duration = random:float(0.3, 0.5), w = random:float(5, 8), v = random:float(150, 200)} end
self.t:tween(0.25, self, {rs = 0}, math.linear, function() self.dead = true end)
self.t:after(0.15, function() self.color = self.target_color end)
end)
end
function SpawnEffect:update(dt)
self:update_game_object(dt)
end
function SpawnEffect:draw()
graphics.circle(self.x, self.y, random:float(0.9, 1.1)*self.rs*self.spring.x, self.color)
end
HoverCrosshair = Object:extend() HoverCrosshair = Object:extend()
HoverCrosshair:implement(GameObject) HoverCrosshair:implement(GameObject)
function HoverCrosshair:init(args) function HoverCrosshair:init(args)
@ -489,7 +518,7 @@ end
function flash(duration, color) function flash(duration, color)
flashing = true flashing = true
flash_color = color or fg[0] flash_color = color or fg[0]
t:after(duration, function() flashing = false end, 'flash') trigger:after(duration, function() flashing = false end, 'flash')
end end
@ -498,7 +527,7 @@ function slow(amount, duration, tween_method)
duration = duration or 0.5 duration = duration or 0.5
tween_method = tween_method or math.cubic_in_out tween_method = tween_method or math.cubic_in_out
slow_amount = amount slow_amount = amount
t:tween(duration, _G, {slow_amount = 1}, tween_method, function() slow_amount = 1 end, 'slow') trigger:tween(duration, _G, {slow_amount = 1}, tween_method, function() slow_amount = 1 end, 'slow')
end end
@ -510,7 +539,7 @@ function HitCircle:init(args)
self:init_game_object(args) self:init_game_object(args)
self.rs = self.rs or 8 self.rs = self.rs or 8
self.duration = self.duration or 0.05 self.duration = self.duration or 0.05
self.color = self.color or white self.color = self.color or fg[0]
self.t:after(self.duration, function() self.dead = true end, 'die') self.t:after(self.duration, function() self.dead = true end, 'die')
return self return self
end end
@ -552,7 +581,7 @@ function HitParticle:init(args)
self.duration = self.duration or random:float(0.2, 0.6) self.duration = self.duration or random:float(0.2, 0.6)
self.w = self.w or random:float(3.5, 7) self.w = self.w or random:float(3.5, 7)
self.h = self.h or self.w/2 self.h = self.h or self.w/2
self.color = self.color or white self.color = self.color or fg[0]
self.t:tween(self.duration, self, {w = 2, h = 2, v = 0}, math.cubic_in_out, function() self.dead = true end) self.t:tween(self.duration, self, {w = 2, h = 2, v = 0}, math.cubic_in_out, function() self.dead = true end)
end end
@ -585,7 +614,7 @@ AnimationEffect:implement(GameObject)
function AnimationEffect:init(args) function AnimationEffect:init(args)
self:init_game_object(args) self:init_game_object(args)
self.animation = Animation(self.delay, self.frames, 'once', {[0] = function() self.dead = true end}) self.animation = Animation(self.delay, self.frames, 'once', {[0] = function() self.dead = true end})
self.color = self.color or white self.color = self.color or fg[0]
end end