V1 update (#1)

This commit is contained in:
Nguyễn Quốc Hưng
2024-06-06 16:01:24 +07:00
committed by Squishy (C6H12O6+NaCl+H2O)
parent 3343d8711b
commit 1d6643448e
30 changed files with 1000 additions and 228 deletions

View File

@@ -35,28 +35,35 @@ Ported to Android (mobile and TV) by SweetSea with on-screen control (with some
### Launch ### Launch
Navigate to where you put ``tromi_mobile.love`` in the File manager (the one you downloaded from the link in Install for TV section), just opening and Tromi should be launched. Navigate to where you put ``tromi_mobile.love`` in the File manager (the one you downloaded from the link in Install for TV section), just opening and Tromi should be launched.
# Differences from original Tromi # Changes
> I must make this list to follow the used license (GNU GPL v3)<br> > I must make this list to follow the used license (GNU GPL v3)<br>
> :no_entry: There are ***very much*** breaking changes right now, and I can't always finish this list. I may try hard to do it. > :no_entry: There are ***very much*** breaking changes right now, and I can't always finish this list. I may try hard to do it.
* No differences in gameplay * **NO DIFFERENCES IN GAMEPLAY**
* Files will be saved into ``Android/data/org.love2d.android/tromi_mobile`` instead the location where the game files in * Files will be saved into ``Android/data/org.love2d.android/tromi_mobile`` instead the location where the game files in
* Add ``simple-button`` module, made by me (SweetSea) * Add replay importer / exporter through clipboard
* All UIs are touch-able * UI are re-designed to compactible with touch screen
* Add on-screen buttons * Add on-screen buttons
* Replaced icons for 3 direction buttons (Left, Down, Right), using from Techmino's font (outdated image) * Replaced icons for 3 direction buttons (Left, Down, Right), using from Techmino's font.
<img src="https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile/raw/branch/main/screenshot/Replay_screen_differences.png"> * Add a special pre-made keybind for Android TV (only supports TV models have their remote has numerical area (0-9)).
* Add a special pre-made keybind for Android TV (only supports TV models have their remote has numerical area (0-9))<img src="https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile/raw/branch/main/screenshot/SPOILER_tv_code.png"> * To use it, you have to activate TV mode. Type ``88663366`` by using your remote or external keyboard at the "Control method selection screen" (Tromi will show this screen at the first boot). After typing, Tromi will automatically use that keybind.
* <details><summary>Changes the way to input secret code to activate Pentominoes mode</summary><img src="https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile/raw/branch/main/screenshot/SPOILER_pento_code.png">To insert the left arrow, tap on the left, so does to right arrow.</details> * To deactivate TV mode, press ``........`` (8 dots). ***WARNING:*** the keyboard method will be resetted, which mean if you have assigned another keybind for keyboard, it will also be erased.
* Add a loading screen ~~(this need to be updated later)~~ * Change the way to input secret code to activate Pentominoes mode.
* Add a loading screen
* Update ``binser`` library, this fixes some weird bugs related to saving * Update ``binser`` library, this fixes some weird bugs related to saving
* Replaced old Cambridge's ``config`` module with the new one inspired by "the sequel of Techmino"s ``SETTINGS`` module * Add ``simple-button`` module, made by me (SweetSea)
* Replaced old Cambridge's ``config`` module with the new one inspired by "the sequel of Techmino"s ``SETTINGS`` module".
# TODO # TODO
- [ ] Add a way to export ~~replay~~ data for Android > 11 - [x] Add a way to export replay data for Android > 11
- [x] Revert ``bitser`` with ``binser`` (if and only if I can make it works) - [x] Revert ``bitser`` with ``binser`` (if and only if I can make it works)
- [x] Design a new on-screen buttons skin (the current one is come from [C₂₉H₂₅N₃O₅](https://github.com/C29H25N3O5), I am aware that it's not fit to Tromi's design language) - [x] Design a new on-screen buttons skin (the current one is come from [C₂₉H₂₅N₃O₅](https://github.com/C29H25N3O5), I am aware that it's not fit to Tromi's design language)
- [ ] Updating on-screen control configuration screen - [x] Updating on-screen control configuration screen
- [ ] (Low priority) Design a new menu screen - [x] (Low priority) Design a new menu screen
- [ ] Add user data management
- [ ] Redesign "the Control method selection" screen
- [ ] Redesign the replay screen
- [ ] Add shortcut to open replay converter at https://sweetsea-butimnotsweet.github.io/tromi_replay_converter
# License (GNU GPLv3) # License (GNU GPLv3)
Please read ``COPYING.txt`` for more information.<br> Please read ``COPYING.txt`` for more information.<br>

View File

@@ -88,8 +88,8 @@ local L={
hollowLogo= 0xF008C, hollowLogo= 0xF008C,
toUp= 0xF008D, toUp= 0xF008D,
toDown= 0xF008E, toDown= 0xF008E,
toLeft= 0xF008F, toLeft= 0xF0090,
toRight= 0xF0090, toRight= 0xF008F,
checkMark= 0xF0091, checkMark= 0xF0091,
crossMark= 0xF0092, crossMark= 0xF0092,
musicMark= 0xF0093, musicMark= 0xF0093,

View File

@@ -94,6 +94,13 @@ function math.roundUnit(n,u)
return math.floor(n/u+.5)*u return math.floor(n/u+.5)*u
end end
---@return table
function table.pack(...)
local t = {...}
t.n = select('#', ...)
return t
end
---@param t1 table ---@param t1 table
---@param t2 table ---@param t2 table
---@return table t ---@return table t
@@ -143,15 +150,6 @@ function drawText(text, x, y, size, orientation, color)
love.graphics.printf(text, x, y, size*2, orientation, nil, 0.5) love.graphics.printf(text, x, y, size*2, orientation, nil, 0.5)
end end
function drawBoldText(text, x, y, size, orientation, color)
if color == nil then color = {1, 1, 1, 1} end
love.graphics.setFont(FONT_bold)
love.graphics.setColor(0, 0, 0, 0.8)
love.graphics.printf(text, x+1, y+1, size*2, orientation, nil, 0.50)
love.graphics.setColor(color)
love.graphics.printf(text, x, y, size*2, orientation, nil, 0.5)
end
function drawBigText(text, x, y, size, orientation, color) function drawBigText(text, x, y, size, orientation, color)
if color == nil then color = {1, 1, 1, 1} end if color == nil then color = {1, 1, 1, 1} end
love.graphics.setFont(FONT_big) love.graphics.setFont(FONT_big)

View File

@@ -1,9 +1,9 @@
local Object = require 'libs.classic' local Object = require 'libs.classic'
local bit = require("bit") local bit = require("bit")
local lualzw = require 'libs.lualzw' local lualzw = require 'libs.lualzw'
local bitser = require 'libs.bitser'
local playedReadySE = false local playedReadySE = false
local hiscore_pos
local Grid = require 'game.grid' local Grid = require 'game.grid'
local Randomizer = require 'game.randomizer' local Randomizer = require 'game.randomizer'
@@ -11,7 +11,9 @@ local Randomizer = require 'game.randomizer'
local GameMode = Object:extend() local GameMode = Object:extend()
function GameMode:new(player_name, input_file, replay_grade) function GameMode:new(player_name, input_file, replay_grade)
VCTRL.toggle(MOBILE and not input_file and not SETTINGS.tvMode) -- VCTRL.toggle(MOBILE and not input_file and not SETTINGS.tvMode)
VCTRL.toggle(true)
VCTRL.reset()
if player_name == nil then self.training = true else self.training = false end if player_name == nil then self.training = true else self.training = false end
if input_file ~= nil then if input_file ~= nil then
@@ -149,7 +151,7 @@ function GameMode:readGradeHistory()
if self.grade > 1 then if self.grade > 1 then
local temp_grade = copy(self.grade_history); temp_grade[2] = 0 local temp_grade = copy(self.grade_history); temp_grade[2] = 0
FILE.write(SAVE_DIR..self.player_name.."_grade_history.sav", temp_grade) FILE.write(SAVE_DIR..self.player_name.."_grade_history.sav", temp_grade)
end end
end end
function GameMode:readHiScores() function GameMode:readHiScores()
@@ -979,7 +981,7 @@ function GameMode:drawScoringInfo()
love.graphics.rectangle("fill", 95, 80, 110, 180, 10, 10) love.graphics.rectangle("fill", 95, 80, 110, 180, 10, 10)
if not PENTO_MODE then drawText("Grade:", 100, 128, 1000, "left") end if not PENTO_MODE then drawText("Grade:", 100, 128, 1000, "left") end
-- Line & Level -- Line & Level
if self.training or SETTINGS["lines"] then if self.input_playback or SETTINGS["lines"] then
love.graphics.setColor(0,0,0,0.5) love.graphics.setColor(0,0,0,0.5)
love.graphics.rectangle("fill", 241, 407, 116, 40, 5, 5) --lines love.graphics.rectangle("fill", 241, 407, 116, 40, 5, 5) --lines
love.graphics.setColor(0.05,0.05,0.05,1) love.graphics.setColor(0.05,0.05,0.05,1)
@@ -992,7 +994,7 @@ function GameMode:drawScoringInfo()
love.graphics.rectangle("fill", 68, 270, 140, 190, 10, 10) love.graphics.rectangle("fill", 68, 270, 140, 190, 10, 10)
love.graphics.setColor(0.05,0.05,0.05,1) love.graphics.setColor(0.05,0.05,0.05,1)
love.graphics.rectangle("fill", 65, 267, 140, 190, 10, 10) love.graphics.rectangle("fill", 65, 267, 140, 190, 10, 10)
drawBoldText(string.format("REPLAY IN PROGRESS\n\n\n\n\n\n\n\n\n%s", formatTime(self.frames)), 70, 275, 1000, "left") drawText(string.format("REPLAY IN PROGRESS\n\n\n\n\n\n\n\n\n%s", formatTime(self.frames)), 70, 275, 1000, "left")
drawBigText(string.format("%s", self.grade), 100, 143, 1000, "left") drawBigText(string.format("%s", self.grade), 100, 143, 1000, "left")
self:drawInputDisplay(103,185) self:drawInputDisplay(103,185)
elseif not PENTO_MODE then elseif not PENTO_MODE then
@@ -1073,6 +1075,7 @@ end
function GameMode:drawFrame() function GameMode:drawFrame()
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.setLineWidth(1)
love.graphics.line(216,80,216,80+(16*self.grid.height)) 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)) love.graphics.line(216+(16*self.grid.width),80,216+(16*self.grid.width),80+(16*self.grid.height))
love.graphics.line(216,80+(16*self.grid.height),216+(16*self.grid.width),80+(16*self.grid.height)) love.graphics.line(216,80+(16*self.grid.height),216+(16*self.grid.width),80+(16*self.grid.height))

View File

@@ -64,7 +64,7 @@ function control_type.button:new(data)
r=data.r or 80, -- size r=data.r or 80, -- size
shape=data.shape or 'circle', shape=data.shape or 'circle',
key=data.key or 'X', key=data.key or 'X',
iconSize=data.iconSize or 80, iconSize=data.iconSize or 60,
alpha=data.alpha or 0.75, alpha=data.alpha or 0.75,
quad=virtual_quad[data.key] quad=virtual_quad[data.key]
},self) },self)
@@ -90,7 +90,7 @@ end
function control_type.button:press(_,_,id) function control_type.button:press(_,_,id)
self.pressed=true self.pressed=true
self.lastPressTime=love.timer.getTime() self.lastPressTime=love.timer.getTime()
self.pressing=id self.pressingID=id
-- love.keypressed(self.key, love.keyboard.getScancodeFromKey(self.key)) -- love.keypressed(self.key, love.keyboard.getScancodeFromKey(self.key))
SCENE:onInputPress{input=self.key,type="virtual"} SCENE:onInputPress{input=self.key,type="virtual"}
end end
@@ -148,6 +148,7 @@ local touches={}
local global_toggle=false local global_toggle=false
VCTRL={} VCTRL={}
VCTRL.focus=nil -- Focusing buttons VCTRL.focus=nil -- Focusing buttons
VCTRL.hasChanged = false
---@class VCTRL.data ---@class VCTRL.data
---@field type 'button' ---@field type 'button'
@@ -231,6 +232,13 @@ function VCTRL.draw(forceAlpha)
end end
end end
function VCTRL.reset()
for _, w in ipairs(VCTRL) do
if w.pressingID then touches[w.pressingID] = nil end
w:reset()
end
end
function VCTRL.exportAll() function VCTRL.exportAll()
local t = {} local t = {}
for o, k in ipairs(VCTRL) do t[o] = k:export() end for o, k in ipairs(VCTRL) do t[o] = k:export() end

