if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE")=="1" then lldebugger=require('lldebugger') lldebugger.start() REQUEST_BREAK=lldebugger.requestBreak else REQUEST_BREAK=function()end end require 'funcs' DEBUG_showKey = false PENTO_MODE = false SAVE_DIR = 'saves/' REPLAY_DIR = 'saves/replays/' if not love.filesystem.getInfo(REPLAY_DIR) then love.filesystem.createDirectory(REPLAY_DIR) end CONFIG_FILE = 'config.sav' HIscoreFILE = 'hiscores.sav' -- Text "LOADING..." local loaded = {} local last_loading local loadedCounter = 0 --- Show the loading text while we are loading resources
--- **WARNING**: should only be used while loading the game! function ShowLoadingText(thing) if last_loading then table.insert(loaded, last_loading) end last_loading = thing loadedCounter = loadedCounter + 1 love.graphics.replaceTransform(GLOBAL_TRANSFORM) love.graphics.setFont(love.graphics.newFont(20)) love.graphics.clear() drawText( "Loading Tromi... ["..loadedCounter.." / 3]\nPlease wait, don't touch anywhere or press any key!\n\nLoading: "..thing, 10,0,1e99,"left" ) for i, t in pairs(loaded) do drawText("Loaded "..t,10,80+20*i,1e99,"left") end love.graphics.flushBatch() love.graphics.present() end function love.load() math.randomseed(os.time()) require "settings" -- Window stuffs love.mouse.setVisible(false) love.window.setMode(love.graphics.getWidth(), love.graphics.getHeight(), {resizable = true}); love.window.setFullscreen(SETTINGS["fullscreen"]) -- Make a new transformer GLOBAL_TRANSFORM = love.math.newTransform() love.resize(love.graphics.getWidth(), love.graphics.getHeight()) -- Now it's real time to load all stuffs! require "load" -- Most game's resources are loaded in here require "scene" require "game.vctrl" -- VCTRL SCENE = SETTINGS.firstTime and InputConfigScene(true) or TitleScene() -- 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}, -- {type='button',x= 40,y=380,key= 'left',r=35,iconSize=60,alpha=0.75}, -- {type='button',x= 160,y=380,key= 'right',r=35,iconSize=60,alpha=0.75}, -- {type='button',x=640- 40,y=380,key= 'rotate_left',r=35,iconSize=60,alpha=0.75}, -- {type='button',x=640-160,y=380,key= 'rotate_left2',r=35,iconSize=60,alpha=0.75}, -- {type='button',x=640-100,y=440,key= 'rotate_right',r=35,iconSize=60,alpha=0.75}, -- {type='button',x=640-100,y=320,key='rotate_right2',r=35,iconSize=60,alpha=0.75}, {type='button',x= 70,y=280,key= 'up',r=45,iconSize=60,alpha=0.375}, {type='button',x= 70,y=430,key= 'down',r=45,iconSize=60,alpha=0.375}, {type='button',x= -5,y=355,key= 'left',r=45,iconSize=60,alpha=0.375}, {type='button',x= 145,y=355,key= 'right',r=45,iconSize=60,alpha=0.375}, {type='button',x=640- -5,y=355,key= 'rotate_left',r=45,iconSize=60,alpha=0.375}, {type='button',x=640-145,y=355,key= 'rotate_left2',r=45,iconSize=60,alpha=0.375}, {type='button',x=640- 70,y=430,key= 'rotate_right',r=45,iconSize=60,alpha=0.375}, {type='button',x=640- 70,y=280,key='rotate_right2',r=45,iconSize=60,alpha=0.375}, {type='button',x=320- 40,y=420,key= 'menu_decide',r=35,iconSize=60,alpha=0.375}, {type='button',x=320+ 40,y=420,key= 'menu_back',r=35,iconSize=60,alpha=0.375}, } end function love.resize(w, h) local scale_factor = math.min(w / 640, h / 480) GLOBAL_TRANSFORM:setTransformation( (w - scale_factor * 640) / 2, (h - scale_factor * 480) / 2, 0, scale_factor ) end function love.draw() love.graphics.replaceTransform(GLOBAL_TRANSFORM) love.graphics.clear() love.graphics.push() SCENE:render() VCTRL.draw() -- -- Grid system -- local grid_width, grid_height = 40, 20 -- love.graphics.replaceTransform(GLOBAL_TRANSFORM) -- love.graphics.setColor(1,1,1,0.5) -- love.graphics.setLineWidth(1) -- -- From 0 to X -- for ix=0,math.floor(640 / grid_width) do -- love.graphics.line(grid_width * ix, 0 , grid_width * ix, 480) -- end -- -- From 0 to Y -- for iy=0,math.floor(480 / grid_height) do -- love.graphics.line(0, grid_height * iy, 640, grid_height * iy) -- end -- drawText( -- "Pressed: "..(LastPressedKey or '[NONE]').." | Released: "..(LastReleasedKey or '[NONE]'), -- 0,0,1000,"left" -- ) love.graphics.pop() end function love.touchpressed(id,x,y) local x,y=GLOBAL_TRANSFORM:inverseTransformPoint(x,y) if not VCTRL.press(x,y,id) then SCENE:onInputPress{type = "touch", x = x, y = y, dx = 0, dy = 0, id = id} end end function love.touchdragged(id,x,y,dx,dy) local x,y=GLOBAL_TRANSFORM:inverseTransformPoint(x,y) if not VCTRL.drag(x,y,id) then SCENE:onInputDrag{type = "touch", x = x, y = y, dx = dx, dy = dy, id = id} end end function love.touchreleased(id,x,y) local x,y=GLOBAL_TRANSFORM:inverseTransformPoint(x,y) if not VCTRL.release(id) then SCENE:onInputRelease{type = "touch", x = x, y = y, dx = 0, dy = 0, id = id} end end function love.keypressed(key, scancode) local input_pressed=nil -- global hotkeys if scancode == "f4" then SETTINGS["fullscreen"] = not SETTINGS["fullscreen"] love.window.setFullscreen(SETTINGS["fullscreen"]) elseif scancode == "f2" and SCENE.title ~= "Input Config" and SCENE.title ~= "Game" then SCENE = InputConfigScene() -- function keys are reserved elseif string.match(scancode, "^f[1-9]$") or string.match(scancode, "^f1[0-2]+$") then return -- escape is reserved for menu_back elseif scancode == "escape" then SCENE:onInputPress{input="menu_back", type="key", key=key, scancode=scancode} -- pass any other key to the scene, with its configured mapping else if SETTINGS.input and SETTINGS.input.keys then input_pressed = SETTINGS.input.keys[scancode] end SCENE:onInputPress{input=input_pressed, type="key", key=key, scancode=scancode} end LastPressedKey = input_pressed or scancode end function love.keyreleased(key, scancode) local input_released = nil -- escape is reserved for menu_back if scancode == "escape" or scancode == 'acback' then SCENE:onInputRelease{input="menu_back", type="key", key=key, scancode=scancode} -- function keys are reserved elseif string.match(scancode, "^f[1-9]$") or string.match(scancode, "^f1[0-2]+$") then return -- handle all other keys; tab is reserved, but the input config scene keeps it from getting configured as a game input, so pass tab to the scene here else if SETTINGS.input and SETTINGS.input.keys then input_released = SETTINGS.input.keys[scancode] end SCENE:onInputRelease{input=input_released, type="key", key=key, scancode=scancode} end LastReleasedKey = input_released or scancode end function love.joystickpressed(joystick, button) local input_pressed = nil if SETTINGS.input and SETTINGS.input.joysticks and SETTINGS.input.joysticks[joystick:getName()] and SETTINGS.input.joysticks[joystick:getName()].buttons then input_pressed = SETTINGS.input.joysticks[joystick:getName()].buttons[button] end SCENE:onInputPress({input=input_pressed, type="joybutton", name=joystick:getName(), button=button}) end function love.joystickreleased(joystick, button) local input_released = nil if SETTINGS.input and SETTINGS.input.joysticks and SETTINGS.input.joysticks[joystick:getName()] and SETTINGS.input.joysticks[joystick:getName()].buttons then input_released = SETTINGS.input.joysticks[joystick:getName()].buttons[button] end SCENE:onInputRelease({input=input_released, type="joybutton", name=joystick:getName(), button=button}) end function love.joystickaxis(joystick, axis, value) local input_pressed = nil local positive_released = nil local negative_released = nil if SETTINGS.input and SETTINGS.input.joysticks and SETTINGS.input.joysticks[joystick:getName()] and SETTINGS.input.joysticks[joystick:getName()].axes and SETTINGS.input.joysticks[joystick:getName()].axes[axis] then if math.abs(value) >= 1 then input_pressed = SETTINGS.input.joysticks[joystick:getName()].axes[axis][value >= 1 and "positive" or "negative"] end positive_released = SETTINGS.input.joysticks[joystick:getName()].axes[axis].positive negative_released = SETTINGS.input.joysticks[joystick:getName()].axes[axis].negative end if math.abs(value) >= 1 then SCENE:onInputPress({input=input_pressed, type="joyaxis", name=joystick:getName(), axis=axis, value=value}) else SCENE:onInputRelease({input=positive_released, type="joyaxis", name=joystick:getName(), axis=axis, value=value}) SCENE:onInputRelease({input=negative_released, type="joyaxis", name=joystick:getName(), axis=axis, value=value}) end end local last_hat_direction = "" local directions = { ["u"] = "up", ["d"] = "down", ["l"] = "left", ["r"] = "right", } function love.joystickhat(joystick, hat, direction) local input_pressed = nil local has_hat = false if SETTINGS.input and SETTINGS.input.joysticks and SETTINGS.input.joysticks[joystick:getName()] and SETTINGS.input.joysticks[joystick:getName()].hats and SETTINGS.input.joysticks[joystick:getName()].hats[hat] then if direction ~= "c" then input_pressed = SETTINGS.input.joysticks[joystick:getName()].hats[hat][direction] end has_hat = true end if input_pressed then for i = 1, #direction do local char = direction:sub(i, i) local _, count = last_hat_direction:gsub(char, char) if count == 0 then SCENE:onInputPress({input=SETTINGS.input.joysticks[joystick:getName()].hats[hat][char], type="joyhat", name=joystick:getName(), hat=hat, direction=char}) end end for i = 1, #last_hat_direction do local char = last_hat_direction:sub(i, i) local _, count = direction:gsub(char, char) if count == 0 then SCENE:onInputRelease({input=SETTINGS.input.joysticks[joystick:getName()].hats[hat][char], type="joyhat", name=joystick:getName(), hat=hat, direction=char}) end end last_hat_direction = direction elseif has_hat then for i, direction in ipairs{"d", "l", "ld", "lu", "r", "rd", "ru", "u"} do SCENE:onInputRelease({input=SETTINGS.input.joysticks[joystick:getName()].hats[hat][direction], type="joyhat", name=joystick:getName(), hat=hat, direction=direction}) end last_hat_direction = "" elseif direction ~= "c" then for i = 1, #direction do local char = direction:sub(i, i) local _, count = last_hat_direction:gsub(char, char) if count == 0 then SCENE:onInputPress({input=directions[char], type="joyhat", name=joystick:getName(), hat=hat, direction=char}) end end for i = 1, #last_hat_direction do local char = last_hat_direction:sub(i, i) local _, count = direction:gsub(char, char) if count == 0 then SCENE:onInputRelease({input=directions[char], type="joyhat", name=joystick:getName(), hat=hat, direction=char}) end end last_hat_direction = direction else for i, direction in ipairs{"d", "l", "ld", "lu", "r", "rd", "ru", "u"} do SCENE:onInputRelease({input=nil, type="joyhat", name=joystick:getName(), hat=hat, direction=direction}) end last_hat_direction = "" end end function love.focus(f) end local TARGET_FPS = 60 function love.run() if love.load then love.load(love.arg.parseGameArguments(arg), arg) end if love.timer then love.timer.step() end local dt = 0 local last_time = love.timer.getTime() local time_accumulator = 0 return function() if love.event then love.event.pump() for name, a,b,c,d,e,f in love.event.poll() do if name == "quit" then if not love.quit or not love.quit() then return a or 0 end end love.handlers[name](a,b,c,d,e,f) end end if SCENE and SCENE.update and love.timer then SCENE:update() local frame_duration = 1.0 / TARGET_FPS if time_accumulator < frame_duration then if love.graphics and love.graphics.isActive() and love.draw then love.graphics.origin() love.graphics.clear(love.graphics.getBackgroundColor()) love.draw() love.graphics.present() end local end_time = last_time + frame_duration local time = love.timer.getTime() while time < end_time do love.timer.sleep(0.001) time = love.timer.getTime() end time_accumulator = time_accumulator + time - last_time end time_accumulator = time_accumulator - frame_duration end last_time = love.timer.getTime() end end local minos = {'R_d', 'O_d', 'Y_d', 'G_d', 'C_d', 'B_d', 'M_d'} local main_bg_grid = {} for x=1, 40 do main_bg_grid[x] = {} for y=1, 30 do main_bg_grid[x][y] = 0 end end local main_bg_cur_pos = {20,6} local main_bg_cur_color = minos[love.math.random(1,7)] local main_bg_cur_mino = 1 local main_bg_draw_frame = 0 local main_bg_last_color = nil function MainBackground() if SETTINGS["music"] and not SOUNDS["bgm_title"]:isPlaying() then SOUNDS["bgm_title"]:setVolume(0.3) SOUNDS["bgm_title"]:play() end local y = 40 if main_bg_draw_frame >= 16 then while y > 1 do for x = 1, 40 do main_bg_grid[x][y] = main_bg_grid[x][y-1] end y = y - 1 end for x=1, 40 do main_bg_grid[x][1] = 0 end main_bg_draw_frame = 0 main_bg_cur_pos[2] = main_bg_cur_pos[2] + 1 end local directions = { {0,-1},{1,0}, {-1,0}} local test_dir = directions[love.math.random(1,3)] main_bg_cur_pos[1] = main_bg_cur_pos[1] + test_dir[1] main_bg_cur_pos[2] = main_bg_cur_pos[2] + test_dir[2] if main_bg_cur_pos[1] > 40 then main_bg_cur_pos[1] = 40 end if main_bg_cur_pos[1] < 1 then main_bg_cur_pos[1] = 1 end if main_bg_cur_pos[2] > 30 then main_bg_cur_pos[2] = 30 end if main_bg_cur_pos[2] < 1 then main_bg_cur_pos[2] = 1 end if main_bg_grid[main_bg_cur_pos[1]][main_bg_cur_pos[2]] == 0 then main_bg_grid[main_bg_cur_pos[1]][main_bg_cur_pos[2]] = main_bg_cur_color main_bg_cur_mino = main_bg_cur_mino + 1 end for x=1,40 do for y=1,30 do if main_bg_grid[x][y] ~= 0 then love.graphics.setColor(1, 1, 1, 0.4) if ((x-1)*48)-560 > 0 and ((x-1)*48)-560 < 640 then love.graphics.draw(BLOCKS["2tie"][main_bg_grid[x][y]], ((x-1)*48)-570, (((y+2)*48)+main_bg_draw_frame*3)-480,0, 3) end love.graphics.setColor(1, 1, 1, 1) end end end for x=1,40 do for y=1,30 do if main_bg_grid[x][y] ~= 0 then love.graphics.setColor(1, 1, 1, 1) love.graphics.draw(BLOCKS["2tie"][main_bg_grid[x][y]], (x-1)*16, ((y-1)*16)+main_bg_draw_frame) end end end for x=1,40 do for y=1,30 do if main_bg_grid[x][y] ~= 0 then love.graphics.setColor(1, 1, 1, 0.6) if ((x-1)*32)-320 > 0 and ((x-1)*32)-320 < 640 then love.graphics.draw(BLOCKS["2tie"][main_bg_grid[x][y]], ((x-1)*32)-320, (((y+1)*32)+main_bg_draw_frame*2)-320,0, 2) end love.graphics.setColor(1, 1, 1, 1) end end end if main_bg_cur_mino == 5 then --if main_bg_cur_pos[2] < 4 then -- main_bg_cur_pos[2] = 4 -- main_bg_cur_pos[1] = love.math.random(4, 36) --end main_bg_cur_pos = {love.math.random(16,24),6} main_bg_last_color = main_bg_cur_color while main_bg_cur_color == main_bg_last_color do main_bg_cur_color = minos[love.math.random(1,7)] end main_bg_cur_mino = 1 end main_bg_placed = false main_bg_draw_frame = main_bg_draw_frame + 1 end