Loop update 1/4

master
a327ex 2021-06-23 00:53:37 -03:00
parent 2453a18d9c
commit dbdd585c48
8 changed files with 539 additions and 275 deletions

221
arena.lua
View File

@ -348,229 +348,12 @@ function Arena:update(dt)
end
if self.shop_text then self.shop_text:update(dt) end
-- print(self.enemy_spawns_prevented)
if input.escape.pressed and not self.transitioning and not self.in_credits and not self.choosing_passives then
if not self.paused then
input:set_mouse_visible(true)
trigger:tween(0.25, _G, {slow_amount = 0}, math.linear, function()
slow_amount = 0
self.paused = true
self.paused_t1 = Text2{group = self.ui, x = gw/2, y = gh/2 - 108, sx = 0.6, sy = 0.6, lines = {{text = '[bg10]<-, a or m1 ->, d or m2', font = fat_font, alignment = 'center'}}}
self.paused_t2 = Text2{group = self.ui, x = gw/2, y = gh/2 - 92, lines = {{text = '[bg10]turn left turn right', font = pixul_font, alignment = 'center'}}}
self.ng_t = Text2{group = self.ui, x = gw/2 + 63, y = gh - 50, lines = {{text = '[bg10]current: ' .. current_new_game_plus, font = pixul_font, alignment = 'center'}}}
self.resume_button = Button{group = self.ui, x = gw/2, y = gh - 225, force_update = true, button_text = 'resume game (esc)', fg_color = 'bg10', bg_color = 'bg', action = function(b)
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
slow_amount = 1
self.paused = false
if self.paused_t1 then self.paused_t1.dead = true; self.paused_t1 = nil end
if self.paused_t2 then self.paused_t2.dead = true; self.paused_t2 = nil end
if self.ng_t then self.ng_t.dead = true; self.ng_t = nil end
if self.resume_button then self.resume_button.dead = true; self.resume_button = nil end
if self.restart_button then self.restart_button.dead = true; self.restart_button = nil end
if self.mouse_button then self.mouse_button.dead = true; self.mouse_button = nil end
if self.dark_transition_button then self.dark_transition_button.dead = true; self.dark_transition_button = nil end
if self.sfx_button then self.sfx_button.dead = true; self.sfx_button = nil end
if self.music_button then self.music_button.dead = true; self.music_button = nil end
if self.video_button_1 then self.video_button_1.dead = true; self.video_button_1 = nil end
if self.video_button_2 then self.video_button_2.dead = true; self.video_button_2 = nil end
if self.video_button_3 then self.video_button_3.dead = true; self.video_button_3 = nil end
if self.quit_button then self.quit_button.dead = true; self.quit_button = nil end
if self.screen_shake_button then self.screen_shake_button.dead = true; self.screen_shake_button = nil end
if self.screen_movement_button then self.screen_movement_button.dead = true; self.screen_movement_button = nil end
if self.cooldown_snake_button then self.cooldown_snake_button.dead = true; self.cooldown_snake_button = nil end
if self.arrow_snake_button then self.arrow_snake_button.dead = true; self.arrow_snake_button = nil end
if self.ng_plus_plus_button then self.ng_plus_plus_button.dead = true; self.ng_plus_plus_button = nil end
if self.ng_plus_minus_button then self.ng_plus_minus_button.dead = true; self.ng_plus_minus_button = nil end
system.save_state()
end, 'pause')
end}
self.restart_button = Button{group = self.ui, x = gw/2, y = gh - 200, force_update = true, button_text = 'restart run (r)', fg_color = 'bg10', bg_color = 'bg', action = function(b)
self.transitioning = true
ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
TransitionEffect{group = main.transitions, x = gw/2, y = gh/2, color = state.dark_transitions and bg[-2] or fg[0], transition_action = function()
slow_amount = 1
gold = 3
passives = {}
main_song_instance:stop()
run_passive_pool = {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance'
}
max_units = 7 + current_new_game_plus
main:add(BuyScreen'buy_screen')
locked_state = nil
system.save_run()
main:go_to('buy_screen', 1, {}, passives, 1, 0)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end}
self.mouse_button = Button{group = self.ui, x = gw/2 - 57, y = gh - 150, force_update = true, button_text = 'mouse control: ' .. tostring(state.mouse_control and 'yes' or 'no'), fg_color = 'bg10', bg_color = 'bg',
action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.mouse_control = not state.mouse_control
b:set_text('mouse control: ' .. tostring(state.mouse_control and 'yes' or 'no'))
input:set_mouse_visible(state.mouse_control)
end}
self.dark_transition_button = Button{group = self.ui, x = gw/2 + 64, y = gh - 150, force_update = true, button_text = 'dark transitions: ' .. tostring(state.dark_transitions and 'yes' or 'no'),
fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.dark_transitions = not state.dark_transitions
b:set_text('dark transitions: ' .. tostring(state.dark_transitions and 'yes' or 'no'))
end}
self.sfx_button = Button{group = self.ui, x = gw/2 - 46, y = gh - 175, force_update = true, button_text = 'sounds (n): ' .. tostring(state.volume_muted and 'no' or 'yes'), fg_color = 'bg10', bg_color = 'bg',
action = function(b)
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
if sfx.volume == 0.5 then
sfx.volume = 0
state.volume_muted = true
elseif sfx.volume == 0 then
sfx.volume = 0.5
state.volume_muted = false
end
b:set_text('sounds (n): ' .. tostring(state.volume_muted and 'no' or 'yes'))
end}
self.music_button = Button{group = self.ui, x = gw/2 + 46, y = gh - 175, force_update = true, button_text = 'music (m): ' .. tostring(state.music_muted and 'no' or 'yes'), fg_color = 'bg10', bg_color = 'bg',
action = function(b)
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
if music.volume == 0.5 then
music.volume = 0
state.music_muted = true
elseif music.volume == 0 then
music.volume = 0.5
state.music_muted = false
end
b:set_text('music (m): ' .. tostring(state.music_muted and 'no' or 'yes'))
end}
self.video_button_1 = Button{group = self.ui, x = gw/2 - 86, y = gh - 125, force_update = true, button_text = 'window size-', fg_color = 'bg10', bg_color = 'bg', action = function()
if sx > 1 and sy > 1 then
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
sx, sy = sx - 1, sy - 1
love.window.setMode(480*sx, 270*sy)
state.sx, state.sy = sx, sy
state.fullscreen = false
end
end}
self.video_button_2 = Button{group = self.ui, x = gw/2, y = gh - 125, force_update = true, button_text = 'window size+', fg_color = 'bg10', bg_color = 'bg', action = function()
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
sx, sy = sx + 1, sy + 1
love.window.setMode(480*sx, 270*sy)
state.sx, state.sy = sx, sy
state.fullscreen = false
end}
self.video_button_3 = Button{group = self.ui, x = gw/2 + 79, y = gh - 125, force_update = true, button_text = 'fullscreen', fg_color = 'bg10', bg_color = 'bg', action = function()
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
local _, _, flags = love.window.getMode()
local window_width, window_height = love.window.getDesktopDimensions(flags.display)
sx, sy = window_width/480, window_height/270
ww, wh = window_width, window_height
love.window.setMode(window_width, window_height, {fullscreen = true})
state.fullscreen = true
end}
self.screen_shake_button = Button{group = self.ui, x = gw/2 - 57, y = gh - 100, w = 110, force_update = true, button_text = '[bg10]screen shake: ' .. tostring(state.no_screen_shake and 'no' or 'yes'),
fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.no_screen_shake = not state.no_screen_shake
b:set_text('screen shake: ' .. tostring(state.no_screen_shake and 'no' or 'yes'))
end}
self.cooldown_snake_button = Button{group = self.ui, x = gw/2 + 75, y = gh - 100, w = 145, force_update = true, button_text = '[bg10]cooldowns on snake: ' .. tostring(state.cooldown_snake and 'yes' or 'no'),
fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.cooldown_snake = not state.cooldown_snake
b:set_text('cooldowns on snake: ' .. tostring(state.cooldown_snake and 'yes' or 'no'))
end}
self.arrow_snake_button = Button{group = self.ui, x = gw/2 + 65, y = gh - 75, w = 125, force_update = true, button_text = '[bg10]arrow on snake: ' .. tostring(state.arrow_snake and 'yes' or 'no'),
fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.arrow_snake = not state.arrow_snake
b:set_text('arrow on snake: ' .. tostring(state.arrow_snake and 'yes' or 'no'))
end}
self.screen_movement_button = Button{group = self.ui, x = gw/2 - 69, y = gh - 75, w = 135, force_update = true, button_text = '[bg10]screen movement: ' .. tostring(state.no_screen_movement and 'no' or 'yes'),
fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.no_screen_movement = not state.no_screen_movement
if state.no_screen_movement then
camera.x, camera.y = gw/2, gh/2
camera.r = 0
end
b:set_text('screen movement: ' .. tostring(state.no_screen_movement and 'no' or 'yes'))
end}
self.ng_plus_minus_button = Button{group = self.ui, x = gw/2 - 58, y = gh - 50, force_update = true, button_text = 'NG+ down', fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
current_new_game_plus = math.clamp(current_new_game_plus - 1, 0, 5)
state.current_new_game_plus = current_new_game_plus
self.ng_t.text:set_text({{text = '[bg10]current: ' .. current_new_game_plus, font = pixul_font, alignment = 'center'}})
end}
self.ng_plus_plus_button = Button{group = self.ui, x = gw/2 + 5, y = gh - 50, force_update = true, button_text = 'NG+ up', fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
current_new_game_plus = math.clamp(current_new_game_plus + 1, 0, new_game_plus)
state.current_new_game_plus = current_new_game_plus
self.ng_t.text:set_text({{text = '[bg10]current: ' .. current_new_game_plus, font = pixul_font, alignment = 'center'}})
end}
self.quit_button = Button{group = self.ui, x = gw/2, y = gh - 25, force_update = true, button_text = 'quit', fg_color = 'bg10', bg_color = 'bg', action = function()
system.save_state()
steam.shutdown()
love.event.quit()
end}
end, 'pause')
open_options(self)
else
if not state.mouse_control then
input:set_mouse_visible(false)
end
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
slow_amount = 1
self.paused = false
if self.paused_t1 then self.paused_t1.dead = true; self.paused_t1 = nil end
if self.paused_t2 then self.paused_t2.dead = true; self.paused_t2 = nil end
if self.ng_t then self.ng_t.dead = true; self.ng_t = nil end
if self.resume_button then self.resume_button.dead = true; self.resume_button = nil end
if self.restart_button then self.restart_button.dead = true; self.restart_button = nil end
if self.mouse_button then self.mouse_button.dead = true; self.mouse_button = nil end
if self.dark_transition_button then self.dark_transition_button.dead = true; self.dark_transition_button = nil end
if self.sfx_button then self.sfx_button.dead = true; self.sfx_button = nil end
if self.music_button then self.music_button.dead = true; self.music_button = nil end
if self.video_button_1 then self.video_button_1.dead = true; self.video_button_1 = nil end
if self.video_button_2 then self.video_button_2.dead = true; self.video_button_2 = nil end
if self.video_button_3 then self.video_button_3.dead = true; self.video_button_3 = nil end
if self.screen_shake_button then self.screen_shake_button.dead = true; self.screen_shake_button = nil end
if self.screen_movement_button then self.screen_movement_button.dead = true; self.screen_movement_button = nil end
if self.cooldown_snake_button then self.cooldown_snake_button.dead = true; self.cooldown_snake_button = nil end
if self.arrow_snake_button then self.arrow_snake_button.dead = true; self.arrow_snake_button = nil end
if self.quit_button then self.quit_button.dead = true; self.quit_button = nil end
if self.ng_plus_plus_button then self.ng_plus_plus_button.dead = true; self.ng_plus_plus_button = nil end
if self.ng_plus_minus_button then self.ng_plus_minus_button.dead = true; self.ng_plus_minus_button = nil end
system.save_state()
end, 'pause')
close_options(self)
end
end

