master
a327ex 2021-03-08 01:33:01 -03:00
parent 36241e694b
commit edbcdba3dc
13 changed files with 169 additions and 101 deletions

100
arena.lua
View File

@ -12,6 +12,7 @@ function Arena:on_enter(from, level, units)
self.hfx:add('condition2', 1)
self.level = level or 1
self.floor = Group()
self.main = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile'})
self.post_main = Group()
self.effects = Group()
@ -72,6 +73,7 @@ function Arena:on_enter(from, level, units)
6, 7, 8, 9, 9, 10
}
self.max_waves = self.level_to_max_waves[self.level]
self.wave = 0
self.start_time = 3
self.t:after(1, function()
self.t:every(1, function()
@ -82,9 +84,9 @@ function Arena:on_enter(from, level, units)
alert1:play{pitch = 1.2, volume = 0.5}
camera:shake(4, 0.25)
SpawnEffect{group = self.effects, x = gw/2, y = gh/2 - 48}
self.wave = 0
self.t:every(function() return #self.main:get_objects_by_classes(self.enemies) <= 0 end, function()
self.wave = self.wave + 1
if self.wave > self.max_waves then return end
self.hfx:use('condition1', 0.25, 200, 10)
self.hfx:pull('condition2', 0.0625)
self.t:after(0.5, function()
@ -92,8 +94,9 @@ function Arena:on_enter(from, level, units)
local spawn_points = {left = {x = self.x1 + 32, y = gh/2}, middle = {x = gw/2, y = gh/2}, right = {x = self.x2 - 32, y = gh/2}}
self:spawn_n_enemies(spawn_points[spawn_type], nil, 8 + (self.wave-1)*2)
end)
end, self.max_waves, function() self.can_quit = true end)
end, self.max_waves+1)
end)
self.t:every(function() return #self.main:get_objects_by_classes(self.enemies) <= 0 and self.wave > self.max_waves end, function() self.can_quit = true end)
end)
elseif self.win_condition == 'enemy_kill' then
@ -119,12 +122,13 @@ function Arena:on_enter(from, level, units)
SpawnEffect{group = self.effects, x = gw/2, y = gh/2 - 48}
self:spawn_distributed_enemies()
self.t:every(2, function()
if love.timer.getTime() - self.last_spawn_enemy_time >= self.enemy_spawn_delay then
if love.timer.getTime() - self.last_spawn_enemy_time >= self.enemy_spawn_delay and #self.main:get_objects_by_class(self.enemies) < self.enemies_to_kill and not self.transitioning then
self:spawn_distributed_enemies()
end
end, nil, nil, 'spawn_enemies')
end)
end)
self.t:every(function() return #self.main:get_objects_by_classes(self.enemies) <= 0 and self.enemies_killed >= self.enemies_to_kill end, function() self.can_quit = true end)
elseif self.win_condition == 'time' then
self.level_to_time_left = {
@ -149,15 +153,27 @@ function Arena:on_enter(from, level, units)
self.time_left = self.time_left - 1
self.hfx:use('condition1', 0.25, 200, 10)
self.hfx:pull('condition2', 0.0625)
end, self.time_left, function() self.can_quit = true end)
end, self.time_left)
self.t:every_immediate(2, function()
if #self.main:get_objects_by_classes(self.enemies) <= 0 or love.timer.getTime() - self.last_spawn_enemy_time >= 8 then
if #self.main:get_objects_by_classes(self.enemies) <= 0 or love.timer.getTime() - self.last_spawn_enemy_time >= 8 and not self.transitioning then
self:spawn_distributed_enemies()
end
end, self.time_left/2)
end)
end)
self.t:every(function() return #self.main:get_objects_by_classes(self.enemies) <= 0 and self.time_left <= 0 end, function() self.can_quit = true end)
end
if self.level == 1 then
local t1 = Text2{group = self.floor, x = gw/2, y = gh/2 + 12, sx = 0.6, sy = 0.6, lines = {{text = '[light_bg]<- or a -> or d', font = fat_font, alignment = 'center'}}}
local t2 = Text2{group = self.floor, x = gw/2, y = gh/2 + 28, lines = {{text = '[light_bg]turn left turn right', font = pixul_font, alignment = 'center'}}}
local t3 = Text2{group = self.floor, x = gw/2, y = gh/2 + 56, sx = 0.6, sy = 0.6, lines = {{text = '[light_bg]n - mute sfx', font = fat_font, alignment = 'center'}}}
local t4 = Text2{group = self.floor, x = gw/2, y = gh/2 + 78, sx = 0.6, sy = 0.6, lines = {{text = '[light_bg]m - mute music', font = fat_font, alignment = 'center'}}}
t1.t:after(8, function() t1.t:tween(0.2, t1, {sy = 0}, math.linear, function() t1.sy = 0 end) end)
t2.t:after(8, function() t2.t:tween(0.2, t2, {sy = 0}, math.linear, function() t2.sy = 0 end) end)
t3.t:after(8, function() t3.t:tween(0.2, t3, {sy = 0}, math.linear, function() t3.sy = 0 end) end)
t4.t:after(8, function() t4.t:tween(0.2, t4, {sy = 0}, math.linear, function() t4.sy = 0 end) end)
end
-- Calculate class levels
@ -219,48 +235,58 @@ function Arena:update(dt)
if self.enchanter_level == 1 then self.enchanter_dmg_m = 1.25
else self.enchanter_dmg_m = 1 end
self.floor:update(dt*slow_amount)
self.main:update(dt*slow_amount)
self.post_main:update(dt*slow_amount)
self.effects:update(dt*slow_amount)
self.ui:update(dt*slow_amount)
if self.win_condition == 'enemy_kill' then
if self.can_quit then
self.t:after(2, function()
TransitionEffect{group = main.transitions, x = self.player.x, y = self.player.y, color = self.color, transition_action = function()
main:add(BuyScreen'buy_screen')
main:go_to('buy_screen', self, self.level, self.color)
end, text = Text({
{text = '[bg]resources gained: ' .. tostring(self.resources_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[bg]interest: ' .. tostring(math.floor(resource/10)), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[bg]total: ' .. tostring(self.resources_gained + math.floor(resource/10)), font = pixul_font, alignment = 'center'}
}, global_text_tags)}
end)
end
else
if self.can_quit and #self.main:get_objects_by_classes(self.enemies) <= 0 then
self.can_quit = false
self.t:after(2, function()
if #self.main:get_objects_by_classes(self.enemies) > 0 then
self.can_quit = true
else
TransitionEffect{group = main.transitions, x = self.player.x, y = self.player.y, color = self.color, transition_action = function()
main:add(BuyScreen'buy_screen')
main:go_to('buy_screen', self, self.level, self.color)
end, text = Text({
{text = '[bg]resources gained: ' .. tostring(self.resources_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[bg]interest: ' .. tostring(math.floor(resource/10)), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[bg]total: ' .. tostring(self.resources_gained + math.floor(resource/10)), font = pixul_font, alignment = 'center'}
}, global_text_tags)}
end
end)
end
if self.can_quit and #self.main:get_objects_by_classes(self.enemies) <= 0 then
self.can_quit = false
self.transitioning = true
if not self.arena_clear_text then self.arena_clear_text = Text2{group = self.ui, x = gw/2, y = gh/2 - 48, lines = {{text = '[wavy_mid, cbyc]arena clear!', font = fat_font, alignment = 'center'}}} end
self.t:after(3, function()
self.transitioning = false
ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
TransitionEffect{group = main.transitions, x = self.player.x, y = self.player.y, color = self.color, transition_action = function(t)
main:add(BuyScreen'buy_screen')
main:go_to('buy_screen', self, self.level, self.color)
t.t:after(0.1, function()
t.text:set_text({
{text = '[nudge_down, bg]resources gained: ' .. tostring(self.resources_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[wavy_lower, bg]interest: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
})
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
t.t:after(0.2, function()
t.text:set_text({
{text = '[wavy_lower, bg]resources gained: ' .. tostring(self.resources_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[nudge_down, bg]interest: ' .. tostring(math.floor(resource/10)), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
})
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
t.t:after(0.2, function()
t.text:set_text({
{text = '[wavy_lower, bg]resources gained: ' .. tostring(self.resources_gained), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[wavy_lower, bg]interest: ' .. tostring(math.floor(resource/10)), font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[nudge_down, bg]total: ' .. tostring(self.resources_gained + math.floor(resource/10)), font = pixul_font, alignment = 'center'}
})
_G[random:table{'coins1', 'coins2', 'coins3'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end)
end)
end)
end, text = Text({
{text = '[wavy_lower, bg]resources gained: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[wavy_lower, bg]interest: 0', font = pixul_font, alignment = 'center', height_multiplier = 1.5},
{text = '[wavy_lower, bg]total: 0', font = pixul_font, alignment = 'center'}
}, global_text_tags)}
end, 'transition')
end
end
function Arena:draw()
self.floor:draw()
self.main:draw()
self.post_main:draw()
self.effects:draw()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -25,7 +25,7 @@ function BuyScreen:on_enter(from, level)
self.cards[3] = PairCard{group = self.main, x = gw/2, y = 225, w = gw, h = gh/4, unit_1 = random:table_remove(units), unit_2 = random:table_remove(units), i = 3, parent = self}
self.title_sy = 1
self.title = Text({{text = '[fg]choose your initial party', font = pixul_font, alignment = 'center'}}, global_text_tags)
self.title = Text({{text = '[wavy_mid, fg]choose your initial party', font = pixul_font, alignment = 'center'}}, global_text_tags)
end
end
@ -43,6 +43,8 @@ function BuyScreen:update(dt)
for i = 1, 3 do self.cards[i]:unselect() end
self.cards[self.selected_card_index]:select()
pop1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
player_hit_wall1:play{pitch = r, volume = 0.5}
end
if input.move_down.pressed then
self.selected_card_index = self.selected_card_index + 1
@ -50,11 +52,13 @@ function BuyScreen:update(dt)
for i = 1, 3 do self.cards[i]:unselect() end
self.cards[self.selected_card_index]:select()
pop1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
player_hit_wall1:play{pitch = r, volume = 0.5}
end
if input.enter.pressed and not self.transitioning then
ui_switch:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_transition:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_transition1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
self.transitioning = true
self.t:tween(0.1, self, {title_sy = 0}, math.linear, function() self.title_sy = 0; self.title = nil end)

View File

@ -336,3 +336,8 @@ I wonder if I should try implementing this now or leave it for the next game.
Transition from first screen to first level works. Polish it up tomorrow with more sounds, tutorial markers (left/right arrows) and more consistency and anticipation when a level ends, and then start work on the main buy
screen.
# Day 19 - 07/03/21
First screen, transition from it to arena, arena and transition from arena to next screen are 99% complete and polished. There's one small bug left that I can't replicate where it will end the level right away, but I can't tell
with which win condition it's happening... I'll fix it in time. Tomorrow I can get started on the main buy screen for real.

View File

@ -51,7 +51,7 @@ text = Text({
-- If 'alignment_width' is set to a specific line then that line will be automatically set to that width, and if it is the biggest then .w will also be set to that value.
Text = Object:extend()
function Text:init(text_data, text_tags)
self.trigger = Trigger()
self.t = Trigger()
self.text_data = text_data
self.text_tags = text_tags
self.white = Color(1, 1, 1, 1)
@ -61,7 +61,7 @@ end
function Text:update(dt)
self.trigger:update(dt)
self.t:update(dt)
self:format_text()
for _, line in ipairs(self.lines) do
for i, c in ipairs(line.characters) do
@ -116,8 +116,8 @@ function Text:format_text()
for i, c in ipairs(line.characters) do
c.x = x
c.y = y
c.sx = line.sx or 1
c.sy = line.sy or 1
c.sx = line.sx or c.sx or 1
c.sy = line.sy or c.sy or 1
x = x + line.font:get_text_width(c.character)
end
y = y + h

View File

@ -17,8 +17,13 @@ function init()
input:bind('enter', {'space', 'return'})
local s = {tags = {sfx}}
ui_switch = Sound('Switch.ogg', s)
ui_transition = Sound('Wind Bolt 8.ogg', s)
ui_switch1 = Sound('Switch.ogg', s)
ui_switch2 = Sound('Switch 3.ogg', s)
ui_transition1 = Sound('Wind Bolt 8.ogg', s)
ui_transition2 = Sound('Wind Bolt 12.ogg', s)
coins1 = Sound('Coins 7.ogg', s)
coins2 = Sound('Coins 8.ogg', s)
coins3 = Sound('Coins 9.ogg', s)
shoot1 = Sound('Shooting Projectile (Classic) 11.ogg', s)
archer1 = Sound('Releasing Bow String 1.ogg', s)
wizard1 = Sound('Wind Bolt 20.ogg', s)
@ -233,7 +238,34 @@ function init()
['engineer'] = function(lvl) return get_character_stat_string('engineer', lvl) end,
}
units = {}
class_stat_multipliers = {
['warrior'] = {hp = 1.4, dmg = 1.1, aspd = 0.9, area_dmg = 1, area_size = 1, def = 1.25, mvspd = 0.9},
['ranger'] = {hp = 1, dmg = 1.2, aspd = 1.5, area_dmg = 1, area_size = 1, def = 0.9, mvspd = 1.2},
['healer'] = {hp = 1.2, dmg = 1, aspd = 0.5, area_dmg = 1, area_size = 1, def = 1.2, mvspd = 1},
['mage'] = {hp = 0.6, dmg = 1.4, aspd = 1, area_dmg = 1.25, area_size = 1.2, def = 0.75, mvspd = 1},
['rogue'] = {hp = 0.8, dmg = 1.3, aspd = 1.1, area_dmg = 0.6, area_size = 0.6, def = 0.8, mvspd = 1.4},
['nuker'] = {hp = 0.9, dmg = 1, aspd = 0.75, area_dmg = 1.5, area_size = 1.5, def = 1, mvspd = 1},
['conjurer'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 1},
['enchanter'] = {hp = 1.2, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1.2, mvspd = 1.2},
['psy'] = {hp = 1.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 0.5, mvspd = 1},
['seeker'] = {hp = 0.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.3},
['saboteur'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 1.4},
}
local ylb1 = function(lvl) return (lvl == 1 and 'yellow' or 'light_bg') end
local ylb2 = function(lvl) return (lvl == 2 and 'yellow' or 'light_bg') end
class_descriptions = {
['ranger'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']10%[' .. ylb2(lvl) .. ']/20% [fg]chance to release a barrage on attack' end,
['warrior'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']+25[' .. ylb2(lvl) .. ']/+50 [fg]defense to allied warriors' end,
['mage'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']-15[' .. ylb2(lvl) .. ']/-30 [fg]enemy defense' end,
['nuker'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']+15%[' .. ylb2(lvl) .. ']/+25% [fg]area damage and size' end,
['rogue'] = function(lvl) return '[' .. ylb1(lvl) .. ']2[' .. ylb2(lvl) .. ']/4 [fg]- [' .. ylb1(lvl) .. ']10%[' .. ylb2(lvl) .. ']/20% [fg]chance to crit, dealing [yellow]4x[] damage' end,
['healer'] = function(lvl) return '[' .. ylb1(lvl) .. ']3 [fg]- [' .. ylb1(lvl) .. ']+25% [fg]healing effectiveness' end,
['conjurer'] = function(lvl) return '[' .. ylb1(lvl) .. ']2 [fg]- [' .. ylb1(lvl) .. ']+25% [fg]construct damage and duration' end,
['enchanter'] = function(lvl) return '[' .. ylb1(lvl) .. ']3 [fg]- [' .. ylb1(lvl) .. ']+25% [fg]damage to all allies' end,
['psy'] = function(lvl) return 'damage taken by psy units is reflected to enemies at double its value' end,
}
resource = 0
main = Main()

View File

@ -237,70 +237,26 @@ function Unit:calculate_stats(first_run)
self.buff_mvspd_m = 1
end
for _, class in ipairs(self.classes) do
if class == 'warrior' then self.class_hp_m = self.class_hp_m*1.4
elseif class == 'mage' then self.class_hp_m = self.class_hp_m*0.6
elseif class == 'healer' then self.class_hp_m = self.class_hp_m*1.2
elseif class == 'nuker' then self.class_hp_m = self.class_hp_m*0.9
elseif class == 'rogue' then self.class_hp_m = self.class_hp_m*0.8
elseif class == 'enchanter' then self.class_hp_m = self.class_hp_m*1.2
elseif class == 'psy' then self.class_hp_m = self.class_hp_m*1.5
elseif class == 'seeker' then self.class_hp_m = self.class_hp_m*0.5 end
end
for _, class in ipairs(self.classes) do self.class_hp_m = self.class_hp_m*class_stat_multipliers[class].hp end
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
if class == 'warrior' then self.class_dmg_m = self.class_dmg_m*1.1
elseif class == 'ranger' then self.class_dmg_m = self.class_dmg_m*1.2
elseif class == 'rogue' then self.class_dmg_m = self.class_dmg_m*1.3
elseif class == 'mage' then self.class_dmg_m = self.class_dmg_m*1.4
elseif class == 'ninja_clone' then self.class_dmg_m = self.class_dmg_m*1.5 end
end
for _, class in ipairs(self.classes) do self.class_dmg_m = self.class_dmg_m*class_stat_multipliers[class].dmg end
self.dmg = (self.base_dmg + self.class_dmg_a + self.buff_dmg_a)*self.class_dmg_m*self.buff_dmg_m
for _, class in ipairs(self.classes) do
if class == 'warrior' then self.class_aspd_m = self.class_aspd_m*0.9
elseif class == 'ranger' then self.class_aspd_m = self.class_aspd_m*1.5
elseif class == 'healer' then self.class_aspd_m = self.class_aspd_m*0.5
elseif class == 'rogue' then self.class_aspd_m = self.class_aspd_m*1.1
elseif class == 'nuker' then self.class_aspd_m = self.class_aspd_m*0.75 end
end
for _, class in ipairs(self.classes) do self.class_aspd_m = self.class_aspd_m*class_stat_multipliers[class].aspd end
self.aspd_m = 1/(self.base_aspd_m*self.class_aspd_m*self.buff_aspd_m)
for _, class in ipairs(self.classes) do
if class == 'mage' then self.class_area_dmg_m = self.class_area_dmg_m*1.25
elseif class == 'nuker' then self.class_area_dmg_m = self.class_area_dmg_m*1.5
elseif class == 'rogue' then self.class_area_dmg_m = self.class_area_dmg_m*0.6 end
end
for _, class in ipairs(self.classes) do self.class_area_dmg_m = self.class_area_dmg_m*class_stat_multipliers[class].area_dmg end
self.area_dmg_m = self.base_area_dmg_m*self.class_area_dmg_m*self.buff_area_dmg_m
for _, class in ipairs(self.classes) do
if class == 'mage' then self.class_area_size_m = self.class_area_size_m*1.2
elseif class == 'nuker' then self.class_area_size_m = self.class_area_size_m*1.3
elseif class == 'rogue' then self.class_area_size_m = self.class_area_size_m*0.6 end
end
for _, class in ipairs(self.classes) do self.class_area_size_m = self.class_area_size_m*class_stat_multipliers[class].area_size end
self.area_size_m = self.base_area_size_m*self.class_area_size_m*self.buff_area_size_m
for _, class in ipairs(self.classes) do
if class == 'warrior' then self.class_def_m = self.class_def_m*1.25
elseif class == 'ranger' then self.class_def_m = self.class_def_m*0.9
elseif class == 'mage' then self.class_def_m = self.class_def_m*0.75
elseif class == 'rogue' then self.class_def_m = self.class_def_m*0.8
elseif class == 'enchanter' then self.class_def_m = self.class_def_m*1.2
elseif class == 'psy' then self.class_def_m = self.class_def_m*0.5
elseif class == 'healer' then self.class_def_m = self.class_def_m*1.2 end
end
for _, class in ipairs(self.classes) do self.class_def_m = self.class_def_m*class_stat_multipliers[class].def end
self.def = (self.base_def + self.class_def_a + self.buff_def_a)*self.class_def_m*self.buff_def_m
for _, class in ipairs(self.classes) do
if class == 'warrior' then self.class_mvspd_m = self.class_mvspd_m*0.9
elseif class == 'ranger' then self.class_mvspd_m = self.class_mvspd_m*1.2
elseif class == 'rogue' then self.class_mvspd_m = self.class_mvspd_m*1.4
elseif class == 'enchanter' then self.class_mvspd_m = self.class_mvspd_m*1.2
elseif class == 'seeker' then self.class_mvspd_m = self.class_mvspd_m*0.3
elseif class == 'saboteur' then self.class_mvspd_m = self.class_mvspd_m*1.4 end
end
for _, class in ipairs(self.classes) do self.class_mvspd_m = self.class_mvspd_m*class_stat_multipliers[class].mvspd end
self.v = (self.base_mvspd + self.class_mvspd_a + self.buff_mvspd_a)*self.class_mvspd_m*self.buff_mvspd_m
end

View File

@ -484,7 +484,8 @@ function Player:on_collision_enter(other, contact)
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)
if self.character == 'vagrant' or self.character == 'psykeeper' then other:hit(40)
else other:hit(20) end
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

View File

@ -1,3 +1,4 @@
-- Shared functions and classes for projects using JUGGLRX's visual style.
function shared_init()
local colors = {
white = ColorRamp(Color(1, 1, 1, 1), 0.025),
@ -388,7 +389,7 @@ function TransitionEffect:init(args)
self.t:tween(0.1, self, {text_sx = 1, text_sy = 1}, math.cubic_in_out)
end)
self.t:tween(0.6, self, {rs = 1.2*gw}, math.linear, function()
if self.transition_action then self.transition_action(unpack(self.transition_action_args or {})) end
if self.transition_action then self:transition_action(unpack(self.transition_action_args or {})) end
self.t:after(0.3, function()
self.x, self.y = gw/2, gh/2
self.t:after(0.6, function() self.t:tween(0.05, self, {text_sx = 0, text_sy = 0}, math.cubic_in_out) end)
@ -419,6 +420,7 @@ end
local invisible = Color(1, 1, 1, 0)
global_text_tags = {
red = TextTag{draw = function(c, i, text) graphics.set_color(red[0]) end},
orange = TextTag{draw = function(c, i, text) graphics.set_color(orange[0]) end},
@ -427,11 +429,53 @@ global_text_tags = {
purple = TextTag{draw = function(c, i, text) graphics.set_color(purple[0]) end},
blue = TextTag{draw = function(c, i, text) graphics.set_color(blue[0]) end},
bg = TextTag{draw = function(c, i, text) graphics.set_color(bg[0]) end},
light_bg = TextTag{draw = function(c, i, text) graphics.set_color(bg[5]) end},
fg = TextTag{draw = function(c, i, text) graphics.set_color(fg[0]) end},
wavy = TextTag{update = function(c, dt, i, text) c.oy = 2*math.sin(4*time + i) end},
wavy_lower = TextTag{update = function(c, dt, i, text) c.oy = math.sin(4*time + i) end},
wavy_mid = TextTag{update = function(c, dt, i, text) c.oy = 0.75*math.sin(3*time + i) end},
wavy_lower = TextTag{update = function(c, dt, i, text) c.oy = 0.25*math.sin(2*time + i) end},
cbyc = TextTag{init = function(c, i, text)
c.color = invisible
text.t:after((i-1)*0.15, function()
c.color = red[0]
camera:shake(3, 0.075)
pop1:play{pitch = random:float(0.95, 1.05), volume = 0.35}
end)
end, draw = function(c, i, text)
graphics.set_color(c.color)
end},
nudge_down = TextTag{init = function(c, i, text)
c.oy = -4
text.t:tween(0.1, c, {oy = 0}, math.linear)
end},
}
Text2 = Object:extend()
Text2:implement(GameObject)
function Text2:init(args)
self:init_game_object(args)
self.text = Text(args.lines, global_text_tags)
end
function Text2:update(dt)
self:update_game_object(dt)
self.text:update(dt)
end
function Text2:draw()
self.text:draw(self.x, self.y, self.r, self.sx, self.sy)
end
InfoText = Object:extend()
InfoText:implement(GameObject)
function InfoText:init(args)