mirror of
https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile.git
synced 2025-01-08 17:33:09 +08:00
V1 update (#1)
This commit is contained in:
committed by
Squishy (C6H12O6+NaCl+H2O)
parent
3343d8711b
commit
1d6643448e
33
README.md
33
README.md
@@ -35,28 +35,35 @@ Ported to Android (mobile and TV) by SweetSea with on-screen control (with some
|
||||
### 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.
|
||||
|
||||
# Differences from original Tromi
|
||||
# Changes
|
||||
> 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 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
|
||||
* Add ``simple-button`` module, made by me (SweetSea)
|
||||
* All UIs are touch-able
|
||||
* Add replay importer / exporter through clipboard
|
||||
* UI are re-designed to compactible with touch screen
|
||||
* Add on-screen buttons
|
||||
* Replaced icons for 3 direction buttons (Left, Down, Right), using from Techmino's font (outdated image)
|
||||
<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))<img src="https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile/raw/branch/main/screenshot/SPOILER_tv_code.png">
|
||||
* <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>
|
||||
* Add a loading screen ~~(this need to be updated later)~~
|
||||
* Replaced icons for 3 direction buttons (Left, Down, Right), using from Techmino's font.
|
||||
* Add a special pre-made keybind for Android TV (only supports TV models have their remote has numerical area (0-9)).
|
||||
* 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.
|
||||
* 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.
|
||||
* 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
|
||||
* 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
|
||||
- [ ] 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] 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
|
||||
- [ ] (Low priority) Design a new menu screen
|
||||
- [x] Updating on-screen control configuration 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)
|
||||
Please read ``COPYING.txt`` for more information.<br>
|
||||
|
||||
4
char.lua
4
char.lua
@@ -88,8 +88,8 @@ local L={
|
||||
hollowLogo= 0xF008C,
|
||||
toUp= 0xF008D,
|
||||
toDown= 0xF008E,
|
||||
toLeft= 0xF008F,
|
||||
toRight= 0xF0090,
|
||||
toLeft= 0xF0090,
|
||||
toRight= 0xF008F,
|
||||
checkMark= 0xF0091,
|
||||
crossMark= 0xF0092,
|
||||
musicMark= 0xF0093,
|
||||
|
||||
16
funcs.lua
16
funcs.lua
@@ -94,6 +94,13 @@ function math.roundUnit(n,u)
|
||||
return math.floor(n/u+.5)*u
|
||||
end
|
||||
|
||||
---@return table
|
||||
function table.pack(...)
|
||||
local t = {...}
|
||||
t.n = select('#', ...)
|
||||
return t
|
||||
end
|
||||
|
||||
---@param t1 table
|
||||
---@param t2 table
|
||||
---@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)
|
||||
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)
|
||||
if color == nil then color = {1, 1, 1, 1} end
|
||||
love.graphics.setFont(FONT_big)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
local Object = require 'libs.classic'
|
||||
local bit = require("bit")
|
||||
local lualzw = require 'libs.lualzw'
|
||||
local bitser = require 'libs.bitser'
|
||||
|
||||
local playedReadySE = false
|
||||
local hiscore_pos
|
||||
|
||||
local Grid = require 'game.grid'
|
||||
local Randomizer = require 'game.randomizer'
|
||||
@@ -11,7 +11,9 @@ local Randomizer = require 'game.randomizer'
|
||||
local GameMode = Object:extend()
|
||||
|
||||
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 input_file ~= nil then
|
||||
@@ -149,7 +151,7 @@ function GameMode:readGradeHistory()
|
||||
if self.grade > 1 then
|
||||
local temp_grade = copy(self.grade_history); temp_grade[2] = 0
|
||||
FILE.write(SAVE_DIR..self.player_name.."_grade_history.sav", temp_grade)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GameMode:readHiScores()
|
||||
@@ -979,7 +981,7 @@ function GameMode:drawScoringInfo()
|
||||
love.graphics.rectangle("fill", 95, 80, 110, 180, 10, 10)
|
||||
if not PENTO_MODE then drawText("Grade:", 100, 128, 1000, "left") end
|
||||
-- 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.rectangle("fill", 241, 407, 116, 40, 5, 5) --lines
|
||||
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.setColor(0.05,0.05,0.05,1)
|
||||
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")
|
||||
self:drawInputDisplay(103,185)
|
||||
elseif not PENTO_MODE then
|
||||
@@ -1073,6 +1075,7 @@ end
|
||||
|
||||
function GameMode:drawFrame()
|
||||
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+(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))
|
||||
|
||||
@@ -64,7 +64,7 @@ function control_type.button:new(data)
|
||||
r=data.r or 80, -- size
|
||||
shape=data.shape or 'circle',
|
||||
key=data.key or 'X',
|
||||
iconSize=data.iconSize or 80,
|
||||
iconSize=data.iconSize or 60,
|
||||
alpha=data.alpha or 0.75,
|
||||
quad=virtual_quad[data.key]
|
||||
},self)
|
||||
@@ -90,7 +90,7 @@ end
|
||||
function control_type.button:press(_,_,id)
|
||||
self.pressed=true
|
||||
self.lastPressTime=love.timer.getTime()
|
||||
self.pressing=id
|
||||
self.pressingID=id
|
||||
-- love.keypressed(self.key, love.keyboard.getScancodeFromKey(self.key))
|
||||
SCENE:onInputPress{input=self.key,type="virtual"}
|
||||
end
|
||||
@@ -148,6 +148,7 @@ local touches={}
|
||||
local global_toggle=false
|
||||
VCTRL={}
|
||||
VCTRL.focus=nil -- Focusing buttons
|
||||
VCTRL.hasChanged = false
|
||||
|
||||
---@class VCTRL.data
|
||||
---@field type 'button'
|
||||
@@ -231,6 +232,13 @@ function VCTRL.draw(forceAlpha)
|
||||
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()
|
||||
local t = {}
|
||||
for o, k in ipairs(VCTRL) do t[o] = k:export() end
|
||||
|
||||
@@ -139,11 +139,11 @@ function button:isHovering(x,y)
|
||||
end
|
||||
---Trigger press action, only when ``self._hovering`` is true
|
||||
function button:press(x, y, touchID)
|
||||
if (touchID and self:isHovering(x, y) or self._hovering) and not self._pressed then
|
||||
self.codeWhenPressed()
|
||||
|
||||
if self:isHovering(x, y) and not self._pressed then
|
||||
self._touchID = touchID
|
||||
self._pressed = true
|
||||
|
||||
self.codeWhenPressed()
|
||||
self:draw()
|
||||
|
||||
return true
|
||||
@@ -154,7 +154,7 @@ function button:release(x, y, touchID)
|
||||
local valid = true
|
||||
if touchID then
|
||||
valid = touchID == self._touchID
|
||||
elseif x and y then
|
||||
else
|
||||
valid = true
|
||||
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
|
||||
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
|
||||
4
load.lua
4
load.lua
@@ -1,10 +1,8 @@
|
||||
-- Fonts
|
||||
FONT_tromi = love.graphics.newFont('res/fonts/Iosevka-Bold.ttf' , 28)
|
||||
FONT_big = love.graphics.newFont('res/fonts/Iosevka-Heavy.ttf', 56)
|
||||
FONT_bold = love.graphics.newFont('res/fonts/Iosevka-Heavy.ttf', 28)
|
||||
-- Icons
|
||||
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))
|
||||
CHAR = require("char")
|
||||
|
||||
@@ -48,8 +46,6 @@ BUTTON.setDefaultOption{
|
||||
|
||||
if self.font == FONT_big then
|
||||
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
|
||||
drawText(text, self.x + 2.5, textPos, self.w - 5, self.textOrientation, self.textColor)
|
||||
end
|
||||
|
||||
78
main.lua
78
main.lua
@@ -2,17 +2,17 @@ if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE")=="1" then
|
||||
LLDEBUGGER=require('lldebugger')
|
||||
LLDEBUGGER.start()
|
||||
end
|
||||
require 'funcs'
|
||||
DEBUG_showKey = false
|
||||
|
||||
PENTO_MODE = false
|
||||
SAVE_DIR = 'saves/'
|
||||
REPLAY_DIR = 'saves/replays/'
|
||||
CONFIG_FILE = 'config.sav'
|
||||
HIscoreFILE = 'hiscores.sav'
|
||||
if not love.filesystem.getInfo(REPLAY_DIR) then
|
||||
love.filesystem.createDirectory(REPLAY_DIR)
|
||||
end
|
||||
CONFIG_FILE = 'config.sav'
|
||||
HIscoreFILE = 'hiscores.sav'
|
||||
|
||||
BACKGROUND_COLOR = {32/255, 120/255, 88/255}
|
||||
|
||||
CURRENT_OS = love.system.getOS()
|
||||
MOBILE = CURRENT_OS == "Android" or CURRENT_OS == "iOS"
|
||||
@@ -34,6 +34,7 @@ function ShowLoadingText(thing)
|
||||
end
|
||||
|
||||
function love.load()
|
||||
require 'funcs'
|
||||
math.randomseed(os.time())
|
||||
require "modules.file" "binser"
|
||||
require "settings"
|
||||
@@ -48,19 +49,11 @@ function love.load()
|
||||
|
||||
-- Now it's real time to load all stuffs!
|
||||
require "load" -- Most game's resources are loaded in here
|
||||
require "modules.scene"
|
||||
require "scene"
|
||||
require "game.vctrl" -- VCTRL
|
||||
|
||||
function SCENE.update()
|
||||
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
|
||||
SCENE = LoadingScene()
|
||||
|
||||
-- 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},
|
||||
-- -- {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)
|
||||
-- end
|
||||
|
||||
-- local x, y = GLOBAL_TRANSFORM:inverseTransformPoint(love.mouse.getPosition())
|
||||
-- love.graphics.setColor(0, 0, 0, 0.8)
|
||||
-- love.graphics.rectangle("fill", 5, 450, 115, 25)
|
||||
-- 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)
|
||||
local x, y = GLOBAL_TRANSFORM:inverseTransformPoint(love.mouse.getPosition())
|
||||
love.graphics.setColor(0, 0, 0, 0.8)
|
||||
love.graphics.rectangle("fill", 5, 450, 115, 25)
|
||||
drawText(string.format("X: %.1d; Y: %.1d", x, y), 10, 455, 110, "left")
|
||||
|
||||
love.graphics.pop()
|
||||
end
|
||||
@@ -156,8 +145,10 @@ function love.keypressed(key, scancode)
|
||||
if scancode == "f4" then
|
||||
SETTINGS["fullscreen"] = not 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
|
||||
SCENE = InputConfigScene()
|
||||
elseif scancode == "f3" then SCENE = DataManagementScene()
|
||||
elseif scancode == "f12" then LLDEBUGGER.requestBreak()
|
||||
-- elseif scancode == "f11" then SETTINGS.firstTime = true
|
||||
-- function keys are reserved
|
||||
@@ -386,30 +377,24 @@ function love.errorhandler(msg)
|
||||
print("\n"..table.concat(err,"\n",1,c-2))
|
||||
local tracebacks = table.concat(err,"\n", 4)
|
||||
|
||||
if drawText == nil then
|
||||
pcall(function()
|
||||
FONT_tromi = love.graphics.newFont('res/fonts/monofonto rg.otf', 20)
|
||||
require "funcs"
|
||||
end)
|
||||
if drawText == nil then
|
||||
love.window.setMode(640, 480, {resizable = true})
|
||||
return function() -- If "funcs" failed to load, we can only return a more simple version of error screen
|
||||
love.event.pump()
|
||||
for e, a, b, c in love.event.poll() do
|
||||
if e == "quit" 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
|
||||
if drawText == nil or FONT_tromi == nil then
|
||||
love.audio.stop()
|
||||
love.graphics.origin()
|
||||
love.graphics.setFont(love.graphics.newFont(20))
|
||||
return function()
|
||||
love.event.pump()
|
||||
for e, a, b, c in love.event.poll() do
|
||||
if (
|
||||
e == "quit" or
|
||||
e == "mousepressed"
|
||||
) then return 1 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
|
||||
|
||||
@@ -535,6 +520,9 @@ local main_bg_draw_frame = 0
|
||||
local main_bg_last_color = nil
|
||||
|
||||
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
|
||||
SOUNDS["bgm_title"]:setVolume(0.3)
|
||||
SOUNDS["bgm_title"]:play()
|
||||
|
||||
85
scene.lua
Normal file
85
scene.lua
Normal 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
139
scene/about.lua
Normal 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
|
||||
81
scene/data/erase_high_scores.lua
Normal file
81
scene/data/erase_high_scores.lua
Normal 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
93
scene/data/reset_all.lua
Normal 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
96
scene/data_management.lua
Normal 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
|
||||
@@ -8,14 +8,5 @@ function ExitScene:update()
|
||||
love.event.quit()
|
||||
end
|
||||
|
||||
function ExitScene:render()
|
||||
end
|
||||
|
||||
function ExitScene:changeOption(rel)
|
||||
end
|
||||
|
||||
function ExitScene:onInputPress(e)
|
||||
end
|
||||
|
||||
return ExitScene
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ GameScene.title = "Game"
|
||||
|
||||
local tas = false
|
||||
|
||||
-- 70 295
|
||||
local buttonList = {
|
||||
BUTTON.new{
|
||||
text = "Rotate Left\n Pause/Frame Step",
|
||||
@@ -45,17 +44,17 @@ local buttonList = {
|
||||
local menuKey -- MENU key used to go main menu XD
|
||||
|
||||
function GameScene:new(player_name, replay_file, replay_grade)
|
||||
VCTRL[9].show = false
|
||||
|
||||
menuKey = BUTTON.new{
|
||||
text = "MENU",
|
||||
x = 265, y = 0, w = 60, h = 25,
|
||||
text = CHAR.icon.menu.." MENU",
|
||||
x = 10, y = 10, w = 70, h = 30,
|
||||
codeWhenReleased = function()
|
||||
if self.game.input_playback or self.game.game_over or self.game.completed then
|
||||
SCENE = TitleScene()
|
||||
end
|
||||
end
|
||||
}
|
||||
VCTRL[9].show = false
|
||||
BUTTON.reset(buttonList)
|
||||
|
||||
game_mode = require 'game.gamemode'
|
||||
if PENTO_MODE then
|
||||
@@ -89,7 +88,7 @@ end
|
||||
|
||||
function GameScene:update(nosound, tas_update)
|
||||
local inputs = {}
|
||||
if tas then
|
||||
if tas then
|
||||
while self.game.are > 2 do
|
||||
self.game:update(inputs, self.ruleset)
|
||||
end
|
||||
|
||||
@@ -48,16 +48,16 @@ end
|
||||
function KeyConfigScene:render()
|
||||
MainBackground()
|
||||
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
|
||||
drawText(self.set_inputs[input], 240, 50 + i * 20, 300, "left")
|
||||
drawText(self.set_inputs[input], 240, 60 + i * 20, 300, "left")
|
||||
end
|
||||
end
|
||||
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
|
||||
drawText("Press key input for " .. input_names[configurable_inputs[self.input_state]] .. ", tab to skip, escape to cancel",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("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("Function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 35,1000)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
local LinesToggleScene = SCENE:extend()
|
||||
LinesToggleScene.title = "Show lines during game:"
|
||||
|
||||
function LinesToggleScene:new()
|
||||
end
|
||||
|
||||
function LinesToggleScene:update()
|
||||
SETTINGS["lines"] = not SETTINGS["lines"]
|
||||
SCENE = TitleScene()
|
||||
end
|
||||
|
||||
function LinesToggleScene:render()
|
||||
end
|
||||
|
||||
function LinesToggleScene:changeOption(rel)
|
||||
end
|
||||
|
||||
function LinesToggleScene:onInputPress(e)
|
||||
end
|
||||
|
||||
return LinesToggleScene
|
||||
10
scene/loading.lua
Normal file
10
scene/loading.lua
Normal 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
|
||||
@@ -1,21 +1,9 @@
|
||||
local MusicToggleScene = SCENE:extend()
|
||||
MusicToggleScene.title = "Play music during game:"
|
||||
|
||||
function MusicToggleScene:new()
|
||||
end
|
||||
|
||||
function MusicToggleScene:update()
|
||||
SETTINGS["music"] = not SETTINGS["music"]
|
||||
SCENE = TitleScene()
|
||||
end
|
||||
|
||||
function MusicToggleScene:render()
|
||||
end
|
||||
|
||||
function MusicToggleScene:changeOption(rel)
|
||||
end
|
||||
|
||||
function MusicToggleScene:onInputPress(e)
|
||||
end
|
||||
|
||||
return MusicToggleScene
|
||||
return MusicToggleScene
|
||||
@@ -3,33 +3,37 @@ NameEntryScene.title = "Game Start"
|
||||
|
||||
local buttonList = {
|
||||
BUTTON.new{
|
||||
text = "←\nCHAR", font = FONT_big,
|
||||
text = "↑\nCHAR", font = FONT_big,
|
||||
x = 25, y = 120, w = 80, h = 80,
|
||||
codeWhenPressed = function() SCENE:onInputPress {input = "left"} end,
|
||||
codeWhenReleased = function() SCENE:onInputRelease{input = "left"} end,
|
||||
},
|
||||
BUTTON.new{
|
||||
text = "→\nCHAR", font = FONT_big,
|
||||
text = "↓\nCHAR", font = FONT_big,
|
||||
x = 115, y = 120, w = 80, h = 80,
|
||||
codeWhenPressed = function() SCENE:onInputPress {input = "right"} end,
|
||||
codeWhenReleased = function() SCENE:onInputRelease{input = "right"} end,
|
||||
},
|
||||
BUTTON.new{
|
||||
text = "↑\nESC", font = FONT_big,
|
||||
text = "←\nESC", font = FONT_big,
|
||||
x = 25, y = 210, w = 80, h = 80,
|
||||
codeWhenPressed = function() SCENE:onInputPress {input = "menu_back"} end,
|
||||
codeWhenReleased = function() SCENE:onInputRelease{input = "menu_back"} end,
|
||||
},
|
||||
BUTTON.new{
|
||||
text = "↓\nENTER", font = FONT_big,
|
||||
text = "→\nENTER", font = FONT_big,
|
||||
x = 115, y = 210, w = 80, h = 80,
|
||||
codeWhenPressed = function() SCENE:onInputPress {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 bitser = require 'libs.bitser'
|
||||
|
||||
function NameEntryScene:new()
|
||||
VCTRL.toggle(false)
|
||||
@@ -61,7 +65,6 @@ function NameEntryScene:new()
|
||||
self.hi_scores = {"TRO",0,"MIT",0,"ROM",0,"ITR",0,"OMI",0}
|
||||
end
|
||||
end
|
||||
|
||||
function NameEntryScene:drawGradeList(left, top)
|
||||
love.graphics.setColor(0,0,0,0.5)
|
||||
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.rectangle("fill", 397, 292, 130, 130, 10, 10)
|
||||
drawText("Best scores:", 410, 297, 1000, "left")
|
||||
i = 2
|
||||
while i <= 10 do
|
||||
for i = 2, 10, 2 do
|
||||
drawText(self.hi_scores[i-1]..' - '..self.hi_scores[i], 410, 297+(i*10), 1000, "left")
|
||||
i = i + 2
|
||||
end
|
||||
if self.entry_pos == 4 then
|
||||
drawText('Press confirm\nto play', 255, 290, 1000)
|
||||
@@ -138,28 +139,43 @@ function NameEntryScene:onInputMove(e)
|
||||
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)
|
||||
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
|
||||
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
|
||||
if self.entry_pos == 4 then
|
||||
BUTTON.release(buttonList, e.x, e.y, e.id)
|
||||
SETTINGS['last_entry'] = name:upper()
|
||||
SCENE = GameScene(name:lower())
|
||||
else
|
||||
if self.entry_pos == 3 then
|
||||
name = string.lower(self.name_entry[1]..self.name_entry[2]..self.name_entry[3])
|
||||
if love.filesystem.getInfo((SAVE_DIR..name.."_grade_history.sav")) then
|
||||
grade_history = FILE.read(SAVE_DIR..name.."_grade_history.sav")
|
||||
self.grade = grade_history[1]
|
||||
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
|
||||
if self.entry_pos == 3 then self:getPlayInfo(name)
|
||||
else
|
||||
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
|
||||
end
|
||||
elseif e.input == "left" or e.scancode == "left" then
|
||||
|
||||
@@ -160,10 +160,10 @@ function ReplaySelectScene:onInputPress(e)
|
||||
end
|
||||
elseif e.input == "rotate_left" then -- Export
|
||||
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
|
||||
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 separator_pos = data_part:find("|", 1, true)
|
||||
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))
|
||||
love.filesystem.write(replay_path, replay_data)
|
||||
|
||||
BUTTON.reset(buttonList)
|
||||
SCENE = ReplayTestScene(replay_name)
|
||||
else
|
||||
BUTTON.reset(buttonList)
|
||||
SCENE = ReplayTestScene()
|
||||
end
|
||||
elseif e.input == "up" or e.scancode == "up" then
|
||||
|
||||
@@ -3,9 +3,12 @@ local ReplayTestScene = SCENE:extend()
|
||||
local GAME
|
||||
local error_message
|
||||
local valid_data
|
||||
local prev_scene
|
||||
|
||||
|
||||
function ReplayTestScene:new(input_file)
|
||||
prev_scene = SCENE
|
||||
|
||||
if not input_file then
|
||||
valid_data = false
|
||||
return
|
||||
@@ -27,7 +30,10 @@ function ReplayTestScene:new(input_file)
|
||||
end
|
||||
|
||||
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 error_message then
|
||||
drawText("Replay test failed! Data corrupted!", 80, 40, 1000)
|
||||
@@ -39,7 +45,7 @@ function ReplayTestScene:render()
|
||||
end
|
||||
else
|
||||
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
|
||||
|
||||
|
||||
95
scene/settings.lua
Normal file
95
scene/settings.lua
Normal 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
|
||||
@@ -48,13 +48,13 @@ end
|
||||
function StickConfigScene:render()
|
||||
MainBackground()
|
||||
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
|
||||
drawText(self.set_inputs[input], 240, 50 + i * 20, 300, "left")
|
||||
drawText(self.set_inputs[input], 240, 60 + i * 20, 300, "left")
|
||||
end
|
||||
end
|
||||
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
|
||||
drawText("Press joystick input for " .. input_names[configurable_inputs[self.input_state]] .. ", tab to skip, escape to cancel", 0, 0, 1000)
|
||||
end
|
||||
|
||||
@@ -15,8 +15,6 @@ local main_menu_screens = {
|
||||
}
|
||||
|
||||
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
|
||||
love.audio.stop()
|
||||
end
|
||||
@@ -116,7 +114,6 @@ function TitleScene:onInputPress(e)
|
||||
if self.main_menu_state ~= selecting then
|
||||
self.main_menu_state = selecting
|
||||
else
|
||||
VCTRL.toggle(true)
|
||||
SCENE = main_menu_screens[selecting]()
|
||||
end
|
||||
end
|
||||
|
||||
164
scene/title2.lua
Normal file
164
scene/title2.lua
Normal 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
|
||||
@@ -5,13 +5,11 @@ TouchConfigScene.title = "Touchscreen config"
|
||||
local Grid = require 'game.grid'
|
||||
|
||||
local buttonList
|
||||
local sliderList
|
||||
local sliderList = {}
|
||||
---@class VCTRL.data
|
||||
local focusingButton
|
||||
---@type number
|
||||
local snapUnit = 1
|
||||
---@type boolean
|
||||
local hasChanged
|
||||
|
||||
---@type function
|
||||
local function exitSceneFunc(saved)
|
||||
@@ -29,23 +27,23 @@ buttonList = {
|
||||
showToggle = BUTTON.new{
|
||||
text = function()
|
||||
if focusingButton then
|
||||
return focusingButton.show and "[SHOW]\nHide" or "Show\n[HIDE]"
|
||||
return focusingButton.show and ">SHOW<\nhide" or "show\n>HIDE<"
|
||||
else
|
||||
return "Show\nHide"
|
||||
return "show\nhide"
|
||||
end
|
||||
end,
|
||||
x = 275, y = 5, w = 50, h = 75,
|
||||
codeWhenReleased = function ()
|
||||
x = 400, y = 110, w = 60, h = 40,
|
||||
codeWhenReleased = function()
|
||||
if focusingButton then
|
||||
focusingButton.show = not focusingButton.show
|
||||
hasChanged = true
|
||||
VCTRL.hasChanged = true
|
||||
end
|
||||
end,
|
||||
update = function(self) self.textColor = focusingButton and {1, 1, 1} or {0.5, 0.5, 0.5} end
|
||||
},
|
||||
previewToggle = BUTTON.new{
|
||||
text = "Preview\nON",
|
||||
x = 570, y = 35, w = 60, h = 40,
|
||||
x = 570, y = 60, w = 60, h = 40,
|
||||
codeWhenReleased = function()
|
||||
VCTRL.release()
|
||||
BUTTON.release(buttonList)
|
||||
@@ -54,7 +52,7 @@ buttonList = {
|
||||
},
|
||||
resetAll = BUTTON.new{
|
||||
text = "RESET\nALL",
|
||||
x = 570, y = 80, w = 60, h = 40,
|
||||
x = 500, y = 110, w = 60, h = 40,
|
||||
codeWhenReleased = function()
|
||||
local selection = love.window.showMessageBox(
|
||||
"Save config?", "Are you really sure about RESETTING ALL touchscreen configuration?",
|
||||
@@ -63,7 +61,7 @@ buttonList = {
|
||||
)
|
||||
if selection == 1 then
|
||||
VCTRL.focus = nil; focusingButton = nil
|
||||
hasChanged = false
|
||||
VCTRL.hasChanged = false
|
||||
VCTRL.clearAll()
|
||||
VCTRL.new(SETTINGS.__default__.input.virtual)
|
||||
SETTINGS.input.virtual = SETTINGS.__default__.input.virtual
|
||||
@@ -72,9 +70,9 @@ buttonList = {
|
||||
},
|
||||
menuScreen = BUTTON.new{
|
||||
text = "MENU",
|
||||
x = 570, y = 5, w = 60, h = 25,
|
||||
x = 570, y = 10, w = 60, h = 40,
|
||||
codeWhenReleased = function()
|
||||
if hasChanged or SETTINGS.firstTime then
|
||||
if VCTRL.hasChanged or SETTINGS.firstTime then
|
||||
local selection = love.window.showMessageBox(
|
||||
"Save config?", "Do you want to save your changes before exiting?",
|
||||
{"Save", "Discard", "Keep editing", escapebutton = 3, enterbutton = 1},
|
||||
@@ -98,45 +96,59 @@ buttonList = {
|
||||
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(
|
||||
155, 20+5, 120, 100, 0, 100,
|
||||
200, 80, 120, 0, 0, 1,
|
||||
function()
|
||||
local v
|
||||
if focusingButton then
|
||||
v = math.roundUnit(sliderList.opacity.value, 0.01)
|
||||
if focusingButton.alpha~=v then
|
||||
focusingButton.alpha = v
|
||||
hasChanged = true
|
||||
VCTRL.hasChanged = true
|
||||
end
|
||||
sliderList.opacity.value = v
|
||||
end
|
||||
end,
|
||||
{width = 30}
|
||||
)
|
||||
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}
|
||||
{width = 40}
|
||||
)
|
||||
local gridSizeTable = {1, 2, 5, 10, 20, 50, 100}
|
||||
sliderList.gridSize = newSlider(
|
||||
405, 50, 100, 1, 1, #gridSizeTable - 1,
|
||||
480, 80, 120, 1, 1, #gridSizeTable - 1,
|
||||
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
|
||||
snapUnit = gridSizeTable[math.roundUnit(v * (#gridSizeTable - 1) + 1)]
|
||||
snapUnit = gridSizeTable[math.roundUnit(v * f + 1)]
|
||||
end,
|
||||
{width = 30}
|
||||
{width = 40}
|
||||
); sliderList.gridSize.forceLight = true
|
||||
|
||||
local function sliderList_draw()
|
||||
@@ -177,13 +189,15 @@ function TouchConfigScene:update()
|
||||
if VCTRL.focus~=focusingButton then
|
||||
focusingButton = VCTRL.focus
|
||||
sliderList.opacity.value = focusingButton.alpha
|
||||
sliderList.size.value = focusingButton.r / 120
|
||||
sliderList.buttonSize.value = focusingButton.r / 120
|
||||
sliderList.iconSize.value = focusingButton.iconSize / 100
|
||||
end
|
||||
|
||||
BUTTON.update(buttonList)
|
||||
sliderList_update()
|
||||
end
|
||||
|
||||
local string_format = string.format
|
||||
function TouchConfigScene:render()
|
||||
MainBackground()
|
||||
|
||||
@@ -206,19 +220,16 @@ function TouchConfigScene:render()
|
||||
end
|
||||
|
||||
love.graphics.setColor(0, 0, 0, 0.7)
|
||||
-- Opacity and Size
|
||||
love.graphics.rectangle("fill", 10, 5, 267, 75)
|
||||
-- Snap to grid
|
||||
love.graphics.rectangle("fill", 330, 5, 150, 75)
|
||||
love.graphics.rectangle("fill", 5, 5, 560, 100)
|
||||
|
||||
-- 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
|
||||
drawText("Opacity", 20, 15, 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")
|
||||
drawText(string_format("Opacity\n%13.1d%%", focusingButton and focusingButton.alpha * 100 or 0), 10, 63, 100, "left")
|
||||
-- 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
|
||||
if v ~= focusingButton then
|
||||
@@ -245,10 +256,8 @@ end
|
||||
---@param e SCENE_onInput
|
||||
function TouchConfigScene:onInputMove(e)
|
||||
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
|
||||
end
|
||||
|
||||
if e.type == "mouse" then
|
||||
if VCTRL.drag(e.dx, e.dy, e.id or 1) then VCTRL.hasChanged = true end
|
||||
elseif e.type == "mouse" then
|
||||
BUTTON.checkHovering(buttonList, e.x, e.y)
|
||||
end
|
||||
end
|
||||
@@ -258,7 +267,8 @@ function TouchConfigScene:onInputPress(e)
|
||||
if not (
|
||||
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
|
||||
(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
|
||||
VCTRL.focus = nil
|
||||
focusingButton = nil
|
||||
|
||||
@@ -8,7 +8,7 @@ local buttonList
|
||||
buttonList = {
|
||||
previewToggle = BUTTON.new{
|
||||
text = "Preview\nOFF",
|
||||
x = 570, y = 35, w = 60, h = 40,
|
||||
x = 570, y = 60, w = 60, h = 40,
|
||||
codeWhenReleased = function()
|
||||
VCTRL.release()
|
||||
BUTTON.release(buttonList)
|
||||
@@ -16,8 +16,6 @@ buttonList = {
|
||||
end
|
||||
},
|
||||
}
|
||||
local sliderList = {}
|
||||
|
||||
local secret_grade_grid = {}
|
||||
do
|
||||
local colour_names = {'R', 'O', 'Y', 'G', 'C', 'B', 'M'}
|
||||
@@ -80,13 +78,17 @@ end
|
||||
function TouchConfigPreviewScene:onInputPress(e)
|
||||
if e.type ~= "virtual" and e.input == 'menu_back' then SCENE = InputConfigScene() end
|
||||
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
|
||||
---@param e SCENE_onInput
|
||||
function TouchConfigPreviewScene:onInputRelease(e)
|
||||
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
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
local TrainingScene = SCENE:extend()
|
||||
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()
|
||||
menuKey = BUTTON.new{
|
||||
text = "MENU",
|
||||
x = 265, y = 0, w = 60, h = 25,
|
||||
codeWhenReleased = function() SCENE = TitleScene() end
|
||||
}
|
||||
BUTTON.reset{menuKey}
|
||||
VCTRL[9].show = true
|
||||
|
||||
game_mode = require 'game.gamemode'
|
||||
if PENTO_MODE then
|
||||
|
||||
10
settings.lua
10
settings.lua
@@ -10,12 +10,12 @@ local _defaultSettings = {
|
||||
lines = true,
|
||||
|
||||
---@class input
|
||||
---@field keys table <string, string>
|
||||
---@field joysticks table <string, string>
|
||||
---@field keys table <string, string>|nil
|
||||
---@field joysticks table <string, string>|nil
|
||||
---@field touch table <string, string>
|
||||
input = {
|
||||
keys = {},
|
||||
joysticks = {},
|
||||
keys = nil,
|
||||
joysticks = nil,
|
||||
virtual = {
|
||||
{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},
|
||||
@@ -28,7 +28,7 @@ local _defaultSettings = {
|
||||
{type='button',x=320, y=420,key= 'restart',r=35,iconSize=60,alpha=0.4},
|
||||
}
|
||||
},
|
||||
tvMode = false -- 79338732
|
||||
tvMode = false
|
||||
}
|
||||
|
||||
SETTINGS = setmetatable(
|
||||
|
||||
Reference in New Issue
Block a user