View File

@@ -139,11 +139,11 @@ function button:isHovering(x,y)
end end
---Trigger press action, only when ``self._hovering`` is true ---Trigger press action, only when ``self._hovering`` is true
function button:press(x, y, touchID) function button:press(x, y, touchID)
if (touchID and self:isHovering(x, y) or self._hovering) and not self._pressed then if self:isHovering(x, y) and not self._pressed then
self.codeWhenPressed()
self._touchID = touchID self._touchID = touchID
self._pressed = true self._pressed = true
self.codeWhenPressed()
self:draw() self:draw()
return true return true
@@ -154,7 +154,7 @@ function button:release(x, y, touchID)
local valid = true local valid = true
if touchID then if touchID then
valid = touchID == self._touchID valid = touchID == self._touchID
elseif x and y then else
valid = true valid = true
end end
@@ -311,4 +311,13 @@ function BUTTON.release(list, x, y, touchID)
for _, v in pairs(list) do if v:release(x, y, touchID) then return true end end for _, v in pairs(list) do if v:release(x, y, touchID) then return true end end
end end
--- Do a reset, useful for switching scenes
function BUTTON.reset(list)
for _, v in pairs(list) do
v._pressed = false
v._hovering = false
v._touchID = false
end
end
return BUTTON return BUTTON

View File