View File

@ -165,6 +165,7 @@ function BuyScreen:on_enter(from, level, units, passives, shop_level, shop_xp)
trigger:tween(1, main_song_instance, {volume = 0.2}, math.linear)
--[[
if self.level == 1 then
self.screen_text = Text2{group = self.ui, x = gw/2, y = gh/2, lines = {
{text = '[bg3]press K if screen is too large', font = pixul_font, alignment = 'center'},
@ -174,6 +175,7 @@ function BuyScreen:on_enter(from, level, units, passives, shop_level, shop_xp)
self.t:tween(0.2, self.screen_text, {sy = 0}, math.linear, function() self.screen_text.sy = 0 end)
end)
end
]]--
locked_state = {locked = self.locked, cards = {self.cards[1] and self.cards[1].unit, self.cards[2] and self.cards[2].unit, self.cards[3] and self.cards[3].unit}}
system.save_run(self.level, gold, self.units, self.passives, self.shop_level, self.shop_xp, run_passive_pool, locked_state)
@ -187,7 +189,7 @@ function BuyScreen:update(dt)
self:update_game_object(dt*slow_amount)
if not self.in_tutorial then
if not self.in_tutorial and not self.paused then
self.main:update(dt*slow_amount)
self.effects:update(dt*slow_amount)
self.ui:update(dt*slow_amount)
@ -198,6 +200,7 @@ function BuyScreen:update(dt)
if self.ng_text then self.ng_text:update(dt) end
if self.level_text then self.level_text:update(dt) end
else
self.ui:update(dt*slow_amount)
self.tutorial:update(dt*slow_amount)
end
@ -205,6 +208,14 @@ function BuyScreen:update(dt)
self:quit_tutorial()
end
if input.escape.pressed and not self.transitioning and not self.in_tutorial then
if not self.paused then
open_options(self)
else
close_options(self)
end
end
for _, part in ipairs(self.characters) do
part.y = 40 + (part.i-1)*19
end
@ -230,6 +241,7 @@ function BuyScreen:draw()
self.effects:draw()
if self.items_text then self.items_text:draw(32, 145) end
if self.level_text then self.level_text:draw(265, gh - 20) end
if self.paused then graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent) end
self.ui:draw()
if self.unit_grabbed then
@ -255,6 +267,7 @@ function BuyScreen:draw()
arrow:draw(gw/2 + 93, gh/2 - 10, 0, 0.4, 0.35)
end
self.tutorial:draw()
end

