diff --git a/libs/simple-button.lua b/libs/simple-button.lua index d262e1e..2560ce0 100644 --- a/libs/simple-button.lua +++ b/libs/simple-button.lua @@ -61,7 +61,8 @@ local button = { codeWhenPressed = NULL, codeWhenReleased = NULL, - _hovering = false + _hovering = false, + _pressed = false, }; button.__index = button function button:draw() love.graphics.setLineWidth(self.borderWidth) @@ -107,14 +108,23 @@ function button:isHovering(x,y) return self._hovering end ---Trigger press action, only when ``self._hovering`` is true -function button:press() - if self._hovering then self.codeWhenPressed() end +function button:press(x, y) + if self:isHovering(x, y) and not self._pressed then + self.codeWhenPressed() + self._pressed = true + end end ---Trigger release action, don't need ``self._hovering`` to ``true`` -function button:release() - if self._hovering then +---@param isMouse? boolean Button just released by mouse? +function button:release(x, y, isTouch) + if self:isHovering(x, y) and self._pressed then self.codeWhenReleased() - self._hovering = false + self._pressed = false + if isTouch then + self._hovering = false + else + self:isHovering(x, y) + end end end @@ -204,4 +214,38 @@ function BUTTON.setDefaultOption(D) end end +-- < EXTRA GENERAL OPTIONS > + +---Draw all buttons in provided list +---@param list table +function BUTTON.draw(list) + for _, v in pairs(list) do v:draw() end +end + +---Check if current mouse position is inside button
+---Calling BUTTON.press will trigger this, but you can call it when moving mouse so button can be highlighted when being hovered +---@param list table +---@param x number # Mouse position +---@param y nunber # Mouse position +function BUTTON.checkHovering(list, x, y) + for _, v in pairs(list) do v:isHovering(x, y) end +end + +--- Trigger the press action, only if ``button._hovering == true`` +---@param list table +---@param x number # Mouse position +---@param y nunber # Mouse position +function BUTTON.press(list, x, y) + for _, v in pairs(list) do v:press(x, y) end +end + +---Trigger the release action +---@param list table +---@param x number # Mouse position +---@param y nunber # Mouse position +---@param isMouse? boolean # Is mouse just released a button? +function BUTTON.release(list, x, y, isTouch) + for _, v in pairs(list) do v:release(x, y, isTouch) end +end + return BUTTON \ No newline at end of file diff --git a/load.lua b/load.lua index 2805300..edc65f0 100644 --- a/load.lua +++ b/load.lua @@ -7,10 +7,13 @@ FONT_tromi = love.graphics.newFont('res/fonts/monofonto rg.otf', 28) FONT_big = love.graphics.newFont('res/fonts/monofonto rg.otf', 56) local font_height = FONT_tromi:getHeight() * 0.5 +local font_big_height = FONT_big:getHeight() * 0.5 -- BUTTON library BUTTON = require "libs.simple-button" BUTTON.setDefaultOption{ draw = function(self) + local need_big_font = (self.font == FONT_big) + love.graphics.setColor(0, 0, 0, 0.8) love.graphics.rectangle('fill', self.x, self.y, self.w, self.h, self.r) @@ -21,14 +24,25 @@ BUTTON.setDefaultOption{ local lineAmount do - local _, t = FONT_tromi:getWrap(self.text, self.w * 2) + local _, t + if need_big_font then + _, t = FONT_big:getWrap(self.text, self.w * 2) + else + _, t = FONT_tromi:getWrap(self.text, self.w * 2) + end lineAmount = #t end - - local textHeight = font_height * (lineAmount * 0.5) + + local _font_height = need_big_font and font_big_height or font_height + + local textHeight = _font_height * (lineAmount * 0.5) local textPos = self.y + (self.h * 0.5) - textHeight - drawText(self.text, self.x, textPos, self.w, 'center') + if need_big_font then + drawBigText(self.text, self.x, textPos, self.w, 'center') + else + drawText(self.text, self.x, textPos, self.w, 'center') + end love.graphics.setColor(1, 1, 1, 0.8) love.graphics.setLineWidth(1) diff --git a/main.lua b/main.lua index 52cdad3..94cbb67 100644 --- a/main.lua +++ b/main.lua @@ -51,7 +51,10 @@ function love.load() require "scene" require "game.vctrl" -- VCTRL - SCENE = SETTINGS.firstTime and InputConfigScene(true) or TitleScene() + SCENE.update = function() + SCENE = SETTINGS.firstTime and InputConfigScene(true) or TitleScene() + end + -- VCTRL.toggle(love.system.getOS()=='Android' or true) VCTRL.new{ -- up down left right --- right left down up -- {type='button',x= 100,y=320,key= 'up',r=35,iconSize=60,alpha=0.75}, @@ -116,11 +119,11 @@ function love.draw() love.graphics.pop() end -function love.mousepressed(x, y, b, _, presses) +function love.mousepressed(x, y, b, isTouch, presses) local x,y=GLOBAL_TRANSFORM:inverseTransformPoint(x,y) SCENE:onInputPress{type = "mouse", x = x, y = y, button = b, presses = presses} end -function love.mousereleased(x,y, b, _, presses) +function love.mousereleased(x, y, b, isTouch, presses) local x,y=GLOBAL_TRANSFORM:inverseTransformPoint(x,y) SCENE:onInputRelease{type = "mouse", x = x, y = y, button = b, presses = presses} end @@ -370,11 +373,10 @@ function love.run() end function love.errorhandler(msg) + local msg = msg or "REV! BÀ ĂN CÁI TỜ TIN NHẮN LỖI RỒI À?!" local showScreenshot = false local errorCopied = false - - -- Reset audio. - if love.audio then love.audio.stop() end + local enter_fullscreen = SETTINGS and SETTINGS["fullscreen"] or false -- Render everything again in a canva love.graphics.origin() @@ -403,13 +405,15 @@ function love.errorhandler(msg) ) love.graphics.setCanvas() + love.audio.stop() + -- Handling the error local err={"Error:"..msg} local c=2 for l in debug.traceback("",2):gmatch("(.-)\n") do if c>2 then if not l:find("boot") then - err[c]=l:gsub("^\t*","") + err[c]=l:gsub("^\t*","\t") c=c+1 end else @@ -434,17 +438,20 @@ function love.errorhandler(msg) drawText([[ OH NO! Tromi has crashed. Since this is not the official port, please do not report any bugs to mycophobia. -Instead, report this to me via my Discord ``sweetsea`` with a screenshot of this. +Instead, report this to me via my Discord ``sweetsea'' with a screenshot of this. -REMEMBER TO SCREENSHOT BECAUSE ERROR INFO IS NOT SAVED! +REMEMBER TO SCREENSHOT ERROR INFO BEFORE QUITTING BECAUSE THEY ARE NOT SAVED! -Ctrl + C: copy the error info | If you click or tap, a window appear with 4 options: -Space : show/hide screenshot | OK: Quit Copy: copy error info +Ctrl + C: copy the error info | If you click / tap, a window appears with 4 options: +Space : show/hide screenshot | OK : Quit Copy: copy error info Escape : Quit | Cancel: Go back Show: show/hide screenshot +]], 20, 10, 620, "left") -Traceback:]]..(errorCopied and " (Copied to clipboard)" or ""), - 20, 10, 620, "left") - drawText(p, 40, 200, 600, "left") + drawText(err[1]:sub(7).."\nTraceback:"..(errorCopied and " (Copied to clipboard)\n" or "\n")..p, 20, 180, 620, "left") + else + love.graphics.setColor(0, 0, 0, 0.8) + love.graphics.rectangle("fill", 15, 450, 400, 25, 5, 5) + drawText("Tromi has crashed! Press Space or tap to show error info", 15, 455, 400, "left") end love.graphics.present() @@ -471,10 +478,10 @@ Traceback:]]..(errorCopied and " (Copied to clipboard)" or ""), elseif e == "keypressed" and a == "space" then showScreenshot = not showScreenshot elseif e == "keypressed" and a == "f4" then - SETTINGS["fullscreen"] = not SETTINGS["fullscreen"] - love.window.setFullscreen(SETTINGS["fullscreen"]) - elseif e == "touchpressed" or e == "mousepressed" then - local pressed = love.window.showMessageBox("Quit Tromi?", "Remember to save a copy of screenshot, since they are not saved!", buttons) + enter_fullscreen = not enter_fullscreen + love.window.setFullscreen(enter_fullscreen) + elseif e == "mousepressed" then + local pressed = love.window.showMessageBox("Quit? Screenshot? Copy?", "Remember to screenshot error info before quitting because they are not saved!", buttons) if pressed == 1 then return 1 elseif pressed == 3 then diff --git a/scene.lua b/scene.lua index ea8220d..25c1d0c 100644 --- a/scene.lua +++ b/scene.lua @@ -4,7 +4,9 @@ SCENE = Object:extend() function SCENE:new() end function SCENE:update() end -function SCENE:render() end +function SCENE:render() + love.graphics.draw(LOADING_IMAGE_FILE,0,0,0,0.5) +end -- You can use the class SCENE_onInput to show suggestions for `e` table diff --git a/scene/name_entry.lua b/scene/name_entry.lua index de5d609..d1829d1 100644 --- a/scene/name_entry.lua +++ b/scene/name_entry.lua @@ -1,11 +1,22 @@ local NameEntryScene = SCENE:extend() NameEntryScene.title = "Game Start" +local buttonList = { + BUTTON.new{ + text = "<\nCHAR", font = FONT_big, + x = 40, y = 160, w = 70, h = 70, + }, + BUTTON.new{ + text = ">\nCHAR", font = FONT_big, + x = 130, y = 160, w = 70, h = 70, + } +} + local Grid = require 'game.grid' local bitser = require 'libs.bitser' function NameEntryScene:new() - self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890." + self.hars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890." self.char_pos = 1 self.name_entry = {'A','A','A'} self.entry_pos = 1 @@ -48,6 +59,8 @@ end function NameEntryScene:render() MainBackground() + BUTTON.draw(buttonList) + love.graphics.setColor(1, 1, 1, 1) love.graphics.line(216,80,216,80+(16*self.grid.height)) love.graphics.line(216+(16*self.grid.width),80,216+(16*self.grid.width),80+(16*self.grid.height)) @@ -108,8 +121,16 @@ function NameEntryScene:update() self.entry_chars = self.name_entry[1]..self.name_entry[2]..self.name_entry[3] end +function NameEntryScene:onInputMove(e) + if e.type == "mouse" then + BUTTON.checkHovering(buttonList, e.x, e.y) + end +end + function NameEntryScene:onInputPress(e) - if e.input == "menu_decide" or e.input == "rotate_left" or e.scancode == "return" then + if e.type == "mouse" or e.type == "touch" then + BUTTON.press(buttonList, e.x, e.y) + elseif e.input == "menu_decide" or e.input == "rotate_left" or e.scancode == "return" then self.delete_confirm = false self.delete_input_count = 0 if self.entry_pos == 4 then @@ -177,7 +198,11 @@ function NameEntryScene:onInputPress(e) end function NameEntryScene:onInputRelease(e) - if e.input == "left" or e.scancode == "left" or e.input == "right" or e.scancode == "right" then + if e.type == "mouse" then + BUTTON.release(buttonList, e.x, e.y) + elseif e.type == "touch" then + BUTTON.release(buttonList, e.x, e.y, true) + elseif e.input == "left" or e.scancode == "left" or e.input == "right" or e.scancode == "right" then self.direction = nil self.repeat_counter = self.repeat_limit-1 end diff --git a/scene/title.lua b/scene/title.lua index 65ad81b..b02211f 100644 --- a/scene/title.lua +++ b/scene/title.lua @@ -94,15 +94,29 @@ end function TitleScene:onInputPress(e) if e.type == "touch" then local selecting = math.floor((e.y - 198) / 20) - if (e.x >= 20 and e.x <= 260) and (selecting > 0 and selecting <= #main_menu_screens) then + if + (e.x >= 20 and e.x <= 260) and + (selecting > 0 and selecting <= #main_menu_screens) + then if self.main_menu_state ~= selecting then self.main_menu_state = selecting else VCTRL.toggle(true) SCENE = main_menu_screens[selecting]() end - elseif e.x >= 14 and e.y >= 40 and e.x <= 274 and e.y <= 170 then - + elseif + e.x >= 14 and + e.y >= 40 and + e.x <= 274 and + e.y <= 160 + then + if e.x >= 137 then -- Right + table.remove(self.code, 8) + table.insert(self.code, 1, 1) + else -- Left + table.remove(self.code, 8) + table.insert(self.code, 1, -1) + end end else if e.input == "menu_decide" or e.input == "rotate_left" or e.scancode == "return" then diff --git a/scene/touch_config.lua b/scene/touch_config.lua index 8c0b895..383e705 100644 --- a/scene/touch_config.lua +++ b/scene/touch_config.lua @@ -7,7 +7,7 @@ TouchConfigScene.title = "Touchscreen config\n(you can tap anywhere on touch scr 2. Add behaviors ]] -local widgetList = { +local buttonList = { select_widget = BUTTON.new{ text = "Select key\n[Rotate right 2]", x = 10, y = 10, w = 120, h = 110 @@ -33,6 +33,7 @@ local widgetList = { BUTTON.new{ text = "Opacity: 50%\nTap to reset", x = 255, y = 70, w = 100, h = 50, + codeWhenReleased = function() PlaySE("autopromote") end }, BUTTON.new{ text = "[+]\nTotally see", @@ -52,23 +53,7 @@ local widgetList = { text = "RESET to\nDEFAULT", x = 560, y = 70, w = 70, h = 50, }, - } -local function widgetList_update() - for _, v in pairs(widgetList) do v:update() end -end -local function widgetList_draw() - for _, v in pairs(widgetList) do v:draw() end -end -local function widgetList_isHovering(x, y) - for _, v in pairs(widgetList) do v:isHovering(x, y) end -end -local function widgetList_press() - for _, v in pairs(widgetList) do v:press() end -end -local function widgetList_release() - for _, v in pairs(widgetList) do v:release() end -end function TouchConfigScene:new() -- TODO @@ -79,31 +64,28 @@ end function TouchConfigScene:render() MainBackground() - widgetList_draw() + BUTTON.draw(buttonList) end ---@param e SCENE_onInput function TouchConfigScene:onInputMove(e) if e.type == "mouse" then - widgetList_isHovering(e.x, e.y) + BUTTON.checkHovering(buttonList, e.x, e.y) end end ---@param e SCENE_onInput function TouchConfigScene:onInputPress(e) if e.input == 'menu_back' then SCENE = InputConfigScene() end - if e.type == "mouse" then widgetList_press() end - if e.type == "touch" then - widgetList_isHovering(e.x,e.y) - widgetList_press() + if e.type == "mouse" or e.type == "touch" then + BUTTON.press(buttonList, e.x, e.y) end end ---@param e SCENE_onInput function TouchConfigScene:onInputRelease(e) if e.type == "mouse" then - widgetList_release() - widgetList_isHovering(x, y) + BUTTON.release(buttonList, e.x, e.y) elseif e.type == "touch" then - widgetList_release() + BUTTON.release(buttonList, e.x, e.y, true) end end