@@ -1,10 +1,8 @@
-- Fonts -- Fonts
FONT_tromi = love.graphics.newFont('res/fonts/Iosevka-Bold.ttf' , 28) FONT_tromi = love.graphics.newFont('res/fonts/Iosevka-Bold.ttf' , 28)
FONT_big = love.graphics.newFont('res/fonts/Iosevka-Heavy.ttf', 56) FONT_big = love.graphics.newFont('res/fonts/Iosevka-Heavy.ttf', 56)
FONT_bold = love.graphics.newFont('res/fonts/Iosevka-Heavy.ttf', 28)
-- Icons -- Icons
FONT_tromi:setFallbacks(love.graphics.newFont('res/fonts/techmino_proportional.otf', 28)) FONT_tromi:setFallbacks(love.graphics.newFont('res/fonts/techmino_proportional.otf', 28))
FONT_bold :setFallbacks(love.graphics.newFont('res/fonts/techmino_proportional.otf', 28))
FONT_big :setFallbacks(love.graphics.newFont('res/fonts/techmino_proportional.otf', 56)) FONT_big :setFallbacks(love.graphics.newFont('res/fonts/techmino_proportional.otf', 56))
CHAR = require("char") CHAR = require("char")
@@ -48,8 +46,6 @@ BUTTON.setDefaultOption{
if self.font == FONT_big then if self.font == FONT_big then
drawBigText(text, self.x + 2.5, textPos, self.w - 5, self.textOrientation, self.textColor) drawBigText(text, self.x + 2.5, textPos, self.w - 5, self.textOrientation, self.textColor)
elseif self.font == FONT_bold then
drawBoldText(text, self.x + 2.5, textPos, self.w - 5, self.textOrientation, self.textColor)
else else
drawText(text, self.x + 2.5, textPos, self.w - 5, self.textOrientation, self.textColor) drawText(text, self.x + 2.5, textPos, self.w - 5, self.textOrientation, self.textColor)
end end

View File

@@ -2,17 +2,17 @@ if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE")=="1" then
LLDEBUGGER=require('lldebugger') LLDEBUGGER=require('lldebugger')
LLDEBUGGER.start() LLDEBUGGER.start()
end end
require 'funcs'
DEBUG_showKey = false
PENTO_MODE = false PENTO_MODE = false
SAVE_DIR = 'saves/' SAVE_DIR = 'saves/'
REPLAY_DIR = 'saves/replays/' REPLAY_DIR = 'saves/replays/'
CONFIG_FILE = 'config.sav'
HIscoreFILE = 'hiscores.sav'
if not love.filesystem.getInfo(REPLAY_DIR) then if not love.filesystem.getInfo(REPLAY_DIR) then
love.filesystem.createDirectory(REPLAY_DIR) love.filesystem.createDirectory(REPLAY_DIR)
end end
CONFIG_FILE = 'config.sav'
HIscoreFILE = 'hiscores.sav' BACKGROUND_COLOR = {32/255, 120/255, 88/255}
CURRENT_OS = love.system.getOS() CURRENT_OS = love.system.getOS()
MOBILE = CURRENT_OS == "Android" or CURRENT_OS == "iOS" MOBILE = CURRENT_OS == "Android" or CURRENT_OS == "iOS"
@@ -34,6 +34,7 @@ function ShowLoadingText(thing)
end end
function love.load() function love.load()
require 'funcs'
math.randomseed(os.time()) math.randomseed(os.time())
require "modules.file" "binser" require "modules.file" "binser"
require "settings" require "settings"
@@ -48,19 +49,11 @@ function love.load()
-- Now it's real time to load all stuffs! -- Now it's real time to load all stuffs!
require "load" -- Most game's resources are loaded in here require "load" -- Most game's resources are loaded in here
require "modules.scene" require "scene"
require "game.vctrl" -- VCTRL require "game.vctrl" -- VCTRL
function SCENE.update() SCENE = LoadingScene()
SCENE.update = function() end
SCENE = SETTINGS.firstTime and InputConfigScene(true) or TitleScene()
end
function SCENE.render()
SCENE.render = function() end
love.graphics.draw(LOADING_IMAGE_FILE,0,0,0,0.5)
end
-- VCTRL.toggle(love.system.getOS()=='Android' or true)
-- VCTRL.new{ -- up down left right --- right left down up -- 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}, -- -- {type='button',x= 100,y=320,key= 'up',r=35,iconSize=60,alpha=0.75},
-- -- {type='button',x= 100,y=440,key= 'down',r=35,iconSize=60,alpha=0.75}, -- -- {type='button',x= 100,y=440,key= 'down',r=35,iconSize=60,alpha=0.75},
@@ -104,14 +97,10 @@ function love.draw()
-- love.graphics.line(0, grid_height * iy, 640, grid_height * iy) -- love.graphics.line(0, grid_height * iy, 640, grid_height * iy)
-- end -- end
-- local x, y = GLOBAL_TRANSFORM:inverseTransformPoint(love.mouse.getPosition()) local x, y = GLOBAL_TRANSFORM:inverseTransformPoint(love.mouse.getPosition())
-- love.graphics.setColor(0, 0, 0, 0.8) love.graphics.setColor(0, 0, 0, 0.8)
-- love.graphics.rectangle("fill", 5, 450, 115, 25) love.graphics.rectangle("fill", 5, 450, 115, 25)
-- drawText(string.format("X: %.1d; Y: %.1d", x, y), 10, 455, 110, "left") drawText(string.format("X: %.1d; Y: %.1d", x, y), 10, 455, 110, "left")
-- love.graphics.setColor(1, 1, 1, 1)
-- love.graphics.setLineWidth(2)
-- love.graphics.rectangle("line", 0, 0, 640, 480)
love.graphics.pop() love.graphics.pop()
end end
@@ -156,8 +145,10 @@ function love.keypressed(key, scancode)
if scancode == "f4" then if scancode == "f4" then
SETTINGS["fullscreen"] = not SETTINGS["fullscreen"] SETTINGS["fullscreen"] = not SETTINGS["fullscreen"]
love.window.setFullscreen(SETTINGS["fullscreen"]) love.window.setFullscreen(SETTINGS["fullscreen"])
love.resize(love.graphics.getDimensions())
elseif scancode == "f2" and SCENE.title ~= "Input Config" and SCENE.title ~= "Game" then elseif scancode == "f2" and SCENE.title ~= "Input Config" and SCENE.title ~= "Game" then
SCENE = InputConfigScene() SCENE = InputConfigScene()
elseif scancode == "f3" then SCENE = DataManagementScene()
elseif scancode == "f12" then LLDEBUGGER.requestBreak() elseif scancode == "f12" then LLDEBUGGER.requestBreak()
-- elseif scancode == "f11" then SETTINGS.firstTime = true -- elseif scancode == "f11" then SETTINGS.firstTime = true
-- function keys are reserved -- function keys are reserved
@@ -386,30 +377,24 @@ function love.errorhandler(msg)
print("\n"..table.concat(err,"\n",1,c-2)) print("\n"..table.concat(err,"\n",1,c-2))
local tracebacks = table.concat(err,"\n", 4) local tracebacks = table.concat(err,"\n", 4)
if drawText == nil then if drawText == nil or FONT_tromi == nil then
pcall(function() love.audio.stop()
FONT_tromi = love.graphics.newFont('res/fonts/monofonto rg.otf', 20) love.graphics.origin()
require "funcs" love.graphics.setFont(love.graphics.newFont(20))
end) return function()
if drawText == nil then love.event.pump()
love.window.setMode(640, 480, {resizable = true}) for e, a, b, c in love.event.poll() do
return function() -- If "funcs" failed to load, we can only return a more simple version of error screen if (
love.event.pump() e == "quit" or
for e, a, b, c in love.event.poll() do e == "mousepressed"
if e == "quit" then return 1 end ) then return 1 end
end
love.graphics.origin()
love.graphics.clear()
love.graphics.setColor(1, 1, 1)
love.graphics.setFont(FONT_tromi)
love.graphics.printf(
err[1]:sub(7).."\nTraceback:\n"..tracebacks,
30, 30, love.graphics.getWidth() - 10, "left"
)
love.graphics.present()
if love.timer then love.timer.sleep(0.1) end
end end
love.graphics.clear()
love.graphics.print(err[1]:sub(7).."\nTraceback:\n"..tracebacks)
love.graphics.present()
love.timer.sleep(0.001)
end end
end end
@@ -535,6 +520,9 @@ local main_bg_draw_frame = 0
local main_bg_last_color = nil local main_bg_last_color = nil
function MainBackground() function MainBackground()
love.graphics.setColor(BACKGROUND_COLOR)
love.graphics.rectangle("fill", 0, 0, 640, 480)
if SETTINGS["music"] and not SOUNDS["bgm_title"]:isPlaying() then if SETTINGS["music"] and not SOUNDS["bgm_title"]:isPlaying() then
SOUNDS["bgm_title"]:setVolume(0.3) SOUNDS["bgm_title"]:setVolume(0.3)
SOUNDS["bgm_title"]:play() SOUNDS["bgm_title"]:play()

85
scene.lua Normal file
View File

@@ -0,0 +1,85 @@
local Object = require "libs.classic"
---@class SCENE
---@field title string
---@field extend function # Get a empty SCENE table
---
---@field new function
---@field update function
---@field render function
---@field onInputMove function
---@field onInputPress function
---@field onInputRelease function
SCENE = Object:extend()
function SCENE:new() end
function SCENE:update() end
function SCENE:render() end
-- You can use the class SCENE_onInput to show suggestions for `e` table
---@class SCENE_onInput
---@field type? "key"|"joystick"|"virtual"|"touch"|"mouse"|"wheel"
---
---@field input? # Action triggered<br>Only visible via keyboard and gamepad
---| "menu_decide"
---| "menu_back"
---| "left"
---| "right"
---| "up"
---| "down"
---| "rotate_left"
---| "rotate_right"
---| "rotate_left2"
---| "rotate_right2"
---
---@field key? love.KeyConstant Key pressed? Only visible via keyboard and gamepad
---@field scancode? love.Scancode Key pressed but on the US layout? Only visible via keyboard and gamepad
---
---@field x? number Only visible via touch and mouse
---@field y? number Only visible via touch and mouse
---@field dx? number # Delta X<br> Only visible via touch, mouse and wheel
---@field dy? number # Delta Y<br> Only visible via touch, mouse and wheel
---@field id? lightuserdata # Only visible via touch
---@field presses? number # Only visible via mouse
-- e in 4 below functions will contain different things based on it's type:
-- key - input, key, scancode
-- joystick - input, button, name
-- virtual - input
-- touch - x, y, dx, dy, id
-- mouse - x, y, dx, dy, presses
-- wheel - dx, dy
function SCENE:onInputMove(e) end
function SCENE:onInputPress(e) end
function SCENE:onInputRelease(e) end
LoadingScene = require "scene.loading"
GameScene = require "scene.game"
TrainingScene = require "scene.training"
NameEntryScene = require "scene.name_entry"
FullscreenScene = require "scene.fullscreen"
KeyConfigScene = require "scene.key_config"
StickConfigScene = require "scene.stick_config"
-- MusicToggleScene = require "scene.music_toggle"
-- LinesToggleScene = require "scene.lines_toggle"
TouchConfigScene = require "scene.touch_config"
TouchConfigPreviewScene = require "scene.touch_config_preview"
InputConfigScene = require "scene.input_config"
SettingsScene = require "scene.settings"
EraseHighScoresScene = require "scene.data.erase_high_scores"
ResetAllScene = require "scene.data.reset_all"
DataManagementScene = require "scene.data_management"
ReplaySelectScene = require "scene.replay"
ReplayTestScene = require"scene.replay_test"
AboutScene = require "scene.about"
ExitScene = require "scene.exit"
TitleScene = require "scene.title2"

139
scene/about.lua Normal file
View File

@@ -0,0 +1,139 @@
---@class SCENE
local AboutScene = SCENE:extend()
AboutScene.title = "About"
local current_page = 1
local maxPage = 2
local buttonList
local function changePage(rel)
current_page = (current_page + maxPage + rel - 1) % maxPage + 1
end
buttonList = {
BUTTON.new{
text = function()
if current_page < maxPage then
return ("%s Next (%s/%s)"):format(CHAR.key.right, current_page, maxPage)
else
return ("%s Back (%s/%s)"):format(CHAR.icon.toLeft, current_page, maxPage)
end
end,
textOrientation = "center",
x = 185, y = 440, w = 130, h = 30,
codeWhenReleased = function()
changePage(1)
BUTTON.reset(buttonList)
end
},
BUTTON.new{
text = CHAR.icon.home.." Title",
textOrientation = "center",
x = 325, y = 440, w = 130, h = 30,
codeWhenReleased = function() SCENE = TitleScene() end
}
}
function AboutScene:new()
current_page = 1
BUTTON.reset(buttonList)
end
function AboutScene:render()
MainBackground()
love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 0, 0, 640, 480)
BUTTON.draw(buttonList)
if current_page == 1 then
-- Design & programming - Mycophobia
drawText ("Design & programming" , 20, 10, 180, "center")
drawBigText("mycophobia" , 20, 25, 180, "center")
drawText ("https://mycophobia.org" , 20, 60, 180, "center")
-- Cambridge - Based on
drawText ("Based on" , 230, 10, 180, "center")
drawBigText("Cambridge" , 230, 25, 180, "center")
drawText ("Cambridge contributors\nhttps://t-sp.in/cambridge", 230, 60, 180, "center")
-- Port to TV & mobile - SweetSea
drawText ("Port to TV & mobile" , 450, 10, 180, "center")
drawBigText("SweetSea" , 450, 25, 180, "center")
drawText ("https://github.com/\nSweetSea-ButImNotSweet" , 450, 60, 180, "center")
-- Design & programming - Mycophobia
drawText ("RNG Consultant" , 20, 120, 180, "center")
drawBigText("colour_thief" , 20, 135, 180, "center")
-- Design & programming - Mycophobia
drawText ("Launcher for Mac" , 450, 120, 180, "center")
drawBigText("nightmareci" , 450, 135, 180, "center")
drawText ("http://iblock.red" , 450, 170, 180, "center")
local other_text_y = 200
--- Other credit text, small text's y on the right = big text's y + 13, on the left: big text's y + 30
-- Music - Jerry Martin
drawBigText("Music", 0, other_text_y, 250, "right")
drawText("all rights reserved", 0, other_text_y + 30, 250, "right")
drawText("Jerry Martin - https://jerrymartinmusic.com \nJuraj Stanik - https://www.jurajstanik.com", 300, other_text_y + 13, 400, "left")
-- Background - PixaBays
drawBigText("Background", 0, other_text_y + 60, 250, "right")
drawText("by people on PixaBays", 0, other_text_y + 90, 250, "right")
drawText(
"Joe_hackney VisualSkyFX\n"..
"yokim Favorisxp Any_Ann",
300, other_text_y + 73, 400, "left"
)
-- Special thanks
drawBigText("Testing and/or\nCool Features", 0, other_text_y + 120, 250, "right")
drawText(
"netdoll esquatre Kirby703\n"..
"switchpalacecorner lindtobias\n"..
"zaphod77 Arch Nemesis dtet_enjoyer\n"..
"woozy Zircean AgentBasey Eden GT",
300, other_text_y + 133, 400, "left"
)
elseif current_page == 2 then
-- Main font
drawBigText("Font", 0, 10, 250, "right")
drawText("all used font are licensed under\nthe SIL Open Font License, v.1.1", 0, 40, 250, "right")
drawText(
"Iosevka - Renzhi Li (aka. Bellve Invis),\n(for game's UI interface and\n on-screen buttons' texture)\n\n"..
"Exo 2 for Techmino - C₂₉H₂₅N₃O₅, (for game's UI)\n\n"..
"Cascadia Code - Microsoft, used with Iosevka\nfor on-screen buttons' texture",
300, 23, 340, "left"
)
-- VCTRL
drawBigText("On-screen buttons\nimplementation", 0, 180, 250, "right")
drawText("UI's buttons: using simple-button module\nwritten by SweetSea\n\nIn-game on-screen control module is based on MrZ's VCTRL module in his games\nTexture made by SweetSea", 300, 193, 340, "left")
drawBigText("Special thanks", 25, 310, 460, "left")
drawText(
"The Absolute Plus - theabsolute.plus FYAD/Imp Zone Collective\
MrZ - https://github.com/MrZ626 C₂₉H₂₅N₃O₅ - https://github.com/C29H25N3O5\n\
AND ALL VERSION 1 PLAYERS "
, 25, 350, 600, "left")
end
end
---@param e SCENE_onInput
function AboutScene:onInputPress(e)
local key = e.input or e.key
if e.type == "touch" or e.type == "mouse" then
BUTTON.press(buttonList, e.x, e.y, e.id)
elseif key == "left" or key == "up" then changePage(-1)
elseif key == "right" or key == "down" then changePage( 1)
elseif e.input == "menu_back" or e.scancode == "escape" then
SCENE = TitleScene()
end
end
function AboutScene:onInputRelease(e)
if e.type == "touch" or e.type == "mouse" then
BUTTON.release(buttonList, e.x, e.y, e.id)
end
end
function AboutScene:onInputMove(e)
if e.type == "mouse" then
BUTTON.checkHovering(buttonList, e.x, e.y)
end
end
return AboutScene