View File

@ -66,10 +66,10 @@ function engine_run(config)
if state.sx and state.sy then
sx, sy = state.sx, state.sy
love.window.setMode(state.sx*gw, state.sy*gh, {fullscreen = state.fullscreen, vsync = config.vsync, msaa = msaa or 0, display = config.display})
love.window.setMode(state.sx*gw, state.sy*gh, {vsync = config.vsync, msaa = msaa or 0, display = config.display})
else
state.sx, state.sy = sx, sy
love.window.setMode(window_width, window_height, {fullscreen = config.fullscreen, vsync = config.vsync, msaa = msaa or 0, display = config.display})
love.window.setMode(window_width, window_height, {vsync = config.vsync, msaa = msaa or 0, display = config.display})
end
love.window.setTitle(config.game_name)

287
main.lua
View File

@ -1,6 +1,7 @@
require 'engine'
require 'shared'
require 'arena'
require 'mainmenu'
require 'buy_screen'
require 'objects'
require 'player'
@ -1474,17 +1475,6 @@ function init()
'magnetism', 'insurance', 'dividends'
}
local run = system.load_run()
run_passive_pool = run.run_passive_pool or {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance'
}
gold = run.gold or 3
passives = run.passives or {}
locked_state = run.locked_state
steam.userStats.requestCurrentStats()
new_game_plus = state.new_game_plus or 0
if not state.new_game_plus then state.new_game_plus = new_game_plus end
@ -1492,12 +1482,15 @@ function init()
if not state.current_new_game_plus then state.current_new_game_plus = current_new_game_plus end
max_units = 7 + current_new_game_plus
main = Main()
main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
main = Main()
main:add(MainMenu'mainmenu')
main:go_to('mainmenu')
--[[
main:add(BuyScreen'buy_screen')
main:go_to('buy_screen', run.level or 1, run.units or {}, passives, run.shop_level or 1, run.shop_xp or 0)
]]--
-- main:go_to('buy_screen', 7, run.units or {}, {'unleash'})
--[[
@ -1552,6 +1545,7 @@ function update(dt)
end
]]--
--[[
if input.n.pressed then
if main.current.sfx_button then
main.current.sfx_button:action()
@ -1581,10 +1575,11 @@ function update(dt)
end
end
end
]]--
if input.k.pressed then
if sx > 1 and sy > 1 then
sx, sy = sx - 1, sy - 1
sx, sy = sx - 0.5, sy - 0.5
love.window.setMode(480*sx, 270*sy)
state.sx, state.sy = sx, sy
state.fullscreen = false
@ -1592,7 +1587,7 @@ function update(dt)
end
if input.l.pressed then
sx, sy = sx + 1, sy + 1
sx, sy = sx + 0.5, sy + 0.5
love.window.setMode(480*sx, 270*sy)
state.sx, state.sy = sx, sy
state.fullscreen = false
@ -1614,10 +1609,268 @@ function draw()
end
function open_options(self)
input:set_mouse_visible(true)
trigger:tween(0.25, _G, {slow_amount = 0}, math.linear, function()
slow_amount = 0
self.paused = true
if self:is(Arena) then
self.paused_t1 = Text2{group = self.ui, x = gw/2, y = gh/2 - 108, sx = 0.6, sy = 0.6, lines = {{text = '[bg10]<-, a or m1 ->, d or m2', font = fat_font, alignment = 'center'}}}
self.paused_t2 = Text2{group = self.ui, x = gw/2, y = gh/2 - 92, lines = {{text = '[bg10]turn left turn right', font = pixul_font, alignment = 'center'}}}
end
if self:is(MainMenu) then
self.ng_t = Text2{group = self.ui, x = gw/2 + 63, y = gh - 50, lines = {{text = '[bg10]current: ' .. current_new_game_plus, font = pixul_font, alignment = 'center'}}}
end
self.resume_button = Button{group = self.ui, x = gw/2, y = gh - 225, force_update = true, button_text = 'resume game (esc)', fg_color = 'bg10', bg_color = 'bg', action = function(b)
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
slow_amount = 1
self.paused = false
if self.paused_t1 then self.paused_t1.dead = true; self.paused_t1 = nil end
if self.paused_t2 then self.paused_t2.dead = true; self.paused_t2 = nil end
if self.ng_t then self.ng_t.dead = true; self.ng_t = nil end
if self.resume_button then self.resume_button.dead = true; self.resume_button = nil end
if self.restart_button then self.restart_button.dead = true; self.restart_button = nil end
if self.mouse_button then self.mouse_button.dead = true; self.mouse_button = nil end
if self.dark_transition_button then self.dark_transition_button.dead = true; self.dark_transition_button = nil end
if self.sfx_button then self.sfx_button.dead = true; self.sfx_button = nil end
if self.music_button then self.music_button.dead = true; self.music_button = nil end
if self.video_button_1 then self.video_button_1.dead = true; self.video_button_1 = nil end
if self.video_button_2 then self.video_button_2.dead = true; self.video_button_2 = nil end
if self.video_button_3 then self.video_button_3.dead = true; self.video_button_3 = nil end
if self.video_button_4 then self.video_button_4.dead = true; self.video_button_4 = nil end
if self.quit_button then self.quit_button.dead = true; self.quit_button = nil end
if self.screen_shake_button then self.screen_shake_button.dead = true; self.screen_shake_button = nil end
if self.screen_movement_button then self.screen_movement_button.dead = true; self.screen_movement_button = nil end
if self.cooldown_snake_button then self.cooldown_snake_button.dead = true; self.cooldown_snake_button = nil end
if self.arrow_snake_button then self.arrow_snake_button.dead = true; self.arrow_snake_button = nil end
if self.ng_plus_plus_button then self.ng_plus_plus_button.dead = true; self.ng_plus_plus_button = nil end
if self.ng_plus_minus_button then self.ng_plus_minus_button.dead = true; self.ng_plus_minus_button = nil end
system.save_state()
end, 'pause')
end}
if not self:is(MainMenu) then
self.restart_button = Button{group = self.ui, x = gw/2, y = gh - 200, force_update = true, button_text = 'restart run (r)', fg_color = 'bg10', bg_color = 'bg', action = function(b)
self.transitioning = true
ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
TransitionEffect{group = main.transitions, x = gw/2, y = gh/2, color = state.dark_transitions and bg[-2] or fg[0], transition_action = function()
slow_amount = 1
gold = 3
passives = {}
main_song_instance:stop()
run_passive_pool = {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance'
}
max_units = 7 + current_new_game_plus
main:add(BuyScreen'buy_screen')
locked_state = nil
system.save_run()
main:go_to('buy_screen', 1, {}, passives, 1, 0)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']restarting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end}
end
self.mouse_button = Button{group = self.ui, x = gw/2 - 57, y = gh - 150, force_update = true, button_text = 'mouse control: ' .. tostring(state.mouse_control and 'yes' or 'no'), fg_color = 'bg10', bg_color = 'bg',
action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.mouse_control = not state.mouse_control
b:set_text('mouse control: ' .. tostring(state.mouse_control and 'yes' or 'no'))
end}
self.dark_transition_button = Button{group = self.ui, x = gw/2 + 64, y = gh - 150, force_update = true, button_text = 'dark transitions: ' .. tostring(state.dark_transitions and 'yes' or 'no'),
fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.dark_transitions = not state.dark_transitions
b:set_text('dark transitions: ' .. tostring(state.dark_transitions and 'yes' or 'no'))
end}
self.sfx_button = Button{group = self.ui, x = gw/2 - 46, y = gh - 175, force_update = true, button_text = 'sfx volume: ' .. tostring((state.sfx_volume or 0.5)*10), fg_color = 'bg10', bg_color = 'bg',
action = function(b)
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
sfx.volume = sfx.volume + 0.1
if sfx.volume > 1 then sfx.volume = 0 end
state.sfx_volume = sfx.volume
b:set_text('sfx volume: ' .. tostring((state.sfx_volume or 0.5)*10))
end}
self.music_button = Button{group = self.ui, x = gw/2 + 48, y = gh - 175, force_update = true, button_text = 'music volume: ' .. tostring((state.music_volume or 0.5)*10), fg_color = 'bg10', bg_color = 'bg',
action = function(b)
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
music.volume = music.volume + 0.1
if music.volume > 1 then music.volume = 0 end
state.music_volume = music.volume
b:set_text('music volume: ' .. tostring((state.music_volume or 0.5)*10))
end}
self.video_button_1 = Button{group = self.ui, x = gw/2 - 136, y = gh - 125, force_update = true, button_text = 'window size-', fg_color = 'bg10', bg_color = 'bg', action = function()
if sx > 1 and sy > 1 then
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
sx, sy = sx - 0.5, sy - 0.5
love.window.setMode(480*sx, 270*sy)
state.sx, state.sy = sx, sy
state.fullscreen = false
end
end}
self.video_button_2 = Button{group = self.ui, x = gw/2 - 50, y = gh - 125, force_update = true, button_text = 'window size+', fg_color = 'bg10', bg_color = 'bg', action = function()
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
sx, sy = sx + 0.5, sy + 0.5
love.window.setMode(480*sx, 270*sy)
state.sx, state.sy = sx, sy
state.fullscreen = false
end}
self.video_button_3 = Button{group = self.ui, x = gw/2 + 29, y = gh - 125, force_update = true, button_text = 'fullscreen', fg_color = 'bg10', bg_color = 'bg', action = function()
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
local _, _, flags = love.window.getMode()
local window_width, window_height = love.window.getDesktopDimensions(flags.display)
sx, sy = window_width/480, window_height/270
state.sx, state.sy = sx, sy
ww, wh = window_width, window_height
love.window.setMode(window_width, window_height)
end}
self.video_button_4 = Button{group = self.ui, x = gw/2 + 129, y = gh - 125, force_update = true, button_text = 'reset video settings', fg_color = 'bg10', bg_color = 'bg', action = function()
local _, _, flags = love.window.getMode()
local window_width, window_height = love.window.getDesktopDimensions(flags.display)
sx, sy = window_width/480, window_height/270
ww, wh = window_width, window_height
state.sx, state.sy = sx, sy
state.fullscreen = false
ww, wh = window_width, window_height
love.window.setMode(window_width, window_height)
end}
self.screen_shake_button = Button{group = self.ui, x = gw/2 - 57, y = gh - 100, w = 110, force_update = true, button_text = '[bg10]screen shake: ' .. tostring(state.no_screen_shake and 'no' or 'yes'),
fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.no_screen_shake = not state.no_screen_shake
b:set_text('screen shake: ' .. tostring(state.no_screen_shake and 'no' or 'yes'))
end}
self.cooldown_snake_button = Button{group = self.ui, x = gw/2 + 75, y = gh - 100, w = 145, force_update = true, button_text = '[bg10]cooldowns on snake: ' .. tostring(state.cooldown_snake and 'yes' or 'no'),
fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.cooldown_snake = not state.cooldown_snake
b:set_text('cooldowns on snake: ' .. tostring(state.cooldown_snake and 'yes' or 'no'))
end}
self.arrow_snake_button = Button{group = self.ui, x = gw/2 + 65, y = gh - 75, w = 125, force_update = true, button_text = '[bg10]arrow on snake: ' .. tostring(state.arrow_snake and 'yes' or 'no'),
fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.arrow_snake = not state.arrow_snake
b:set_text('arrow on snake: ' .. tostring(state.arrow_snake and 'yes' or 'no'))
end}
self.screen_movement_button = Button{group = self.ui, x = gw/2 - 69, y = gh - 75, w = 135, force_update = true, button_text = '[bg10]screen movement: ' .. tostring(state.no_screen_movement and 'no' or 'yes'),
fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
state.no_screen_movement = not state.no_screen_movement
if state.no_screen_movement then
camera.x, camera.y = gw/2, gh/2
camera.r = 0
end
b:set_text('screen movement: ' .. tostring(state.no_screen_movement and 'no' or 'yes'))
end}
if self:is(MainMenu) then
self.ng_plus_minus_button = Button{group = self.ui, x = gw/2 - 58, y = gh - 50, force_update = true, button_text = 'NG+ down', fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
current_new_game_plus = math.clamp(current_new_game_plus - 1, 0, 5)
state.current_new_game_plus = current_new_game_plus
self.ng_t.text:set_text({{text = '[bg10]current: ' .. current_new_game_plus, font = pixul_font, alignment = 'center'}})
end}
self.ng_plus_plus_button = Button{group = self.ui, x = gw/2 + 5, y = gh - 50, force_update = true, button_text = 'NG+ up', fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
current_new_game_plus = math.clamp(current_new_game_plus + 1, 0, new_game_plus)
state.current_new_game_plus = current_new_game_plus
self.ng_t.text:set_text({{text = '[bg10]current: ' .. current_new_game_plus, font = pixul_font, alignment = 'center'}})
end}
end
if not self:is(MainMenu) then
self.main_menu_button = Button{group = self.ui, x = gw/2, y = gh - 50, force_update = true, button_text = 'main menu', fg_color = 'bg10', bg_color = 'bg', action = function(b)
self.transitioning = true
ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
TransitionEffect{group = main.transitions, x = gw/2, y = gh/2, color = state.dark_transitions and bg[-2] or fg[0], transition_action = function()
system.save_run()
main:add(MainMenu'main_menu')
main:go_to('main_menu')
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']..', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end}
end
self.quit_button = Button{group = self.ui, x = gw/2, y = gh - 25, force_update = true, button_text = 'quit', fg_color = 'bg10', bg_color = 'bg', action = function()
system.save_state()
steam.shutdown()
love.event.quit()
end}
end, 'pause')
end
function close_options(self)
if not state.mouse_control then
input:set_mouse_visible(false)
end
if self:is(Arena) then
input:set_mouse_visible(state.mouse_control or false)
end
trigger:tween(0.25, _G, {slow_amount = 1}, math.linear, function()
slow_amount = 1
self.paused = false
if self.paused_t1 then self.paused_t1.dead = true; self.paused_t1 = nil end
if self.paused_t2 then self.paused_t2.dead = true; self.paused_t2 = nil end
if self.ng_t then self.ng_t.dead = true; self.ng_t = nil end
if self.resume_button then self.resume_button.dead = true; self.resume_button = nil end
if self.restart_button then self.restart_button.dead = true; self.restart_button = nil end
if self.mouse_button then self.mouse_button.dead = true; self.mouse_button = nil end
if self.dark_transition_button then self.dark_transition_button.dead = true; self.dark_transition_button = nil end
if self.sfx_button then self.sfx_button.dead = true; self.sfx_button = nil end
if self.music_button then self.music_button.dead = true; self.music_button = nil end
if self.video_button_1 then self.video_button_1.dead = true; self.video_button_1 = nil end
if self.video_button_2 then self.video_button_2.dead = true; self.video_button_2 = nil end
if self.video_button_3 then self.video_button_3.dead = true; self.video_button_3 = nil end
if self.video_button_4 then self.video_button_4.dead = true; self.video_button_4 = nil end
if self.screen_shake_button then self.screen_shake_button.dead = true; self.screen_shake_button = nil end
if self.screen_movement_button then self.screen_movement_button.dead = true; self.screen_movement_button = nil end
if self.cooldown_snake_button then self.cooldown_snake_button.dead = true; self.cooldown_snake_button = nil end
if self.arrow_snake_button then self.arrow_snake_button.dead = true; self.arrow_snake_button = nil end
if self.quit_button then self.quit_button.dead = true; self.quit_button = nil end
if self.ng_plus_plus_button then self.ng_plus_plus_button.dead = true; self.ng_plus_plus_button = nil end
if self.ng_plus_minus_button then self.ng_plus_minus_button.dead = true; self.ng_plus_minus_button = nil end
if self.main_menu_button then self.main_menu_button.dead = true; self.main_menu_button = nil end
system.save_state()
end, 'pause')
end
function love.run()
return engine_run({
game_name = 'SNKRX',
window_width = 480*4,
window_height = 270*4,
window_width = 'max',
window_height = 'max',
})
end

202
mainmenu.lua 100644
View File

@ -0,0 +1,202 @@
MainMenu = Object:extend()
MainMenu:implement(State)
MainMenu:implement(GameObject)
function MainMenu:init(name)
self:init_state(name)
self:init_game_object()
end
function MainMenu:on_enter(from)
slow_amount = 1
trigger:tween(2, main_song_instance, {volume = 0.5, pitch = 1}, math.linear)
steam.friends.setRichPresence('steam_display', '#StatusFull')
steam.friends.setRichPresence('text', 'Main Menu')
self.floor = Group()
self.main = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile', 'force_field', 'ghost'})
self.post_main = Group()
self.effects = Group()
self.main_ui = Group():no_camera()
self.ui = Group():no_camera()
self.main:disable_collision_between('player', 'player')
self.main:disable_collision_between('player', 'projectile')
self.main:disable_collision_between('player', 'enemy_projectile')
self.main:disable_collision_between('projectile', 'projectile')
self.main:disable_collision_between('projectile', 'enemy_projectile')
self.main:disable_collision_between('projectile', 'enemy')
self.main:disable_collision_between('enemy_projectile', 'enemy')
self.main:disable_collision_between('enemy_projectile', 'enemy_projectile')
self.main:disable_collision_between('player', 'force_field')
self.main:disable_collision_between('projectile', 'force_field')
self.main:disable_collision_between('ghost', 'player')
self.main:disable_collision_between('ghost', 'projectile')
self.main:disable_collision_between('ghost', 'enemy')
self.main:disable_collision_between('ghost', 'enemy_projectile')
self.main:disable_collision_between('ghost', 'ghost')
self.main:disable_collision_between('ghost', 'force_field')
self.main:enable_trigger_between('projectile', 'enemy')
self.main:enable_trigger_between('enemy_projectile', 'player')
self.main:enable_trigger_between('player', 'enemy_projectile')
self.main:enable_trigger_between('enemy_projectile', 'enemy')
self.main:enable_trigger_between('player', 'ghost')
self.enemies = {Seeker, EnemyCritter}
-- Spawn solids and player
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.w, self.h = self.x2 - self.x1, self.y2 - self.y1
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(self.x2, -40, gw + 40, gh + 40), 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]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(-40, -40, self.x1, gh + 40), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x2, -40, gw + 40, gh + 40), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x1, -40, self.x2, self.y1), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x1, self.y2, self.x2, gh + 40), color = bg[-1]}
self.t:every(0.375, function()
local p = random:table(star_positions)
Star{group = star_group, x = p.x, y = p.y}
end)
self.units = {
{character = 'vagrant', level = 1},
{character = 'magician', level = 1},
{character = 'bane', level = 1},
{character = 'scout', level = 1},
{character = 'cannoneer', level = 1},
{character = 'swordsman', level = 1},
{character = 'archer', level = 1},
}
for i, unit in ipairs(self.units) do
if i == 1 then
self.player = Player{group = self.main, x = gw/2 + random:float(-48, 48), y = gh/2 + 16 + random:float(-48, 48), leader = true, character = unit.character, level = unit.level, passives = self.passives, ii = i}
else
self.player:add_follower(Player{group = self.main, character = unit.character, level = unit.level, passives = self.passives, ii = i})
end
end
self.title_text = Text({{text = '[wavy_mid, fg]SNKRX', font = fat_font, alignment = 'center'}}, global_text_tags)
self.arena_run_button = Button{group = self.main_ui, x = 55, y = gh/2 - 10, force_update = true, button_text = 'arena run', fg_color = 'bg10', bg_color = 'bg', action = function(b)
self.transitioning = true
ui_transition2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
TransitionEffect{group = main.transitions, x = gw/2, y = gh/2, color = state.dark_transitions and bg[-2] or fg[0], transition_action = function()
slow_amount = 1
local run = system.load_run()
run_passive_pool = run.run_passive_pool or {
'centipede', 'ouroboros_technique_r', 'ouroboros_technique_l', 'amplify', 'resonance', 'ballista', 'call_of_the_void', 'crucio', 'speed_3', 'damage_4', 'shoot_5', 'death_6', 'lasting_7',
'defensive_stance', 'offensive_stance', 'kinetic_bomb', 'porcupine_technique', 'last_stand', 'seeping', 'deceleration', 'annihilation', 'malediction', 'hextouch', 'whispers_of_doom',
'tremor', 'heavy_impact', 'fracture', 'meat_shield', 'hive', 'baneling_burst', 'blunt_arrow', 'explosive_arrow', 'divine_machine_arrow', 'chronomancy', 'awakening', 'divine_punishment',
'assassination', 'flying_daggers', 'ultimatum', 'magnify', 'echo_barrage', 'unleash', 'reinforce', 'payback', 'enchanted', 'freezing_field', 'burning_field', 'gravity_field', 'magnetism',
'insurance', 'dividends', 'berserking', 'unwavering_stance', 'unrelenting_stance'
}
gold = run.gold or 3
passives = run.passives or {}
locked_state = run.locked_state
system.save_state()
main:add(BuyScreen'buy_screen')
main:go_to('buy_screen', run.level or 1, run.units or {}, passives, run.shop_level or 1, run.shop_xp or 0)
end, text = Text({{text = '[wavy, ' .. tostring(state.dark_transitions and 'fg' or 'bg') .. ']starting...', font = pixul_font, alignment = 'center'}}, global_text_tags)}
end}
self.options_button = Button{group = self.main_ui, x = 47, y = gh/2 + 12, force_update = true, button_text = 'options', fg_color = 'bg10', bg_color = 'bg', action = function(b)
if not self.paused then
open_options(self)
else
close_options(self)
end
end}
self.quit_button = Button{group = self.main_ui, x = 37, y = gh/2 + 34, force_update = true, button_text = 'quit', fg_color = 'bg10', bg_color = 'bg', action = function(b)
system.save_state()
steam.shutdown()
love.event.quit()
end}
self.t:every(2, function() self.soundtrack_button.spring:pull(0.025, 200, 10) end)
self.soundtrack_button = Button{group = self.main_ui, x = gw - 72, y = gh - 17, force_update = true, button_text = 'buy the soundtrack!', fg_color = 'bg10', bg_color = 'bg', action = function(b)
ui_switch2:play{pitch = random:float(0.95, 1.05), volume = 0.5}
b.spring:pull(0.2, 200, 10)
b.selected = true
ui_switch1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
system.open_url('https://kubbimusic.com/album/ember')
end}
end
function MainMenu:on_exit()
self.floor:destroy()
self.main:destroy()
self.post_main:destroy()
self.effects:destroy()
self.ui:destroy()
self.main_ui:destroy()
self.t:destroy()
self.floor = nil
self.main = nil
self.post_main = nil
self.effects = nil
self.ui = nil
self.units = nil
self.player = nil
self.t = nil
self.springs = nil
self.flashes = nil
self.hfx = nil
self.title_text = nil
end
function MainMenu:update(dt)
if main_song_instance:isStopped() then
main_song_instance = _G[random:table{'song1', 'song2', 'song3', 'song4', 'song5'}]:play{volume = 0.5}
end
if input.escape.pressed then
if not self.paused then
open_options(self)
else
close_options(self)
end
end
self:update_game_object(dt*slow_amount)
if not self.paused and not self.transitioning then
star_group:update(dt*slow_amount)
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.main_ui:update(dt*slow_amount)
if self.title_text then self.title_text:update(dt) end
self.ui:update(dt*slow_amount)
else
self.ui:update(dt*slow_amount)
end
end
function MainMenu:draw()
self.floor:draw()
self.main:draw()
self.post_main:draw()
self.effects:draw()
graphics.draw_with_mask(function()
star_canvas:draw(0, 0, 0, 1, 1)
end, function()
camera:attach()
graphics.rectangle(gw/2, gh/2, self.w, self.h, nil, nil, fg[0])
camera:detach()
end, true)
graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent)
self.main_ui:draw()
self.title_text:draw(60, gh/2 - 40)
if self.paused then graphics.rectangle(gw/2, gh/2, 2*gw, 2*gh, nil, nil, modal_transparent) end
self.ui:draw()
end

