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
|
### 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>
|
||||||
|
|||||||
4
char.lua
4
char.lua
@@ -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,
|
||||||
|
|||||||
16
funcs.lua
16
funcs.lua
@@ -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)
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
4
load.lua
4
load.lua
@@ -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
|
||||||
|
|||||||
78
main.lua
78
main.lua
@@ -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
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()
|
love.event.quit()
|
||||||
end
|
end
|
||||||
|
|
||||||
function ExitScene:render()
|
|
||||||
end
|
|
||||||
|
|
||||||
function ExitScene:changeOption(rel)
|
|
||||||
end
|
|
||||||
|
|
||||||
function ExitScene:onInputPress(e)
|
|
||||||
end
|
|
||||||
|
|
||||||
return ExitScene
|
return ExitScene
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
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()
|
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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
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()
|
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
|
||||||
|
|||||||
@@ -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
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 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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
10
settings.lua
10
settings.lua
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user