View File

@@ -0,0 +1,81 @@
local EraseHighScoresScene = SCENE:extend()
EraseHighScoresScene.title = "Erase all high scores"
local selection_title = {"No", "Yes"}
local selection_icon = {
CHAR.icon.crossMark,
CHAR.icon.checkMark,
}
local menu_tip = "Are you sure you want to erase all your high scores?\n\nCAUTION!\nThis action CANNOT BE UNDONE!"
local settings_func = {
function() return DataManagementScene() end,
function()
love.filesystem.remove(HIscoreFILE)
love.window.showMessageBox("Done", "All high scores are erased!")
return DataManagementScene()
end,
}
function EraseHighScoresScene:new()
self.settings_menu_state = 1
end
function EraseHighScoresScene:changeOption(rel)
local len = #selection_title
self.settings_menu_state = (self.settings_menu_state + len + rel - 1) % len + 1
end
function EraseHighScoresScene:render()
MainBackground()
love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 30, 60, 580, 85, 10, 10) -- Tromi
love.graphics.rectangle("fill", 30, 165, 580, 225, 10, 10) -- Menu
drawBigText(CHAR.icon.erase.." ERASE ALL HIGH SCORES?", 40, 85, 400, "left")
-- Selecting
love.graphics.setColor(0.4, 1, 1, 0.5)
love.graphics.rectangle("fill", 330, 135 + 40 * self.settings_menu_state, 270, 40)
-- Text
for i = 1, #selection_title do
drawText (selection_title[i], 365, 145 + 40 * i, 230, "left")
drawBigText(selection_icon [i], 335, 135 + 40 * i, 50, "left")
end
drawText(menu_tip, 45, 175, 610 - 15 - 330, "left")
end
---@param e SCENE_onInput
function EraseHighScoresScene:onInputPress(e)
if e.input == "menu_back" or e.scancode == "escape" then SCENE = TitleScene()
elseif e.input == "menu_decide" or e.key == "return" then
local s = settings_func[self.settings_menu_state]()
if s then SCENE = s end
elseif e.input == "down" or e.scancode == "down" then
self:changeOption(1)
elseif e.input == "up" or e.scancode == "up" then
self:changeOption(-1)
elseif e.type == "touch" or e.type == "mouse" then
local x, y = e.x, e.y
local testOption = function(sel)
if sel ~= self.settings_menu_state then
self.settings_menu_state = sel
else
self:onInputPress{input = "menu_decide"}
end
end
if (
x >= 330 and x <= 600 and
y >= 175 and y <= 375
) then
local sel = math.floor((y - 175) / 40) + 1
if sel <= #settings_func then
testOption(sel)
end
end
end
end
return EraseHighScoresScene

93
scene/data/reset_all.lua Normal file
View File

@@ -0,0 +1,93 @@
local ResetAllScene = SCENE:extend()
ResetAllScene.title = "Erase all high scores"
local selection_title = {"No", "Yes"}
local selection_icon = {
CHAR.icon.crossMark,
CHAR.icon.checkMark,
}
local menu_tip = "ARE YOU SURE you want to RESET ALL?\n\nCAUTION: This will reset everything: accounts, replays, high scores and your settings!\n\nGame will restart after resetting."
local function recursivelyDelete(item)
if love.filesystem.getInfo(item,"directory") then
for _, child in ipairs(love.filesystem.getDirectoryItems(item)) do
recursivelyDelete(item..'/'..child)
love.filesystem.remove(item..'/'..child)
end
elseif love.filesystem.getInfo(item) then
love.filesystem.remove(item)
end
love.filesystem.remove(item)
end
local settings_func = {
function() return DataManagementScene() end,
function()
recursivelyDelete('')
love.window.showMessageBox("Done", "All your data erased\nQuitting game... Game will restart now!")
love.event.quit()
end,
}
function ResetAllScene:new()
self.settings_menu_state = 1
end
function ResetAllScene:changeOption(rel)
local len = #selection_title
self.settings_menu_state = (self.settings_menu_state + len + rel - 1) % len + 1
end
function ResetAllScene:render()
MainBackground()
love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 30, 60, 580, 85, 10, 10) -- Tromi
love.graphics.rectangle("fill", 30, 165, 580, 225, 10, 10) -- Menu
drawBigText(CHAR.icon.erase.." RESET ALL?", 40, 85, 400, "left")
-- Selecting
love.graphics.setColor(0.4, 1, 1, 0.5)
love.graphics.rectangle("fill", 330, 135 + 40 * self.settings_menu_state, 270, 40)
-- Text
for i = 1, #selection_title do
drawText (selection_title[i], 365, 145 + 40 * i, 230, "left")
drawBigText(selection_icon [i], 335, 135 + 40 * i, 50, "left")
end
drawText(menu_tip, 45, 175, 610 - 15 - 330, "left")
end
---@param e SCENE_onInput
function ResetAllScene:onInputPress(e)
if e.input == "menu_back" or e.scancode == "escape" then SCENE = TitleScene()
elseif e.input == "menu_decide" or e.key == "return" then
local s = settings_func[self.settings_menu_state]()
if s then SCENE = s end
elseif e.input == "down" or e.scancode == "down" then
self:changeOption(1)
elseif e.input == "up" or e.scancode == "up" then
self:changeOption(-1)
elseif e.type == "touch" or e.type == "mouse" then
local x, y = e.x, e.y
local testOption = function(sel)
if sel ~= self.settings_menu_state then
self.settings_menu_state = sel
else
self:onInputPress{input = "menu_decide"}
end
end
if (
x >= 330 and x <= 600 and
y >= 175 and y <= 375
) then
local sel = math.floor((y - 175) / 40) + 1
if sel <= #settings_func then
testOption(sel)
end
end
end
end
return ResetAllScene

96
scene/data_management.lua Normal file
View File

@@ -0,0 +1,96 @@
local DataManagementScene = SCENE:extend()
DataManagementScene.title = "Data Management"
local data_title = {
"Open save folder",
"Manage accounts (WIP)",
"Erase all high scores",
"RESET ALL!",
"Back"
}
local data_icon = {
CHAR.key .windows,
CHAR.icon.menu,
CHAR.icon.erase,
CHAR.icon.erase,
CHAR.icon.home,
}
local data_explaination = {
"(Only for PC)\nOpen save folder in a new window",
"You can view and delete your accounts here.",
"Erase all your high scores\nThis will make high score table go back to default",
"Erase all accounts, replays and all high scores!",
"Back to main menu"
}
local NULL = function() end
local settings_func = {
function() love.system.openURL(love.filesystem.getSaveDirectory()) end,
NULL,
function() return EraseHighScoresScene() end,
function() return ResetAllScene() end,
function() return TitleScene() end,
}
function DataManagementScene:new()
self.data_menu_state = 1
end
function DataManagementScene:changeOption(rel)
local len = #data_title
self.data_menu_state = (self.data_menu_state + len + rel - 1) % len + 1
end
function DataManagementScene:render()
MainBackground()
love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 30, 60, 580, 85, 10, 10) -- Tromi
love.graphics.rectangle("fill", 30, 165, 580, 225, 10, 10) -- Menu
drawBigText(CHAR.icon.export.." DATA MANAGEMENT", 40, 85, 400, "left")
-- Selecting
love.graphics.setColor(0.4, 1, 1, 0.5)
love.graphics.rectangle("fill", 40, 135 + 40 * self.data_menu_state, 270, 40)
-- Text
for i = 1, #data_title do
drawText (data_title[i], 85, 145 + 40 * i, 230, "left")
drawBigText(data_icon [i], 45, 135 + 40 * i, 50, "left")
end
drawText(data_explaination[self.data_menu_state], 330, 175, 610 - 15 - 330, "left")
end
---@param e SCENE_onInput
function DataManagementScene:onInputPress(e)
if e.input == "menu_back" or e.scancode == "escape" then SCENE = TitleScene()
elseif e.input == "menu_decide" or e.key == "return" then
local s = settings_func[self.data_menu_state]()
if s then SCENE = s end
elseif e.input == "down" or e.scancode == "down" then
self:changeOption(1)
elseif e.input == "up" or e.scancode == "up" then
self:changeOption(-1)
elseif e.type == "touch" or e.type == "mouse" then
local x, y = e.x, e.y
local testOption = function(sel)
if sel ~= self.data_menu_state then
self.data_menu_state = sel
else
self:onInputPress{input = "menu_decide"}
end
end
if (
x >= 40 and x <= 310 and
y >= 175 and y <= 375
) then
local sel = math.floor((y - 175) / 40) + 1
if sel <= #settings_func then
testOption(sel)
end
end
end
end
return DataManagementScene

View File

@@ -8,14 +8,5 @@ function ExitScene:update()
love.event.quit() love.event.quit()
end end
function ExitScene:render()
end
function ExitScene:changeOption(rel)
end
function ExitScene:onInputPress(e)
end
return ExitScene return ExitScene

View File