View File

@ -1012,6 +1012,11 @@ function Player:init(args)
end
self.mouse_control_v_buffer = {}
if main.current:is(MainMenu) then
self.r = random:table{-math.pi/4, math.pi/4, 3*math.pi/4, -3*math.pi/4}
self:set_angle(self.r)
end
end
@ -1216,19 +1221,21 @@ function Player:update(dt)
self.t:set_every_multiplier('attack', self.aspd_m)
if self.leader then
if input.move_left.pressed and not self.move_right_pressed then self.move_left_pressed = love.timer.getTime() end
if input.move_right.pressed and not self.move_left_pressed then self.move_right_pressed = love.timer.getTime() end
if input.move_left.released then self.move_left_pressed = nil end
if input.move_right.released then self.move_right_pressed = nil end
if not main.current:is(MainMenu) then
if input.move_left.pressed and not self.move_right_pressed then self.move_left_pressed = love.timer.getTime() end
if input.move_right.pressed and not self.move_left_pressed then self.move_right_pressed = love.timer.getTime() end
if input.move_left.released then self.move_left_pressed = nil end
if input.move_right.released then self.move_right_pressed = nil end
if state.mouse_control then
self.mouse_control_v = Vector(math.cos(self.r), math.sin(self.r)):perpendicular():dot(Vector(math.cos(self:angle_to_mouse()), math.sin(self:angle_to_mouse())))
self.r = self.r + math.sign(self.mouse_control_v)*1.66*math.pi*dt
table.insert(self.mouse_control_v_buffer, 1, self.mouse_control_v)
if #self.mouse_control_v_buffer > 64 then self.mouse_control_v_buffer[65] = nil end
else
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
if state.mouse_control then
self.mouse_control_v = Vector(math.cos(self.r), math.sin(self.r)):perpendicular():dot(Vector(math.cos(self:angle_to_mouse()), math.sin(self:angle_to_mouse())))
self.r = self.r + math.sign(self.mouse_control_v)*1.66*math.pi*dt
table.insert(self.mouse_control_v_buffer, 1, self.mouse_control_v)
if #self.mouse_control_v_buffer > 64 then self.mouse_control_v_buffer[65] = nil end
else
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
end
end
local total_v = 0
@ -2770,7 +2777,7 @@ end
function Volcano:update(dt)
self:update_game_object(dt)
self.vr = self.vr + self.dvr*dt
if self.dvr then self.vr = self.vr + self.dvr*dt end
end
@ -2782,7 +2789,7 @@ function Volcano:draw()
graphics.triangle_equilateral(self.x, self.y, 1.5*self.shape.w, self.hfx.hit.f and fg[0] or self.color, 3)
graphics.pop()
graphics.push(self.x, self.y, self.r + self.vr, self.spring.x, self.spring.x)
graphics.push(self.x, self.y, self.r + (self.vr or 0), self.spring.x, self.spring.x)
-- graphics.circle(self.x, self.y, self.shape.rs + random:float(-1, 1), self.color, 2)
graphics.circle(self.x, self.y, 24, self.color_transparent)
local lw = 2

