diff --git a/buy_screen.lua b/buy_screen.lua index ca85a89..97c0a10 100644 --- a/buy_screen.lua +++ b/buy_screen.lua @@ -13,14 +13,17 @@ function BuyScreen:on_enter(from, level) self.main = Group() self.effects = Group() self.ui = Group() + self.info_text = InfoText{group = self.ui} if self.level == 0 then + self.cards = {} + self.selected_card_index = 1 local units = {'vagrant', 'swordsman', 'wizard', 'archer', 'scout', 'cleric'} - PairCard{group = self.main, x = gw/2, y = 85, w = gw, h = gh/4, unit_1 = random:table_remove(units), unit_2 = random:table_remove(units), i = 1} + self.cards[1] = PairCard{group = self.main, x = gw/2, y = 85, w = gw, h = gh/4, unit_1 = random:table_remove(units), unit_2 = random:table_remove(units), i = 1, parent = self} local units = {'vagrant', 'swordsman', 'wizard', 'archer', 'scout', 'cleric'} - 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} + 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'} - 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} + 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 = Text({{text = '[fg]choose your initial party', font = pixul_font, alignment = 'center'}}, global_text_tags) end end @@ -34,6 +37,18 @@ function BuyScreen:update(dt) if self.level == 0 then self.title:update(dt) + if input.move_up.pressed then + self.selected_card_index = self.selected_card_index - 1 + if self.selected_card_index == 0 then self.selected_card_index = 3 end + for i = 1, 3 do self.cards[i]:unselect() end + self.cards[self.selected_card_index]:select() + end + if input.move_down.pressed then + self.selected_card_index = self.selected_card_index + 1 + if self.selected_card_index == 4 then self.selected_card_index = 1 end + for i = 1, 3 do self.cards[i]:unselect() end + self.cards[self.selected_card_index]:select() + end end end @@ -57,9 +72,7 @@ function PairCard:init(args) self:init_game_object(args) self.plus_r = 0 - if self.i == 1 then - self:select() - end + if self.i == 1 then self:select() end end @@ -70,7 +83,7 @@ end function PairCard:select() self.selected = true - self.spring:pull(0.05, 200, 10) + 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() @@ -78,6 +91,24 @@ function PairCard:select() end, 'pulse_2') end end, nil, nil, 'pulse') + + + self.parent.info_text:activate({ + {text = '[' .. character_color_strings[self.unit_1] .. ']' .. self.unit_1:upper() .. '[] - ' .. table.reduce(character_classes[self.unit_1], + function(memo, v) return memo .. '[' .. class_color_strings[v] .. ']' .. v .. '[fg], ' end, ''):sub(1, -3), font = pixul_font, height_multiplier = 1.1}, + {text = character_descriptions[self.unit_1](10), font = pixul_font}, + }, nil, nil, nil, nil, 20, 10, nil, 3) + self.parent.info_text.x = gw/2 + self.parent.info_text.y = gh/2 +end + + +function PairCard: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 @@ -86,7 +117,7 @@ function PairCard:draw() if self.selected then graphics.push(x + (fat_font:get_text_width(self.i) + 20)/2, self.y - 25 + 37/2, 0, self.spring.x*self.sx, self.spring.x*self.sy) - graphics.rectangle2(x - 52, self.y - 25, fat_font:get_text_width(self.i) + 20, 37, nil, nil, bg[2]) + graphics.rectangle2(x - 52, self.y - 25, fat_font:get_text_width(self.i) + 20, 37, 6, 6, bg[2]) graphics.pop() end @@ -123,5 +154,3 @@ function PairCard:draw() end graphics.pop() end - - diff --git a/devlog.md b/devlog.md index 71cbb67..9c7b8b4 100644 --- a/devlog.md +++ b/devlog.md @@ -324,3 +324,10 @@ UI work on the game's first screen. These days that I ended up not doing nothing to think up how exactly I want the game's UI to be like. I ended up thinking too much and paralyzed myself into not doing anything. Right now I'm just doing the most basic thing I can that still looks reasonably OK and conveys all the info needed. + +# Day 17 - 05/03/21 + +More UI stuff. Fairly slow moving but I'm slowly getting a clearer picture in my head of what the game's UI should be like which should make it easier to get it done. + +Also found this cool article today: https://halt.software/dead-simple-layouts/. This reminds me of one of my attempts from a few years ago at creating a clean UI abstraction but with a slightly different focus that seems promising. +I wonder if I should try implementing this now or leave it for the next game. diff --git a/engine/datastructures/table.lua b/engine/datastructures/table.lua index 6fe3622..df8df9d 100644 --- a/engine/datastructures/table.lua +++ b/engine/datastructures/table.lua @@ -255,7 +255,7 @@ end -- For those cases the third argument comes in handy and can be used to set the initial value of memo directly. function table.reduce(t, f, dv, ...) local memo = dv or t[1] - for i = 2, #t do + for i = 1, #t do memo = f(memo, t[i], i, ...) end return memo diff --git a/main.lua b/main.lua index 909745f..a246a10 100644 --- a/main.lua +++ b/main.lua @@ -87,6 +87,18 @@ function init() ['psy'] = fg[0], } + class_color_strings = { + ['warrior'] = 'yellow', + ['ranger'] = 'green', + ['healer'] = 'green', + ['conjurer'] = 'yellow', + ['mage'] = 'blue', + ['nuker'] = 'blue', + ['rogue'] = 'red', + ['enchanter'] = 'red', + ['psy'] = 'fg', + } + character_colors = { ['vagrant'] = fg[0], ['swordsman'] = yellow[0], @@ -110,6 +122,29 @@ function init() ['engineer'] = yellow[0], } + character_color_strings = { + ['vagrant'] = 'fg', + ['swordsman'] = 'yellow', + ['wizard'] = 'blue', + ['archer'] = 'green', + ['scout'] = 'red', + ['cleric'] = 'green', + ['outlaw'] = 'red', + ['blade'] = 'yellow', + ['elementor'] = 'blue', + ['saboteur'] = 'red', + ['stormweaver'] = 'red', + ['sage'] = 'blue', + ['squire'] = 'yellow', + ['cannoneer'] = 'green', + ['dual_gunner'] = 'green', + ['hunter'] = 'green', + ['chronomancer'] = 'blue', + ['spellblade'] = 'blue', + ['psykeeper'] = 'fg', + ['engineer'] = 'yellow', + } + character_classes = { ['vagrant'] = {'ranger', 'warrior', 'psy'}, ['swordsman'] = {'warrior'}, @@ -133,6 +168,33 @@ function init() ['engineer'] = {'conjurer'}, } + character_descriptions = { + ['vagrant'] = function(dmg) return '[fg]shoots a projectile that deals [yellow]' .. dmg .. '[fg] damage' end, + ['swordsman'] = function(dmg) return '[fg]deals [yellow]' .. dmg .. '[fg] damage in an area around the unit' end, + ['wizard'] = function(dmg) return '[fg]shoots a projectile that deals [yellow]' .. dmg .. ' AoE[fg] damage' end, + ['archer'] = function(dmg) return '[fg]shoots an arrow that deals [yellow]' .. dmg .. '[fg] damage and pierces' end, + ['scout'] = function(dmg) return '[fg]throws a knife that deals [yellow]' .. dmg .. '[fg] damage and chains [yellow]3[fg] times' end, + ['cleric'] = function() return '[fg]heals every unit for [yellow]10%[fg] max hp when any one drops below [yellow]50%[fg] max hp' end, + ['outlaw'] = function(dmg) return '[fg]throws a fan of [yellow]5[] knives, each dealing [yellow]' .. dmg .. '[fg] damage' end, + ['blade'] = function(dmg) return '[fg]throws multiple blades that deal [yellow]' .. dmg .. ' AoE[fg] damage' end, + ['elementor'] = function(dmg) return '[fg]deals [yellow]' .. dmg .. ' AoE[fg] damage to a random target' end, + ['saboteur'] = function(dmg) return '[fg]calls [yellow]4[] saboteus to seek targets and deal [yellow]' .. dmg .. ' AoE[fg] damage' end, + ['stormweaver'] = function(dmg) return '[fg]infuses all allied projectiles with chain lightning that deals [yellow]+' .. dmg .. '[fg] damage on hit' end, + ['sage'] = function(dmg) return '[fg]shoots a slow projectile that draws enemies in' end, + ['squire'] = function(dmg) return '[yellow]+10 dmg[fg] & [yellow]+25 def[fg] to adjacent units, heal them for [yellow]10%[fg] max hp every 8 seconds' end, + ['cannoneer'] = function(dmg) return '[fg]shoots a projectile that deals [yellow]' .. dmg .. ' AoE[fg] damage' end, + ['dual_gunner'] = function() return '[fg]shoots two parallel projectiles' end, + ['hunter'] = function(dmg) return '[fg]shoots an arrow that deals [yellow]' .. dmg .. '[fg] damage and has a [yellow]20%[fg] chance to summon a pet' end, + ['chronomancer'] = function() return '[yellow]+25% aspd[fg] to adjacent units' end, + ['spellblade'] = function(dmg) return '[fg]throws knives that deal [yellow]' .. dmg .. '[fg] damage, pierce and spiral outwards' end, + ['psykeeper'] = function() return '[fg]all damage taken is stored and distributed as healing to all allies' end, + ['engineer'] = function(dmg) return '[fg]drops sentries that shoot bursts of projectiles, each dealing [yellow]' .. dmg .. '[fg] damage' end, + } + + character_stats = { + + } + units = {} resource = 0 diff --git a/shared.lua b/shared.lua index bbd2ae9..3c118ac 100644 --- a/shared.lua +++ b/shared.lua @@ -439,6 +439,7 @@ function InfoText:init(args) self.sx, self.sy = 0, 0 self.ox, self.oy = 0, 0 self.ow, self.oh = 0, 0 + self.tox, self.toy = 0, 0 self.text = Text({}, global_text_tags) end @@ -451,25 +452,25 @@ end function InfoText:draw() graphics.push(self.x + self.ox, self.y + self.oy, 0, self.sx*self.spring.x, self.sy*self.spring.x) graphics.rectangle(self.x + self.ox, self.y + self.oy, self.text.w + self.ow, self.text.h + self.oh, self.text.h/4, self.text.h/4, bg[-2]) - self.text:draw(self.x + self.ox, self.y + self.oy + self.text.h/2) + self.text:draw(self.x + self.ox + self.tox, self.y + self.oy + self.toy) graphics.pop() end -function InfoText:activate(text, ox, oy, sx, sy, ow, oh) - ox, oy = 0, 0 - sx, sy = 1, 1 - ow, oh = 16, 4 +function InfoText:activate(text, ox, oy, sx, sy, ow, oh, tox, toy) + self.ox, self.oy = ox or 0, oy or 0 + self.sx, self.sy = sx or 1, sy or 1 + self.ow, self.oh = ow or 0, oh or 0 + self.tox, self.toy = tox or 0, toy or 0 self.text:set_text(text) self.t:cancel'deactivate' - self.t:tween(0.1, self, {sx = sx, sy = sy}, math.cubic_in_out, function() self.sx, self.sy = sx, sy end, 'activate_1') - self.t:after(0.075, function() self.spring:pull(0.1, 200, 10) end, 'activate_2') + self.t:tween(0.1, self, {sx = sx or 1, sy = sy or 1}, math.cubic_in_out, function() self.sx, self.sy = sx or 1, sy or 1 end, 'activate') + self.spring:pull(0.075) end function InfoText:deactivate() - self.t:cancel'activate_1' - self.t:cancel'activate_2' + self.t:cancel'activate' self.t:tween(0.05, self, {sy = 0}, math.linear, function() self.sy = 0 end, 'deactivate') end