@@ -3,7 +3,6 @@ GameScene.title = "Game"
local tas = false local tas = false
-- 70 295
local buttonList = { local buttonList = {
BUTTON.new{ BUTTON.new{
text = "Rotate Left\n Pause/Frame Step", text = "Rotate Left\n Pause/Frame Step",
@@ -45,17 +44,17 @@ local buttonList = {
local menuKey -- MENU key used to go main menu XD local menuKey -- MENU key used to go main menu XD
function GameScene:new(player_name, replay_file, replay_grade) function GameScene:new(player_name, replay_file, replay_grade)
VCTRL[9].show = false
menuKey = BUTTON.new{ menuKey = BUTTON.new{
text = "MENU", text = CHAR.icon.menu.." MENU",
x = 265, y = 0, w = 60, h = 25, x = 10, y = 10, w = 70, h = 30,
codeWhenReleased = function() codeWhenReleased = function()
if self.game.input_playback or self.game.game_over or self.game.completed then if self.game.input_playback or self.game.game_over or self.game.completed then
SCENE = TitleScene() SCENE = TitleScene()
end end
end end
} }
VCTRL[9].show = false
BUTTON.reset(buttonList)
game_mode = require 'game.gamemode' game_mode = require 'game.gamemode'
if PENTO_MODE then if PENTO_MODE then

View File

@@ -48,16 +48,16 @@ end
function KeyConfigScene:render() function KeyConfigScene:render()
MainBackground() MainBackground()
for i, input in ipairs(configurable_inputs) do for i, input in ipairs(configurable_inputs) do
drawText(input_names[input], 40, 50 + i * 20, 200, "left") drawText(input_names[input], 40, 60 + i * 20, 200, "left")
if self.set_inputs[input] then if self.set_inputs[input] then
drawText(self.set_inputs[input], 240, 50 + i * 20, 300, "left") drawText(self.set_inputs[input], 240, 60 + i * 20, 300, "left")
end end
end end
if self.input_state > #configurable_inputs then if self.input_state > #configurable_inputs then
drawText("Press Enter/Confirm Selection to confirm, delete/backspace to retry" .. (SETTINGS.input and ", escape/Go Back to cancel" or ""),0,0,1000) drawText("Press Enter/Confirm Selection to confirm, delete/backspace to retry" .. (SETTINGS.input.keys and ", esc/Go Back to cancel" or ""),0,0,1000)
else else
drawText("Press key input for " .. input_names[configurable_inputs[self.input_state]] .. ", tab to skip, escape to cancel",0,0,1000) drawText("Press key input for " .. input_names[configurable_inputs[self.input_state]] .. ", escape to cancel\nPress tab on keyboard, or any key from other inputs, to skip",0,0,1000)
drawText("Press any key from other input than keyboard will also skip.\nFunction keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20,1000) drawText("Function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 35,1000)
end end
end end

View File

@@ -1,21 +1,9 @@
local LinesToggleScene = SCENE:extend() local LinesToggleScene = SCENE:extend()
LinesToggleScene.title = "Show lines during game:" LinesToggleScene.title = "Show lines during game:"
function LinesToggleScene:new()
end
function LinesToggleScene:update() function LinesToggleScene:update()
SETTINGS["lines"] = not SETTINGS["lines"] SETTINGS["lines"] = not SETTINGS["lines"]
SCENE = TitleScene() SCENE = TitleScene()
end end
function LinesToggleScene:render()
end
function LinesToggleScene:changeOption(rel)
end
function LinesToggleScene:onInputPress(e)
end
return LinesToggleScene return LinesToggleScene

10
scene/loading.lua Normal file
View File

@@ -0,0 +1,10 @@
local LoadingScene = SCENE:extend()
function LoadingScene.update()
SCENE = SETTINGS.firstTime and InputConfigScene(true) or TitleScene()
end
function LoadingScene.render()
love.graphics.draw(LOADING_IMAGE_FILE,0,0,0,0.5)
end
return LoadingScene

View File

@@ -1,21 +1,9 @@
local MusicToggleScene = SCENE:extend() local MusicToggleScene = SCENE:extend()
MusicToggleScene.title = "Play music during game:" MusicToggleScene.title = "Play music during game:"
function MusicToggleScene:new()
end
function MusicToggleScene:update() function MusicToggleScene:update()
SETTINGS["music"] = not SETTINGS["music"] SETTINGS["music"] = not SETTINGS["music"]
SCENE = TitleScene() SCENE = TitleScene()
end end
function MusicToggleScene:render()
end
function MusicToggleScene:changeOption(rel)
end
function MusicToggleScene:onInputPress(e)
end
return MusicToggleScene return MusicToggleScene

View File

@@ -3,33 +3,37 @@ NameEntryScene.title = "Game Start"
local buttonList = { local buttonList = {
BUTTON.new{ BUTTON.new{
text = "\nCHAR", font = FONT_big, text = "\nCHAR", font = FONT_big,
x = 25, y = 120, w = 80, h = 80, x = 25, y = 120, w = 80, h = 80,
codeWhenPressed = function() SCENE:onInputPress {input = "left"} end, codeWhenPressed = function() SCENE:onInputPress {input = "left"} end,
codeWhenReleased = function() SCENE:onInputRelease{input = "left"} end, codeWhenReleased = function() SCENE:onInputRelease{input = "left"} end,
}, },
BUTTON.new{ BUTTON.new{
text = "\nCHAR", font = FONT_big, text = "\nCHAR", font = FONT_big,
x = 115, y = 120, w = 80, h = 80, x = 115, y = 120, w = 80, h = 80,
codeWhenPressed = function() SCENE:onInputPress {input = "right"} end, codeWhenPressed = function() SCENE:onInputPress {input = "right"} end,
codeWhenReleased = function() SCENE:onInputRelease{input = "right"} end, codeWhenReleased = function() SCENE:onInputRelease{input = "right"} end,
}, },
BUTTON.new{ BUTTON.new{
text = "\nESC", font = FONT_big, text = "\nESC", font = FONT_big,
x = 25, y = 210, w = 80, h = 80, x = 25, y = 210, w = 80, h = 80,
codeWhenPressed = function() SCENE:onInputPress {input = "menu_back"} end, codeWhenPressed = function() SCENE:onInputPress {input = "menu_back"} end,
codeWhenReleased = function() SCENE:onInputRelease{input = "menu_back"} end, codeWhenReleased = function() SCENE:onInputRelease{input = "menu_back"} end,
}, },
BUTTON.new{ BUTTON.new{
text = "\nENTER", font = FONT_big, text = "\nENTER", font = FONT_big,
x = 115, y = 210, w = 80, h = 80, x = 115, y = 210, w = 80, h = 80,
codeWhenPressed = function() SCENE:onInputPress {input = "menu_decide"} end, codeWhenPressed = function() SCENE:onInputPress {input = "menu_decide"} end,
codeWhenReleased = function() SCENE:onInputRelease{input = "menu_decide"} end, codeWhenReleased = function() SCENE:onInputRelease{input = "menu_decide"} end,
}, },
BUTTON.new{
text = CHAR.key.keyboard.." Open OSK", font = FONT_big,
x = 25, y = 300, w = 170, h = 40,
codeWhenReleased = function() love.keyboard.setTextInput(true, 215, 175, 160, 160) end
}
} }
local Grid = require 'game.grid' local Grid = require 'game.grid'
local bitser = require 'libs.bitser'
function NameEntryScene:new() function NameEntryScene:new()
VCTRL.toggle(false) VCTRL.toggle(false)
@@ -61,7 +65,6 @@ function NameEntryScene:new()
self.hi_scores = {"TRO",0,"MIT",0,"ROM",0,"ITR",0,"OMI",0} self.hi_scores = {"TRO",0,"MIT",0,"ROM",0,"ITR",0,"OMI",0}
end end
end end
function NameEntryScene:drawGradeList(left, top) function NameEntryScene:drawGradeList(left, top)
love.graphics.setColor(0,0,0,0.5) love.graphics.setColor(0,0,0,0.5)
love.graphics.rectangle("fill", left+3, top+3, 200, 240, 10, 10) love.graphics.rectangle("fill", left+3, top+3, 200, 240, 10, 10)
@@ -97,10 +100,8 @@ function NameEntryScene:render()
love.graphics.setColor(0.05,0.05,0.05,1) love.graphics.setColor(0.05,0.05,0.05,1)
love.graphics.rectangle("fill", 397, 292, 130, 130, 10, 10) love.graphics.rectangle("fill", 397, 292, 130, 130, 10, 10)
drawText("Best scores:", 410, 297, 1000, "left") drawText("Best scores:", 410, 297, 1000, "left")
i = 2 for i = 2, 10, 2 do
while i <= 10 do
drawText(self.hi_scores[i-1]..' - '..self.hi_scores[i], 410, 297+(i*10), 1000, "left") drawText(self.hi_scores[i-1]..' - '..self.hi_scores[i], 410, 297+(i*10), 1000, "left")
i = i + 2
end end
if self.entry_pos == 4 then if self.entry_pos == 4 then
drawText('Press confirm\nto play', 255, 290, 1000) drawText('Press confirm\nto play', 255, 290, 1000)
@@ -138,28 +139,43 @@ function NameEntryScene:onInputMove(e)
end end
end end
function NameEntryScene:getPlayInfo(player_name)
if love.filesystem.getInfo((SAVE_DIR..player_name.."_grade_history.sav")) then
grade_history = FILE.read(SAVE_DIR..player_name.."_grade_history.sav")
self.grade = grade_history[1]
self.wins = grade_history[2]
self.plays = grade_history[4]
else
self.grade, self.win, self.plays = 0, 0, 0
end
return self.grade, self.win, self.plays
end
function NameEntryScene:onInputPress(e) function NameEntryScene:onInputPress(e)
local name = string.lower(self.name_entry[1]..self.name_entry[2]..self.name_entry[3])
if e.type == "mouse" or e.type == "touch" then if e.type == "mouse" or e.type == "touch" then
BUTTON.press(buttonList, e.x, e.y, e.id) BUTTON.press(buttonList, e.x, e.y, e.id)
elseif e.key and #e.key == 1 then
local pos = string.find("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.", string.upper(e.key), 1, true)
if pos then
if self.entry_pos <= 3 then
self.char_pos = pos
self.name_entry[self.entry_pos] = string.upper(e.key)
self.name_entry[self.entry_pos + 1] = string.upper(e.key)
end
if self.entry_pos == 3 then self:getPlayInfo(name) end
self.entry_pos = math.min(self.entry_pos + 1, 4)
end
elseif e.input == "menu_decide" or e.input == "rotate_left" or e.scancode == "return" then elseif e.input == "menu_decide" or e.input == "rotate_left" or e.scancode == "return" then
if self.entry_pos == 4 then if self.entry_pos == 4 then
BUTTON.release(buttonList, e.x, e.y, e.id) BUTTON.release(buttonList, e.x, e.y, e.id)
SETTINGS['last_entry'] = name:upper() SETTINGS['last_entry'] = name:upper()
SCENE = GameScene(name:lower()) SCENE = GameScene(name:lower())
else else
if self.entry_pos == 3 then if self.entry_pos == 3 then self:getPlayInfo(name)
name = string.lower(self.name_entry[1]..self.name_entry[2]..self.name_entry[3]) else
if love.filesystem.getInfo((SAVE_DIR..name.."_grade_history.sav")) then self.name_entry[self.entry_pos ] = self.chars:sub(self.char_pos, self.char_pos)
grade_history = FILE.read(SAVE_DIR..name.."_grade_history.sav") self.name_entry[self.entry_pos+1] = self.chars:sub(self.char_pos, self.char_pos)
self.grade = grade_history[1] end
self.wins = grade_history[2]
self.plays = grade_history[4]
end
end
if self.entry_pos < 3 then
self.name_entry[self.entry_pos] = self.chars:sub(self.char_pos, self.char_pos)
self.name_entry[self.entry_pos+1] = self.chars:sub(self.char_pos, self.char_pos)
end
self.entry_pos = self.entry_pos + 1 self.entry_pos = self.entry_pos + 1
end end
elseif e.input == "left" or e.scancode == "left" then elseif e.input == "left" or e.scancode == "left" then

View File

@@ -160,10 +160,10 @@ function ReplaySelectScene:onInputPress(e)
end end
elseif e.input == "rotate_left" then -- Export elseif e.input == "rotate_left" then -- Export
local plain_replay_data = love.data.encode("string", "base64", love.filesystem.read(REPLAY_DIR..selected_replay)) local plain_replay_data = love.data.encode("string", "base64", love.filesystem.read(REPLAY_DIR..selected_replay))
love.system.setClipboardText(("BEGINNING_OF_TROMI_REPLAY|%s|%s|END_OF_TROMI_REPLAY"):format(selected_replay, plain_replay_data)) love.system.setClipboardText(("BEGIN_OF_TROMI_REPLAY|%s|%s|END_OF_TROMI_REPLAY"):format(selected_replay, plain_replay_data))
elseif e.input == "rotate_right" then -- Import elseif e.input == "rotate_right" then -- Import
local input_data = love.system.getClipboardText() local input_data = love.system.getClipboardText()
if input_data:find("BEGINNING_OF_TROMI_REPLAY|", 1, true) == 1 and input_data:find("|END_OF_TROMI_REPLAY", 1, true) == #input_data - 19 then if input_data:find("BEGIN_OF_TROMI_REPLAY|", 1, true) == 1 and input_data:find("|END_OF_TROMI_REPLAY", 1, true) == #input_data - 19 then
local data_part = input_data:sub(27, #input_data - 20) local data_part = input_data:sub(27, #input_data - 20)
local separator_pos = data_part:find("|", 1, true) local separator_pos = data_part:find("|", 1, true)
local replay_name = data_part:sub(1, separator_pos - 1) local replay_name = data_part:sub(1, separator_pos - 1)
@@ -171,8 +171,10 @@ function ReplaySelectScene:onInputPress(e)
local replay_data = love.data.decode("string", "base64", data_part:sub(separator_pos + 1)) local replay_data = love.data.decode("string", "base64", data_part:sub(separator_pos + 1))
love.filesystem.write(replay_path, replay_data) love.filesystem.write(replay_path, replay_data)
BUTTON.reset(buttonList)
SCENE = ReplayTestScene(replay_name) SCENE = ReplayTestScene(replay_name)
else else
BUTTON.reset(buttonList)
SCENE = ReplayTestScene() SCENE = ReplayTestScene()
end end
elseif e.input == "up" or e.scancode == "up" then elseif e.input == "up" or e.scancode == "up" then

View File

@@ -3,9 +3,12 @@ local ReplayTestScene = SCENE:extend()
local GAME local GAME
local error_message local error_message
local valid_data local valid_data
local prev_scene
function ReplayTestScene:new(input_file) function ReplayTestScene:new(input_file)
prev_scene = SCENE
if not input_file then if not input_file then
valid_data = false valid_data = false
return return
@@ -27,7 +30,10 @@ function ReplayTestScene:new(input_file)
end end
function ReplayTestScene:render() function ReplayTestScene:render()
MainBackground() prev_scene:render()
love.graphics.setColor(0, 0, 0, 0.8)
love.graphics.rectangle("fill", 0, 0, 640, 480)
if valid_data then if valid_data then
if error_message then if error_message then
drawText("Replay test failed! Data corrupted!", 80, 40, 1000) drawText("Replay test failed! Data corrupted!", 80, 40, 1000)
@@ -39,7 +45,7 @@ function ReplayTestScene:render()
end end
else else
drawText("Replay test failed! Not Tromi's replay data", 80, 40, 1000) drawText("Replay test failed! Not Tromi's replay data", 80, 40, 1000)
drawText("Press any key to go back, and check your device's clipboard again!", 80, 100, 1000) drawText("Press any key to go back, and check your device's clipboard again!", 80, 70, 1000)
end end
end end

95
scene/settings.lua Normal file
View File

@@ -0,0 +1,95 @@
local SettingsScene = SCENE:extend()
SettingsScene.title = "Settings"
local settings_title = {
"Music",
"Lines",
"Fullscreen (F4)",
"Input configuration (F2)",
"Back",
}
local settings_explaination = {
"Enable music?\nThis does not apply to sound effects.",
"Show level and lines counter?\nThis setting is ignored when replaying.",
"Enter or leave fullscreen\nYou can press F4 key at any screen to do this quick.",
"This is where you can re-configure your keybinds.\nYou can press F2 on the keyboard to open this quick\n\nTip for TV:\n\t88663366: enable TV mode.\n\t........: disable TV mode",
"Back to main menu"
}
local settings_func = {
function()
SETTINGS["music"] = not SETTINGS["music"]
love.audio.stop()
end,
function() SETTINGS["lines"] = not SETTINGS["lines"] end,
function() love.keypressed("f4", "f4") end,
InputConfigScene,
function() return TitleScene() end,
}
function SettingsScene:new()
self.settings_menu_state = 1
end
function SettingsScene:changeOption(rel)
local len = #settings_title
self.settings_menu_state = (self.settings_menu_state + len + rel - 1) % len + 1
end
function SettingsScene:render()
MainBackground()
love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 30, 60, 580, 85, 10, 10) -- Tromi
love.graphics.rectangle("fill", 30, 165, 580, 225, 10, 10) -- Menu
drawBigText(CHAR.icon.settings.." SETTINGS", 40, 85, 200, "left")
-- Selecting
love.graphics.setColor(0.4, 1, 1, 0.5)
love.graphics.rectangle("fill", 40, 135 + 40 * self.settings_menu_state, 270, 40)
-- Text
for i = 1, #settings_title do
drawText(settings_title[i], 45, 145 + 40 * i, 230, "left")
end
drawBigText(SETTINGS["music"] and CHAR.icon.checkMark or CHAR.icon.crossMark, 260, 175, 50, "center")
drawBigText(SETTINGS["lines"] and CHAR.icon.checkMark or CHAR.icon.crossMark, 260, 215, 50, "center")
drawBigText(love.window.getFullscreen() and CHAR.icon.checkMark or CHAR.icon.crossMark, 260, 255, 50, "center")
drawBigText(CHAR.key.keyboard , 260, 295, 50, "center")
drawBigText(CHAR.icon.home , 260, 335, 50, "center")
drawText(settings_explaination[self.settings_menu_state], 330, 175, 610 - 15 - 330, "left")
end
---@param e SCENE_onInput
function SettingsScene:onInputPress(e)
if e.input == "menu_back" or e.scancode == "escape" then SCENE = TitleScene()
elseif e.input == "menu_decide" or e.key == "return" then
local s = settings_func[self.settings_menu_state]()
if s then SCENE = s end
elseif e.input == "down" or e.scancode == "down" then
self:changeOption(1)
elseif e.input == "up" or e.scancode == "up" then
self:changeOption(-1)
elseif e.type == "touch" or e.type == "mouse" then
local x, y = e.x, e.y
local testOption = function(sel)
if sel ~= self.settings_menu_state then
self.settings_menu_state = sel
else
self:onInputPress{input = "menu_decide"}
end
end
if (
x >= 40 and x <= 310 and
y >= 175 and y <= 375
) then
local sel = math.floor((y - 175) / 40) + 1
if sel <= #settings_func then
testOption(sel)
end
end
end
end
return SettingsScene

View File

@@ -48,13 +48,13 @@ end
function StickConfigScene:render() function StickConfigScene:render()
MainBackground() MainBackground()
for i, input in ipairs(configurable_inputs) do for i, input in ipairs(configurable_inputs) do
drawText(input_names[input], 40, 50 + i * 20, 200, "left") drawText(input_names[input], 40, 60 + i * 20, 200, "left")
if self.set_inputs[input] then if self.set_inputs[input] then
drawText(self.set_inputs[input], 240, 50 + i * 20, 300, "left") drawText(self.set_inputs[input], 240, 60 + i * 20, 300, "left")
end end
end end
if self.input_state > #configurable_inputs then if self.input_state > #configurable_inputs then
drawText("Press enter/Confirm Selection to confirm, delete/backspace to retry" .. (SETTINGS.input and ", escape/Go Back to cancel" or ""), 0, 0, 1000) drawText("Press enter/Confirm Selection to confirm, delete/backspace to retry" .. (SETTINGS.input.joysticks and ", esc/Go Back to cancel" or ""), 0, 0, 1000)
else else
drawText("Press joystick input for " .. input_names[configurable_inputs[self.input_state]] .. ", tab to skip, escape to cancel", 0, 0, 1000) drawText("Press joystick input for " .. input_names[configurable_inputs[self.input_state]] .. ", tab to skip, escape to cancel", 0, 0, 1000)
end end

View File

@@ -15,8 +15,6 @@ local main_menu_screens = {
} }
function TitleScene:new() function TitleScene:new()
VCTRL.clearAll() -- Reset the RESTART button state
VCTRL.new(SETTINGS.input.virtual)
if SOUNDS['bgm_firsthalf']:isPlaying() or SOUNDS['bgm_secondhalf']:isPlaying() or not SETTINGS["music"] then if SOUNDS['bgm_firsthalf']:isPlaying() or SOUNDS['bgm_secondhalf']:isPlaying() or not SETTINGS["music"] then
love.audio.stop() love.audio.stop()
end end
@@ -116,7 +114,6 @@ function TitleScene:onInputPress(e)
if self.main_menu_state ~= selecting then if self.main_menu_state ~= selecting then
self.main_menu_state = selecting self.main_menu_state = selecting
else else
VCTRL.toggle(true)
SCENE = main_menu_screens[selecting]() SCENE = main_menu_screens[selecting]()
end end
end end

164
scene/title2.lua Normal file
View File

@@ -0,0 +1,164 @@
---@class SCENE
local Title2Scene = SCENE:extend()
Title2Scene.title = "Title"
local input_code = {}
local main_menu_title = {
"New game" ,
"Replay" ,
"Data management" ,
"Mobile port repository",
"About" ,
"Max gravity Training",
"Leaderboard" ,
"Settings" ,
"Official homepage" ,
"Exit game" ,
}
local half_pos = math.roundUnit(#main_menu_title / 2)
local main_menu_scenes = {
NameEntryScene,
ReplaySelectScene,
DataManagementScene,
function() love.system.openURL("https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile") end,
AboutScene,
TrainingScene,
function() love.system.openURL("https://mycophobia.org/forums/viewtopic.php?t=29") end,
SettingsScene,
function() love.system.openURL("https://mycophobia.org/tromi") end,
ExitScene
}
local main_menu_icons = {
CHAR.icon.play,
CHAR.icon.rewind,
CHAR.icon.export,
CHAR.icon.home,
CHAR.icon.info,
CHAR.icon.toDown,
CHAR.icon.globe,
CHAR.icon.settings,
CHAR.icon.home,
CHAR.icon.back,
}
function Title2Scene:new()
if SOUNDS['bgm_firsthalf']:isPlaying() or SOUNDS['bgm_secondhalf']:isPlaying() or not SETTINGS["music"] then
love.audio.stop()
end
self.main_menu_state = 1
PENTO_MODE = false
input_code = {0,0,0,0,0,0,0,0}
end
function Title2Scene:changeOption(rel)
local len = #main_menu_title
self.main_menu_state = (self.main_menu_state + len + rel - 1) % len + 1
end
function Title2Scene:render()
MainBackground()
love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 30, 60, 580, 85, 10, 10) -- Tromi
love.graphics.rectangle("fill", 30, 165, 580, 225, 10, 10) -- Menu
drawBigText("Tromi", 40, 65, 100, "left")
drawText("Mobile 1.0 - PC 2.3", 150, 78, 200, "left")
drawText("https://mycophobia.org\nhttps://github.com/SweetSea-ButImNotSweet/", 40, 100, 300, "left")
if PENTO_MODE then
drawBigText("PENTO MODE", 400, 85, 200, "right")
end
love.graphics.setColor(1, 1, 1, 0.5)
love.graphics.setLineWidth(1)
love.graphics.line(320, 175, 320, 375)
-- Selecting
love.graphics.setColor(0.4, 1, 1, 0.5)
if self.main_menu_state > half_pos then
love.graphics.rectangle("fill", 330, 135 + 40 * (self.main_menu_state - half_pos), 270, 40)
else
love.graphics.rectangle("fill", 40, 135 + 40 * self.main_menu_state, 270, 40)
end
-- Text
for i = 1, half_pos do
drawText(main_menu_title[i] , 45, 145 + 40 * i, 230, "right")
drawText(main_menu_icons[i] or '', 285, 145 + 40 * i, 20, "center")
end
for i = half_pos + 1, #main_menu_title do
drawText(main_menu_title[i] , 365, 145 + 40 * (i - half_pos), 230, "left")
drawText(main_menu_icons[i] or '', 335, 145 + 40 * (i - half_pos), 20, "center")
end
end
local function checkCode(c)
if not PENTO_MODE then
table.insert(input_code, c)
if #input_code > 8 then
table.remove(input_code, 1)
end
local code_string = table.concat(input_code, ',')
if (
code_string == "-1,-1,-1,-1,1,1,1,1" or
code_string == "2,2,2,2,2,2,2,2"
) then
PENTO_MODE = true
end
end
end
---@param e SCENE_onInput
function Title2Scene:onInputPress(e)
if e.input == "menu_back" or e.scancode == "escape" then SCENE = TitleScene()
elseif e.input == "menu_decide" or e.key == "return" then
local s = main_menu_scenes[self.main_menu_state]()
if s then SCENE = s end
elseif e.input == "down" or e.scancode == "down" then
self:changeOption(1)
elseif e.input == "up" or e.scancode == "up" then
self:changeOption(-1)
elseif e.input == "left" or e.scancode == "left" then
self:changeOption(-half_pos)
checkCode(-1)
elseif e.input == "right" or e.scancode == "right" then
self:changeOption(half_pos)
checkCode(1)
elseif e.type == "touch" or e.type == "mouse" then
local x, y = e.x, e.y
local testOption = function(sel)
if sel ~= self.main_menu_state then
self.main_menu_state = sel
else
self:onInputPress{input = "menu_decide"}
end
end
-- 40 175 320 375 320 175 600 375
if y >= 175 and y <= 375 then
local sel = math.floor((y - 175) / 40) + 1
if x >= 40 and x <= 310 and sel <= half_pos then
testOption(sel)
elseif (
x >= 330 and x <= 600 and
sel >= 1 and sel + half_pos <= #main_menu_scenes
) then
testOption(sel + half_pos)
end
elseif (
x >= 460 and y >= 85 and
x <= 600 and y <= 125
) then
checkCode(2)
end
end
end
return Title2Scene

View File

@@ -5,13 +5,11 @@ TouchConfigScene.title = "Touchscreen config"
local Grid = require 'game.grid' local Grid = require 'game.grid'
local buttonList local buttonList
local sliderList local sliderList = {}
---@class VCTRL.data ---@class VCTRL.data
local focusingButton local focusingButton
---@type number ---@type number
local snapUnit = 1 local snapUnit = 1
---@type boolean
local hasChanged
---@type function ---@type function
local function exitSceneFunc(saved) local function exitSceneFunc(saved)
@@ -29,23 +27,23 @@ buttonList = {
showToggle = BUTTON.new{ showToggle = BUTTON.new{
text = function() text = function()
if focusingButton then if focusingButton then
return focusingButton.show and "[SHOW]\nHide" or "Show\n[HIDE]" return focusingButton.show and ">SHOW<\nhide" or "show\n>HIDE<"
else else
return "Show\nHide" return "show\nhide"
end end
end, end,
x = 275, y = 5, w = 50, h = 75, x = 400, y = 110, w = 60, h = 40,
codeWhenReleased = function () codeWhenReleased = function()
if focusingButton then if focusingButton then
focusingButton.show = not focusingButton.show focusingButton.show = not focusingButton.show
hasChanged = true VCTRL.hasChanged = true
end end
end, end,
update = function(self) self.textColor = focusingButton and {1, 1, 1} or {0.5, 0.5, 0.5} end update = function(self) self.textColor = focusingButton and {1, 1, 1} or {0.5, 0.5, 0.5} end
}, },
previewToggle = BUTTON.new{ previewToggle = BUTTON.new{
text = "Preview\nON", text = "Preview\nON",
x = 570, y = 35, w = 60, h = 40, x = 570, y = 60, w = 60, h = 40,
codeWhenReleased = function() codeWhenReleased = function()
VCTRL.release() VCTRL.release()
BUTTON.release(buttonList) BUTTON.release(buttonList)
@@ -54,7 +52,7 @@ buttonList = {
}, },
resetAll = BUTTON.new{ resetAll = BUTTON.new{
text = "RESET\nALL", text = "RESET\nALL",
x = 570, y = 80, w = 60, h = 40, x = 500, y = 110, w = 60, h = 40,
codeWhenReleased = function() codeWhenReleased = function()
local selection = love.window.showMessageBox( local selection = love.window.showMessageBox(
"Save config?", "Are you really sure about RESETTING ALL touchscreen configuration?", "Save config?", "Are you really sure about RESETTING ALL touchscreen configuration?",
@@ -63,7 +61,7 @@ buttonList = {
) )
if selection == 1 then if selection == 1 then
VCTRL.focus = nil; focusingButton = nil VCTRL.focus = nil; focusingButton = nil
hasChanged = false VCTRL.hasChanged = false
VCTRL.clearAll() VCTRL.clearAll()
VCTRL.new(SETTINGS.__default__.input.virtual) VCTRL.new(SETTINGS.__default__.input.virtual)
SETTINGS.input.virtual = SETTINGS.__default__.input.virtual SETTINGS.input.virtual = SETTINGS.__default__.input.virtual
@@ -72,9 +70,9 @@ buttonList = {
}, },
menuScreen = BUTTON.new{ menuScreen = BUTTON.new{
text = "MENU", text = "MENU",
x = 570, y = 5, w = 60, h = 25, x = 570, y = 10, w = 60, h = 40,
codeWhenReleased = function() codeWhenReleased = function()
if hasChanged or SETTINGS.firstTime then if VCTRL.hasChanged or SETTINGS.firstTime then
local selection = love.window.showMessageBox( local selection = love.window.showMessageBox(
"Save config?", "Do you want to save your changes before exiting?", "Save config?", "Do you want to save your changes before exiting?",
{"Save", "Discard", "Keep editing", escapebutton = 3, enterbutton = 1}, {"Save", "Discard", "Keep editing", escapebutton = 3, enterbutton = 1},
@@ -98,45 +96,59 @@ buttonList = {
end end
} }
} }
sliderList = {} sliderList.buttonSize = newSlider(
200, 30, 120, 0, 0, 120,
function(v)
if focusingButton then
v = math.roundUnit(v, 5)
if focusingButton.r ~= v then
focusingButton.r = v
VCTRL.hasChanged = true
end
sliderList.buttonSize.value = v / 120
end
end,
{width = 40}
)
sliderList.iconSize = newSlider(
480, 30, 120, 0, 0, 100,
function(v)
if focusingButton then
v = math.roundUnit(v, 5)
if focusingButton.iconSize ~= v then
focusingButton.iconSize = v
VCTRL.hasChanged = true
end
sliderList.iconSize.value = v / 100
end
end,
{width = 40}
)
sliderList.opacity = newSlider( sliderList.opacity = newSlider(
155, 20+5, 120, 100, 0, 100, 200, 80, 120, 0, 0, 1,
function() function()
local v local v
if focusingButton then if focusingButton then
v = math.roundUnit(sliderList.opacity.value, 0.01) v = math.roundUnit(sliderList.opacity.value, 0.01)
if focusingButton.alpha~=v then if focusingButton.alpha~=v then
focusingButton.alpha = v focusingButton.alpha = v
hasChanged = true VCTRL.hasChanged = true
end end
sliderList.opacity.value = v sliderList.opacity.value = v
end end
end, end,
{width = 30} {width = 40}
)
sliderList.size = newSlider(
155, 60+2.5, 120, 45, 0, 120,
function(v)
if focusingButton then
local v = math.roundUnit(v, 5)
if focusingButton.r ~= v then
focusingButton.r = v
hasChanged = true
end
sliderList.size.value = v / 120
end
end,
{width = 30}
) )
local gridSizeTable = {1, 2, 5, 10, 20, 50, 100} local gridSizeTable = {1, 2, 5, 10, 20, 50, 100}
sliderList.gridSize = newSlider( sliderList.gridSize = newSlider(
405, 50, 100, 1, 1, #gridSizeTable - 1, 480, 80, 120, 1, 1, #gridSizeTable - 1,
function() function()
local v = math.roundUnit(sliderList.gridSize.value, 1 / 6) local f = #gridSizeTable - 1
local v = math.roundUnit(sliderList.gridSize.value, 1 / f)
sliderList.gridSize.value = v sliderList.gridSize.value = v
snapUnit = gridSizeTable[math.roundUnit(v * (#gridSizeTable - 1) + 1)] snapUnit = gridSizeTable[math.roundUnit(v * f + 1)]
end, end,
{width = 30} {width = 40}
); sliderList.gridSize.forceLight = true ); sliderList.gridSize.forceLight = true
local function sliderList_draw() local function sliderList_draw()
@@ -177,13 +189,15 @@ function TouchConfigScene:update()
if VCTRL.focus~=focusingButton then if VCTRL.focus~=focusingButton then
focusingButton = VCTRL.focus focusingButton = VCTRL.focus
sliderList.opacity.value = focusingButton.alpha sliderList.opacity.value = focusingButton.alpha
sliderList.size.value = focusingButton.r / 120 sliderList.buttonSize.value = focusingButton.r / 120
sliderList.iconSize.value = focusingButton.iconSize / 100
end end
BUTTON.update(buttonList) BUTTON.update(buttonList)
sliderList_update() sliderList_update()
end end
local string_format = string.format
function TouchConfigScene:render() function TouchConfigScene:render()
MainBackground() MainBackground()
@@ -206,19 +220,16 @@ function TouchConfigScene:render()
end end
love.graphics.setColor(0, 0, 0, 0.7) love.graphics.setColor(0, 0, 0, 0.7)
-- Opacity and Size love.graphics.rectangle("fill", 5, 5, 560, 100)
love.graphics.rectangle("fill", 10, 5, 267, 75)
-- Snap to grid
love.graphics.rectangle("fill", 330, 5, 150, 75)
-- Button Size
drawText(string_format("Size (buttons)\n%14.1d", focusingButton and focusingButton.r or 0), 10, 13, 100, "left")
-- Icon size
drawText(string_format("Size (icons)\n%13.1d%%", focusingButton and focusingButton.iconSize or 0), 290, 13, 100, "left")
-- Opacity -- Opacity
drawText("Opacity", 20, 15, 100, "left") drawText(string_format("Opacity\n%13.1d%%", focusingButton and focusingButton.alpha * 100 or 0), 10, 63, 100, "left")
drawText(string.format("%3.1d%%", focusingButton and focusingButton.alpha * 100 or 0), 225, 15, 40, "left")
-- Size
drawText("Size", 20, 55, 100, "left")
drawText(string.format("%3.1dpx", focusingButton and focusingButton.r or 0), 225, 55, 40, "left")
-- Snap to grid -- Snap to grid
drawText(string.format("Snap to grid: %3s", snapUnit), 345, 15, 140, "left") drawText(string_format("Snap to grid\n%14.1d", snapUnit), 290, 63, 100, "left")
for _, v in ipairs(VCTRL) do for _, v in ipairs(VCTRL) do
if v ~= focusingButton then if v ~= focusingButton then
@@ -245,10 +256,8 @@ end
---@param e SCENE_onInput ---@param e SCENE_onInput
function TouchConfigScene:onInputMove(e) function TouchConfigScene:onInputMove(e)
if e.type == "touch" or (e.type == "mouse" and love.mouse.isDown(1)) then if e.type == "touch" or (e.type == "mouse" and love.mouse.isDown(1)) then
if VCTRL.drag(e.dx, e.dy, e.id or 1) then hasChanged = true end if VCTRL.drag(e.dx, e.dy, e.id or 1) then VCTRL.hasChanged = true end
end elseif e.type == "mouse" then
if e.type == "mouse" then
BUTTON.checkHovering(buttonList, e.x, e.y) BUTTON.checkHovering(buttonList, e.x, e.y)
end end
end end
@@ -258,7 +267,8 @@ function TouchConfigScene:onInputPress(e)
if not ( if not (
VCTRL.press(e.x, e.y, e.id and e.id or 1, true) or VCTRL.press(e.x, e.y, e.id and e.id or 1, true) or
BUTTON.press(buttonList, e.x, e.y, e.id) or BUTTON.press(buttonList, e.x, e.y, e.id) or
(e.x >= 80 and e.x <= 230 and e.y >= 10 and e.y <= 77) (e.x >= 120 and e.x <= 280 and e.y >= 10 and e.y <= 100) or
(e.x >= 400 and e.x <= 560 and e.y >= 10 and e.y <= 100)
) then ) then
VCTRL.focus = nil VCTRL.focus = nil
focusingButton = nil focusingButton = nil

View File

@@ -8,7 +8,7 @@ local buttonList
buttonList = { buttonList = {
previewToggle = BUTTON.new{ previewToggle = BUTTON.new{
text = "Preview\nOFF", text = "Preview\nOFF",
x = 570, y = 35, w = 60, h = 40, x = 570, y = 60, w = 60, h = 40,
codeWhenReleased = function() codeWhenReleased = function()
VCTRL.release() VCTRL.release()
BUTTON.release(buttonList) BUTTON.release(buttonList)
@@ -16,8 +16,6 @@ buttonList = {
end end
}, },
} }
local sliderList = {}
local secret_grade_grid = {} local secret_grade_grid = {}
do do
local colour_names = {'R', 'O', 'Y', 'G', 'C', 'B', 'M'} local colour_names = {'R', 'O', 'Y', 'G', 'C', 'B', 'M'}
@@ -80,13 +78,17 @@ end
function TouchConfigPreviewScene:onInputPress(e) function TouchConfigPreviewScene:onInputPress(e)
if e.type ~= "virtual" and e.input == 'menu_back' then SCENE = InputConfigScene() end if e.type ~= "virtual" and e.input == 'menu_back' then SCENE = InputConfigScene() end
if e.type == "mouse" or e.type == "touch" then if e.type == "mouse" or e.type == "touch" then
BUTTON.press(buttonList, e.x, e.y, e.id) if not BUTTON.press(buttonList, e.x, e.y, e.id) then
VCTRL.press(e.x, e.y, e.id or 1)
end
end end
end end
---@param e SCENE_onInput ---@param e SCENE_onInput
function TouchConfigPreviewScene:onInputRelease(e) function TouchConfigPreviewScene:onInputRelease(e)
if e.type == "mouse" or e.type == "touch" then if e.type == "mouse" or e.type == "touch" then
BUTTON.release(buttonList, e.x, e.y, e.id) if not BUTTON.release(buttonList, e.x, e.y, e.id) then
VCTRL.release(e.id or 1)
end
end end
end end

View File

@@ -1,14 +1,15 @@
local TrainingScene = SCENE:extend() local TrainingScene = SCENE:extend()
TrainingScene.title = "Max Gravity Training" TrainingScene.title = "Max Gravity Training"
local menuKey local menuKey = BUTTON.new{
text = CHAR.icon.menu.." MENU",
x = 10, y = 10, w = 70, h = 30,
codeWhenReleased = function() SCENE = TitleScene() end
}
function TrainingScene:new() function TrainingScene:new()
menuKey = BUTTON.new{ BUTTON.reset{menuKey}
text = "MENU", VCTRL[9].show = true
x = 265, y = 0, w = 60, h = 25,
codeWhenReleased = function() SCENE = TitleScene() end
}
game_mode = require 'game.gamemode' game_mode = require 'game.gamemode'
if PENTO_MODE then if PENTO_MODE then

View File

@@ -10,12 +10,12 @@ local _defaultSettings = {
lines = true, lines = true,
---@class input ---@class input
---@field keys table <string, string> ---@field keys table <string, string>|nil
---@field joysticks table <string, string> ---@field joysticks table <string, string>|nil
---@field touch table <string, string> ---@field touch table <string, string>
input = { input = {
keys = {}, keys = nil,
joysticks = {}, joysticks = nil,
virtual = { virtual = {
{type='button',x= 70,y=280,key= 'up',r=45,iconSize=60,alpha=0.4}, {type='button',x= 70,y=280,key= 'up',r=45,iconSize=60,alpha=0.4},
{type='button',x= 70,y=430,key= 'down',r=45,iconSize=60,alpha=0.4}, {type='button',x= 70,y=430,key= 'down',r=45,iconSize=60,alpha=0.4},
@@ -28,7 +28,7 @@ local _defaultSettings = {
{type='button',x=320, y=420,key= 'restart',r=35,iconSize=60,alpha=0.4}, {type='button',x=320, y=420,key= 'restart',r=35,iconSize=60,alpha=0.4},
} }
}, },
tvMode = false -- 79338732 tvMode = false
} }
SETTINGS = setmetatable( SETTINGS = setmetatable(