From 45b29dc137c7fec2eaa5d98c1e93398d0854bc7f Mon Sep 17 00:00:00 2001 From: a327ex Date: Wed, 10 Mar 2021 02:47:27 -0300 Subject: [PATCH] Day 20-21 --- arena.lua | 11 +-- buy_screen.lua | 175 ++++++++++++++++++++++++++++++++++++++++-- devlog.md | 6 ++ engine/game/group.lua | 16 +++- main.lua | 4 +- shared.lua | 4 +- 6 files changed, 198 insertions(+), 18 deletions(-) diff --git a/arena.lua b/arena.lua index 2d20262..9cb5be5 100644 --- a/arena.lua +++ b/arena.lua @@ -11,6 +11,7 @@ function Arena:on_enter(from, level, units) self.hfx:add('condition1', 1) self.hfx:add('condition2', 1) self.level = level or 1 + self.units = units self.floor = Group() self.main = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile'}) @@ -166,10 +167,10 @@ function Arena:on_enter(from, level, units) 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'}}} + local t1 = Text2{group = self.floor, x = gw/2, y = gh/2 + 2, 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 + 18, 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 + 46, 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 + 68, 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) @@ -250,7 +251,7 @@ function Arena:update(dt) 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) + main:go_to('buy_screen', self.level, self.units) 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}, diff --git a/buy_screen.lua b/buy_screen.lua index bc17cac..36b5628 100644 --- a/buy_screen.lua +++ b/buy_screen.lua @@ -7,13 +7,17 @@ function BuyScreen:init(name) end -function BuyScreen:on_enter(from, level) +function BuyScreen:on_enter(from, level, units) self.level = level self.main = Group() + self.top = Group() + self.ui = Group() if self.level == 0 then 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} self.first_screen = true self.cards = {} self.selected_card_index = 1 @@ -23,9 +27,49 @@ function BuyScreen:on_enter(from, level) self.cards[2] = PairCard{group = self.main, x = gw/2, y = 155, w = gw, h = gh/4, unit_1 = random:table_remove(units), unit_2 = random:table_remove(units), i = 2, parent = self} local units = {'vagrant', 'swordsman', 'wizard', 'archer', 'scout', 'cleric'} 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 = '[wavy_mid, fg]choose your initial party', font = pixul_font, alignment = 'center'}}, global_text_tags) + + else + local tier_to_units = { + [1] = {'vagrant', 'swordsman', 'wizard', 'archer', 'cleric', 'scout'}, + [2] = {'saboteur', 'hunter', 'cannoneer', 'stormweaver', 'squire', 'dual_gunner', 'chronomancer', 'sage', 'cannoneer'}, + [3] = {'blade', 'outlaw', 'elementor', 'psykeeper', 'spellblade'}, + } + local level_to_tier_weights = { + [1] = {100, 0, 0}, + [2] = {95, 5, 0}, + [3] = {90, 10, 0}, + [4] = {85, 15, 0}, + [5] = {80, 20, 0}, + [6] = {75, 25, 0}, + [7] = {70, 30, 0}, + [8] = {65, 35, 0}, + [9] = {60, 40, 0}, + [10] = {55, 45, 0}, + [11] = {50, 50, 0}, + [12] = {45, 50, 5}, + [13] = {40, 50, 10}, + [14] = {35, 50, 15}, + [15] = {30, 50, 20}, + [16] = {25, 50, 25}, + [17] = {20, 55, 25}, + [18] = {15, 60, 25}, + [19] = {10, 65, 25}, + [20] = {5, 70, 25}, + [21] = {0, 75, 25}, + [22] = {0, 70, 30}, + [23] = {0, 65, 35}, + [24] = {0, 60, 40}, + [25] = {0, 55, 45}, + } + self.cards = {} + self.selected_card_index = 1 + self.cards[1] = ShopCard{group = self.main, x = gw/2 - 120, y = gh/4, w = 100, h = 90, unit = random:table(tier_to_units[random:weighted_pick(unpack(level_to_tier_weights[self.level]))]), parent = self} + self.cards[2] = ShopCard{group = self.main, x = gw/2, y = gh/4, w = 100, h = 90, unit = random:table(tier_to_units[random:weighted_pick(unpack(level_to_tier_weights[self.level]))]), parent = self} + self.cards[3] = ShopCard{group = self.main, x = gw/2 + 120, y = gh/4, w = 100, h = 90, unit = random:table(tier_to_units[random:weighted_pick(unpack(level_to_tier_weights[self.level]))]), parent = self} + self.shop_text_sy = 1 + self.shop_text = Text({{text = '[wavy_mid, fg]shop', font = pixul_font, alignment = 'center'}}, global_text_tags) end end @@ -33,6 +77,8 @@ end function BuyScreen:update(dt) self:update_game_object(dt*slow_amount) self.main:update(dt*slow_amount) + self.top:update(dt*slow_amount) + self.ui:update(dt*slow_amount) if self.level == 0 and self.first_screen then if self.title then self.title:update(dt) end @@ -80,29 +126,146 @@ function BuyScreen:update(dt) }, global_text_tags)} ]]-- end + + else + if self.shop_text then self.shop_text:update(dt) end + end end function BuyScreen:draw() self.main:draw() + self.top:draw() + self.ui:draw() if self.level == 0 then if self.title then self.title:draw(3.25*gw/4, 25, 0, 1, self.title_sy) end - if self.unit_info_text then - self.unit_info_text:draw(gw/2, gh/2) - end + if self.unit_info_text then self.unit_info_text:draw(gw/2, gh/2) end + else + if self.shop_text then self.shop_text:draw(gw/2, 15, 0, 1, self.shop_text_sy) end end end +ShopCard = Object:extend() +ShopCard:implement(GameObject) +function ShopCard:init(args) + self:init_game_object(args) + self.character_icon = CharacterIcon{group = main.current.top, x = self.x, y = self.y, character = self.unit} + self.class_icons = {} + for i, class in ipairs(character_classes[self.unit]) do + local x = self.x + if #character_classes[self.unit] == 2 then x = self.x - 10 + elseif #character_classes[self.unit] == 3 then x = self.x - 20 end + table.insert(self.class_icons, ClassIcon{group = main.current.top, x = x + (i-1)*20, y = self.y + 10, class = class}) + end +end + + +function ShopCard:update(dt) + self:update_game_object(dt) + if self.unit_text then self.unit_text:update(dt) end +end + + +function ShopCard:select() + self.selected = true + self.spring:pull(0.2, 200, 10) + self.t:every_immediate(1.4, function() + if self.selected then + self.t:tween(0.7, self, {sx = 0.97, sy = 0.97, plus_r = -math.pi/32}, math.linear, function() + self.t:tween(0.7, self, {sx = 1.03, sy = 1.03, plus_r = math.pi/32}, math.linear, nil, 'pulse_1') + end, 'pulse_2') + end + end, nil, nil, 'pulse') +end + + +function ShopCard:unselect() + self.selected = false + self.t:cancel'pulse' + self.t:cancel'pulse_1' + self.t:cancel'pulse_2' + self.t:tween(0.1, self, {sx = 1, sy = 1, plus_r = 0}, math.linear, function() self.sx, self.sy, self.plus_r = 1, 1, 0 end, 'pulse') +end + + +function ShopCard:draw() + +end + + + + +CharacterIcon = Object:extend() +CharacterIcon:implement(GameObject) +function CharacterIcon:init(args) + self:init_game_object(args) + self.character_text = Text({{text = '[' .. character_color_strings[self.character] .. ']' .. self.character, font = pixul_font, alignment = 'center'}}, global_text_tags) +end + + +function CharacterIcon:update(dt) + self:update_game_object(dt) + self.character_text:update(dt) +end + + +function CharacterIcon:draw() + graphics.push(self.x, self.y, 0, self.spring.x, self.spring.x) + graphics.rectangle(self.x, self.y - 25, 12, 12, 3, 3, character_colors[self.character]) + self.character_text:draw(self.x, self.y - 10) + graphics.pop() +end + + + +ClassIcon = Object:extend() +ClassIcon:implement(GameObject) +function ClassIcon:init(args) + self:init_game_object(args) + self.shape = Rectangle(self.x, self.y, 20, 30) + self.interact_with_mouse = true +end + + +function ClassIcon:update(dt) + self:update_game_object(dt) +end + + +function ClassIcon:draw() + graphics.push(self.x, self.y, 0, self.spring.x, self.spring.x) + _G[self.class]:draw(self.x, self.y, 0, 0.4, 0.4, 0, 0, class_colors[self.class]) + graphics.pop() +end + + +function ClassIcon:on_mouse_enter() + self.spring:pull(0.2, 200, 10) + self.info_text = InfoText{group = main.current.ui} + self.info_text:activate({ + {text = '[' .. class_color_strings[self.class] .. ']' .. self.class:capitalize(), font = pixul_font, alignment = 'center', height_multiplier = 1.25}, + {text = class_descriptions[self.class](0), font = pixul_font, alignment = 'center'}, + }, nil, nil, nil, nil, 16, 4, nil, 2) + self.info_text.x, self.info_text.y = gw/2, self.y + 60 +end + + +function ClassIcon:on_mouse_exit() + self.info_text:deactivate() + self.info_text = nil +end + + + PairCard = Object:extend() PairCard:implement(GameObject) function PairCard:init(args) self:init_game_object(args) - self.plus_r = 0 if self.i == 1 then self:select() end end diff --git a/devlog.md b/devlog.md index 1dd661d..47b155e 100644 --- a/devlog.md +++ b/devlog.md @@ -341,3 +341,9 @@ screen. 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. + +# Day 20-21 - 08-09/03/21 + +Initial work done on the main buy screen. Fairly slow moving still. There's a sort of conceptual fuzziness that happens when writing UI code where there's a few different ways of doing it and this freedom seems fairly paralyzing. +I've been thinking really hard about what to do about that but it's still up in the air. The "dead simple layouts" thing is a good idea but layouting is not necessarily the main problem I have, it's more like relationships between +different objects and a UI coordination issue that seems to stop me. diff --git a/engine/game/group.lua b/engine/game/group.lua index 25a37e7..907d1fb 100644 --- a/engine/game/group.lua +++ b/engine/game/group.lua @@ -77,7 +77,11 @@ end -- The closer to 0, the more of a parallaxing effect there will be. function Group:draw(scroll_factor_x, scroll_factor_y) if self.camera then self.camera:attach(scroll_factor_x, scroll_factor_y) end - for _, object in ipairs(self.objects) do object:draw() end + for _, object in ipairs(self.objects) do + if not object.hidden then + object:draw() + end + end if self.camera then self.camera:detach() end end @@ -86,7 +90,11 @@ end -- group:draw_range(1, 3) -> draws only 1st, 2nd and 3rd objects in this group function Group:draw_range(i, j, scroll_factor_x, scroll_factor_y) if self.camera then self.camera:attach(scroll_factor_x, scroll_factor_y) end - for k = i, j do self.objects[k]:draw() end + for k = i, j do + if not self.objects[k].hidden then + self.objects[k]:draw() + end + end if self.camera then self.camera:detach() end end @@ -96,7 +104,7 @@ end function Group:draw_class(class, scroll_factor_x, scroll_factor_y) if self.camera then self.camera:attach(scroll_factor_x, scroll_factor_y) end for _, object in ipairs(self.objects) do - if object:is(class) then + if object:is(class) and not object.hidden then object:draw() end end @@ -109,7 +117,7 @@ end function Group:draw_all_except(classes, scroll_factor_x, scroll_factor_y) if self.camera then self.camera:attach(scroll_factor_x, scroll_factor_y) end for _, object in ipairs(self.objects) do - if not table.any(classes, function(v) return object:is(v) end) then + if not table.any(classes, function(v) return object:is(v) end) and not object.hidden then object:draw() end end diff --git a/main.lua b/main.lua index 555a702..ce9e6b4 100644 --- a/main.lua +++ b/main.lua @@ -263,14 +263,14 @@ function init() ['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, + ['psy'] = function(lvl) return '[fg]damage taken by psy units is reflected to enemies at double its value' end, } resource = 0 main = Main() main:add(BuyScreen'buy_screen') - main:go_to('buy_screen', 0) + main:go_to('buy_screen', 1, {}) end diff --git a/shared.lua b/shared.lua index bd1aafd..d397be5 100644 --- a/shared.lua +++ b/shared.lua @@ -433,6 +433,7 @@ global_text_tags = { 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_mid = TextTag{update = function(c, dt, i, text) c.oy = 0.75*math.sin(3*time + i) end}, + wavy_mid2 = TextTag{update = function(c, dt, i, text) c.oy = 0.5*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) @@ -485,6 +486,7 @@ function InfoText:init(args) self.ow, self.oh = 0, 0 self.tox, self.toy = 0, 0 self.text = Text({}, global_text_tags) + return self end @@ -515,7 +517,7 @@ end function InfoText:deactivate() self.t:cancel'activate' - self.t:tween(0.05, self, {sy = 0}, math.linear, function() self.sy = 0 end, 'deactivate') + self.t:tween(0.05, self, {sy = 0}, math.linear, function() self.sy = 0; self.dead = true end, 'deactivate') end