View File

@ -88,9 +88,10 @@ function shared_draw(draw_action)
shadow_shader:unset()
end)
background_canvas:draw(0, 0, 0, sx, sy)
shadow_canvas:draw(1.5*sx, 1.5*sy, 0, sx, sy)
main_canvas:draw(0, 0, 0, sx, sy)
local x, y = 0, 0
background_canvas:draw(x, y, 0, sx, sy)
shadow_canvas:draw(x + 1.5*sx, y + 1.5*sy, 0, sx, sy)
main_canvas:draw(x, y, 0, sx, sy)
end

43
todo
View File

@ -31,6 +31,7 @@ Looping Update
Summon Instability - summons explode when disappearing, dealing 100/150/200% damage
Changes:
Magnetism - also attracts healing orbs
Enchanted - 30/60/90%
Healer rework:
Enemies have a 8/16% chance to spawn healing orbs on death, orbs prioritize healing low health allies
Cleric: creates 1 healing orb, Lv.3: creates 4 healing orbs and grants +20% healing effectiveness
@ -38,7 +39,7 @@ Looping Update
Fairy: grants a random unit 100% attack speed for 6 seconds and creates 1 healing orb
Psyker rework:
Create orbitting, damaging balls at the head of the snake equal to the number of psykers
Flagellant - Lv.3: deals no damage to self and grants +10% damage to all allies per cast
Flagellant - Lv.3: 2X flagellant max HP and grants +10% damage to all allies per cast
Psychic - Lv.3: gains up to 300% damage the less HP the psychic has
Psykino - Lv.3: gains up to 100% attack speed the less HP the psykino has
Psykeeper - creates a healing orb every time the psykeeper takes 30% of its max HP in damage, Lv.3: deal double the damage taken by the psykeeper to all enemies
@ -52,30 +53,30 @@ Looping Update
* Decreased reroll cost to 8
* Increased sage's attack speed
QoL
Your party + items on end, death and passive screens - https://i.imgur.com/JJUddT3.png
Volume slider
Add visuals divine intervention, fairy buff
Options menu from buy screen
Add option for mouse cursor to always be visible
Add main menu
Soundtrack button
Arena run button
Options button
Quit button
Show cooldown on elite attack
* Options menu from buy screen
* Add main menu
* Title
* Snake DVD
* Arena run button
* Options button
* Quit button
* Soundtrack button
https://i.imgur.com/4hOt5uX.png "party 7/9"
https://i.imgur.com/dlGbx0k.png lvl 3 effect on shop card
* Volume slider
Your party + items on end, death and passive screens - https://i.imgur.com/JJUddT3.png
Add option for mouse cursor to always be visible
Add visuals divine intervention, fairy buff
Change text for enchanted to "if you have >= 2 enchanters" and change text for reinforce to "if you have >= 1 enchanter"
Bug fixes
Fix fullscreen with different resolutions that don't scale properly - https://steamcommunity.com/app/915310/discussions/0/3106901665841020282/
Fix enemies still spawning after arena clear (this happens with the extra enemy spawns that were blocked earlier)
Kill enemies that go outside play area - https://i.imgur.com/QPgZbve.png
https://i.imgur.com/lCdPFZx.png - dvr crash, already fixed i think
* Fixed fullscreen button and general resolution issues
Fixed a series of crashes that happened rarely right before changing from the arena back to the shop
https://i.imgur.com/Rk6qbDD.png - merchant doesnt give reroll if dies
https://i.imgur.com/1soUUdk.png - 5th position stops shooting when 1-4 die
https://i.imgur.com/G9DosVw.png - lasting 7 bug
https://i.imgur.com/8he1WDm.png - infinite money
https://i.imgur.com/0wZ5wma.png - max unit bugged when changing ng mid run, https://i.imgur.com/qrExpq5.png
https://i.imgur.com/1soUUdk.png - 5th position stops shooting when 1-4 die
https://i.imgur.com/cJMFDfc.png - lasting 7 doesnt work?
"your build" only shows alive units, this is the same problem as merchant not giving interest if dead?
https://i.imgur.com/Ta3lBui.png - Pet bug due to enemies spawning after arena is clear
---
@ -119,6 +120,10 @@ Challenge mode
Units die permanently when they die
Slower scaling with less individually threatening units
Max snake size goes up every 10 levels
Draft mode
Enemy ideas - https://steamcommunity.com/app/915310/discussions/0/3069747783691890511/
Unit ideas - https://i.imgur.com/VNMS2YV.png
Unit ideas - https://steamcommunity.com/app/915310/discussions/0/3069747783693969554/
--