[Z-framework stand alone ready]
This commit is contained in:
17
callback.lua
17
callback.lua
@@ -5,10 +5,6 @@ local int,rnd,max,min=math.floor,math.random,math.max,math.min
|
||||
local abs=math.abs
|
||||
local rem=table.remove
|
||||
|
||||
kb.setKeyRepeat(true)
|
||||
kb.setTextInput(false)
|
||||
ms.setVisible(false)
|
||||
|
||||
local scr=scr
|
||||
local xOy=love.math.newTransform()
|
||||
local mx,my,mouseShow=-20,-20,false
|
||||
@@ -17,7 +13,6 @@ local touchDist=nil
|
||||
joysticks={}
|
||||
|
||||
local devMode
|
||||
players={alive={},human=0}
|
||||
|
||||
local Tmr=require("timer")
|
||||
local Pnt=require("paint")
|
||||
@@ -153,7 +148,7 @@ local function onMode(x,y)
|
||||
local cam=mapCam
|
||||
x=(cam.x1-640+x)/cam.k1
|
||||
y=(cam.y1-360+y)/cam.k1
|
||||
local MM,R=modes,modeRanks
|
||||
local MM,R=Modes,modeRanks
|
||||
for _=1,#MM do
|
||||
if R[_]then
|
||||
local M=MM[_]
|
||||
@@ -199,7 +194,7 @@ function mouseClick.mode(x,y,k)
|
||||
if __ then
|
||||
SFX.play("click")
|
||||
cam.moving=true
|
||||
_=modes[__]
|
||||
_=Modes[__]
|
||||
cam.x=_.x*cam.k+180
|
||||
cam.y=_.y*cam.k
|
||||
cam.sel=__
|
||||
@@ -402,17 +397,17 @@ function mouseDown.setting_sound(x,y,k)
|
||||
VOC.play((t<1.5 or t>15)and"doubt"or rnd()<.8 and"happy"or"egg")
|
||||
sceneTemp.last=Timer()
|
||||
if rnd()<.0626 then
|
||||
for i=1,#modes do
|
||||
local M=modes[i]
|
||||
for i=1,#Modes do
|
||||
local M=Modes[i]
|
||||
for i=1,#M.unlock do
|
||||
local m=M.unlock[i]
|
||||
if not modeRanks[m]then
|
||||
modeRanks[m]=modes[m].score and 0 or 6
|
||||
modeRanks[m]=Modes[m].score and 0 or 6
|
||||
end
|
||||
end
|
||||
end
|
||||
FILE.saveUnlock()
|
||||
TEXT.show("DEVMODE:UNLOCKALL",640,360,50,"stretch",.6)
|
||||
TEXT.show("DEVModes:UNLOCKALL",640,360,50,"stretch",.6)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
2
conf.lua
2
conf.lua
@@ -6,7 +6,7 @@ function love.conf(t)
|
||||
t.gammacorrect=false
|
||||
t.appendidentity=true--search files in source before save directory
|
||||
t.accelerometerjoystick=false--accelerometer=joystick on ios/android
|
||||
t.audio.mixwithsystem=true
|
||||
if t.audio then t.audio.mixwithsystem=true end
|
||||
|
||||
local W=t.window
|
||||
W.title="Techmino "..gameVersion
|
||||
|
||||
70
main.lua
70
main.lua
@@ -2,8 +2,15 @@
|
||||
Techmino is my first "huge project"
|
||||
optimization is welcomed if you also love tetromino game
|
||||
]]
|
||||
|
||||
--Global Setting & Vars
|
||||
package.path="./?.lua;./parts/?.lua;./modules/?.lua"
|
||||
math.randomseed(os.time()*626)
|
||||
--Global vars
|
||||
love.keyboard.setKeyRepeat(true)
|
||||
love.keyboard.setTextInput(false)
|
||||
love.mouse.setVisible(false)
|
||||
|
||||
function NULL()end
|
||||
system=love.system.getOS()
|
||||
game={}
|
||||
mapCam={
|
||||
@@ -22,46 +29,49 @@ mapCam={
|
||||
scr={x=0,y=0,w=0,h=0,rad=0,k=1}--wid,hei,radius,scale K
|
||||
customSel={1,22,1,1,7,3,1,1,8,4,1,1,1}
|
||||
preField={h=20}for i=1,20 do preField[i]={0,0,0,0,0,0,0,0,0,0}end
|
||||
function NULL()end
|
||||
players={alive={},human=0}
|
||||
--blockSkin,blockSkinMini={},{}--redefined in SKIN.change
|
||||
|
||||
--Load modules
|
||||
setFont=require("parts/setfont")
|
||||
color=require("parts/color")
|
||||
blocks=require("parts/mino")
|
||||
SHADER=require("parts/shader")
|
||||
AITemplate=require("parts/AITemplate")
|
||||
freeRow=require("parts/freeRow")
|
||||
tickEvent=require("parts/tickEvent")
|
||||
color= require("color")
|
||||
blocks= require("mino")
|
||||
AITemplate= require("AITemplate")
|
||||
freeRow= require("freeRow")
|
||||
|
||||
require("parts/list")
|
||||
require("toolfunc")
|
||||
require("list")
|
||||
require("gametoolfunc")
|
||||
require("texture")
|
||||
require("default_data")
|
||||
|
||||
SCN=require("scene")
|
||||
VIB=require("parts/vib")
|
||||
SFX=require("parts/sfx")
|
||||
sysFX=require("parts/sysFX")
|
||||
BGM=require("parts/bgm")
|
||||
VOC=require("parts/voice")
|
||||
SKIN=require("parts/skin")
|
||||
LANG=require("parts/languages")
|
||||
FILE=require("parts/file")
|
||||
TEXT=require("parts/text")
|
||||
TASK=require("parts/task")
|
||||
BG=require("parts/bg")
|
||||
IMG=require("parts/img")
|
||||
WIDGET=require("parts/widget")
|
||||
LIGHT=require("parts/light")
|
||||
SKIN= require("skin")
|
||||
PLY= require("player")
|
||||
AIfunc= require("ai")
|
||||
Modes= require("modes")
|
||||
|
||||
require("parts/modes")
|
||||
require("parts/default_data")
|
||||
require("parts/ai")
|
||||
PLY=require("player")
|
||||
widgetList=require("widgetList")
|
||||
--load Z's Framework
|
||||
SHADER= require("shader")
|
||||
VIB= require("vib")
|
||||
SFX= require("sfx")
|
||||
sysFX= require("sysFX")
|
||||
BG= require("bg")
|
||||
BGM= require("bgm")
|
||||
VOC= require("voice")
|
||||
LANG= require("languages")
|
||||
FILE= require("file")
|
||||
TEXT= require("text")
|
||||
TASK= require("task")
|
||||
IMG= require("img")
|
||||
WIDGET= require("widget")
|
||||
Widgets=require("widgetList")
|
||||
LIGHT= require("light")
|
||||
SCN= require("scene")
|
||||
require("callback")
|
||||
|
||||
--load files & settings
|
||||
modeRanks={}for i=1,#Modes do modeRanks[i]=false assert(i==Modes[i].id,"ModeID error:"..i)end
|
||||
modeRanks[1]=0
|
||||
|
||||
local fs=love.filesystem
|
||||
if fs.getInfo("keymap.dat")then fs.remove("keymap.dat")end
|
||||
if fs.getInfo("setting.dat")then fs.remove("setting.dat")end
|
||||
|
||||
@@ -22,7 +22,7 @@ return{
|
||||
getRank=function(P)
|
||||
local L=P.stat.row
|
||||
return
|
||||
L>=2600 and 5 or
|
||||
L>=2000 and 5 or
|
||||
L>=1500 and 4 or
|
||||
L>=1000 and 3 or
|
||||
L>=500 and 2 or
|
||||
|
||||
@@ -27,7 +27,7 @@ return{
|
||||
getRank=function(P)
|
||||
local L=P.stat.pc
|
||||
return
|
||||
L>=25 and 5 or
|
||||
L>=24 and 5 or
|
||||
L>=20 and 4 or
|
||||
L>=16 and 3 or
|
||||
L>=13 and 2 or
|
||||
|
||||
@@ -152,7 +152,7 @@ function Pnt.mode()
|
||||
gc.scale(cam.zoomK)
|
||||
gc.translate(-cam.x1,-cam.y1)
|
||||
gc.scale(cam.k1)
|
||||
local MM=modes
|
||||
local MM=Modes
|
||||
local R=modeRanks
|
||||
local sel=cam.sel
|
||||
setFont(30)
|
||||
|
||||
@@ -192,7 +192,7 @@ local function getScore(field,cb,cy)
|
||||
return score
|
||||
end
|
||||
-------------------------------------------------
|
||||
AI_think={
|
||||
return{
|
||||
["9S"]={
|
||||
function(P,ctrl)
|
||||
local Tfield={}--test field
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
local min=math.min
|
||||
local rem=table.remove
|
||||
|
||||
local function fadeOut(_,id)
|
||||
local src=BGM.list[id]
|
||||
local v=src:getVolume()-.025*setting.bgm*.1
|
||||
src:setVolume(v>0 and v or 0)
|
||||
if v<=0 then
|
||||
src:stop()
|
||||
return true
|
||||
end
|
||||
end
|
||||
local function fadeIn(_,id)
|
||||
local src=BGM.list[id]
|
||||
local v=min(src:getVolume()+.025*setting.bgm*.1,setting.bgm*.1)
|
||||
src:setVolume(v)
|
||||
if v>=setting.bgm*.1 then return true end
|
||||
end
|
||||
|
||||
local BGM={
|
||||
--nowPlay=[str:playing ID]
|
||||
--suspend=[str:pausing ID]
|
||||
@@ -36,12 +53,12 @@ function BGM.play(s)
|
||||
return
|
||||
end
|
||||
if BGM.nowPlay~=s then
|
||||
if BGM.nowPlay then TASK.new(tickEvent.bgmFadeOut,nil,BGM.nowPlay)end
|
||||
TASK.changeCode(tickEvent.bgmFadeIn,tickEvent.bgmFadeOut)
|
||||
if BGM.nowPlay then TASK.new(fadeOut,nil,BGM.nowPlay)end
|
||||
TASK.changeCode(fadeIn,fadeOut)
|
||||
TASK.removeTask_data(s)
|
||||
|
||||
BGM.nowPlay,BGM.suspend=s
|
||||
TASK.new(tickEvent.bgmFadeIn,nil,s)
|
||||
TASK.new(fadeIn,nil,s)
|
||||
BGM.playing=BGM.list[s]
|
||||
BGM.playing:play()
|
||||
end
|
||||
@@ -64,9 +81,9 @@ function BGM.freshVolume()
|
||||
end
|
||||
function BGM.stop()
|
||||
if BGM.nowPlay then
|
||||
TASK.new(tickEvent.bgmFadeOut,nil,BGM.nowPlay)
|
||||
TASK.new(fadeOut,nil,BGM.nowPlay)
|
||||
end
|
||||
TASK.changeCode(tickEvent.bgmFadeIn,tickEvent.bgmFadeOut)
|
||||
TASK.changeCode(fadeIn,fadeOut)
|
||||
BGM.playing,BGM.nowPlay=nil
|
||||
end
|
||||
return BGM
|
||||
304
parts/gametoolfunc.lua
Normal file
304
parts/gametoolfunc.lua
Normal file
@@ -0,0 +1,304 @@
|
||||
local tm,gc=love.timer,love.graphics
|
||||
local kb,data=love.keyboard,love.data
|
||||
local int,abs,rnd=math.floor,math.abs,math.random
|
||||
local max,min=math.max,math.min
|
||||
local sub,find=string.sub,string.find
|
||||
local char,byte=string.char,string.byte
|
||||
local ins,rem=table.insert,table.remove
|
||||
|
||||
function destroyPlayers()
|
||||
for i=#players,1,-1 do
|
||||
local P=players[i]
|
||||
if P.canvas then P.canvas:release()end
|
||||
while P.field[1]do
|
||||
freeRow.discard(rem(P.field))
|
||||
freeRow.discard(rem(P.visTime))
|
||||
end
|
||||
if P.AI_mode=="CC"then
|
||||
BOT.free(P.bot_opt)
|
||||
BOT.free(P.bot_wei)
|
||||
BOT.destroy(P.AI_bot)
|
||||
P.AI_mode=nil
|
||||
end
|
||||
players[i]=nil
|
||||
end
|
||||
for i=#players.alive,1,-1 do
|
||||
players.alive[i]=nil
|
||||
end
|
||||
players.human=0
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
function restoreVirtualKey()
|
||||
for i=1,#VK_org do
|
||||
local B,O=virtualkey[i],VK_org[i]
|
||||
B.ava=O.ava
|
||||
B.x=O.x
|
||||
B.y=O.y
|
||||
B.r=O.r
|
||||
B.isDown=false
|
||||
B.pressTime=0
|
||||
end
|
||||
if not modeEnv.Fkey then
|
||||
virtualkey[9].ava=false
|
||||
end
|
||||
end
|
||||
function copyBoard()
|
||||
local str=""
|
||||
local H=0
|
||||
for y=20,1,-1 do
|
||||
for x=1,10 do
|
||||
if preField[y][x]~=0 then
|
||||
H=y
|
||||
goto L
|
||||
end
|
||||
end
|
||||
end
|
||||
::L::
|
||||
for y=1,H do
|
||||
local S=""
|
||||
local L=preField[y]
|
||||
for x=1,10 do
|
||||
S=S..char(L[x]+1)
|
||||
end
|
||||
str=str..S
|
||||
end
|
||||
love.system.setClipboardText("Techmino sketchpad:"..data.encode("string","base64",data.compress("string","deflate",str)))
|
||||
TEXT.show(text.copySuccess,350,360,40,"appear",.5)
|
||||
end
|
||||
function pasteBoard()
|
||||
local str=love.system.getClipboardText()
|
||||
local fX,fY=1,1--*ptr for Field(r*10+(c-1))
|
||||
local _,Bid
|
||||
local p=find(str,":")--ptr*
|
||||
if p then str=sub(str,p+1)end
|
||||
_,str=pcall(data.decode,"string","base64",str)
|
||||
if not _ then goto ERROR end
|
||||
_,str=pcall(data.decompress,"string","deflate",str)
|
||||
if not _ then goto ERROR end
|
||||
p=1
|
||||
while true do
|
||||
_=byte(str,p)--1byte
|
||||
if not _ then
|
||||
if fX~=1 then goto ERROR
|
||||
else break
|
||||
end
|
||||
end--str end
|
||||
__=_%32-1--block id
|
||||
if __>17 then goto ERROR end--illegal blockid
|
||||
_=int(_/32)--mode id
|
||||
preField[fY][fX]=__
|
||||
if fX<10 then
|
||||
fX=fX+1
|
||||
else
|
||||
if fY==20 then break end
|
||||
fX=1;fY=fY+1
|
||||
end
|
||||
p=p+1
|
||||
end
|
||||
|
||||
for y=fY+1,20 do
|
||||
for x=1,10 do
|
||||
preField[y][x]=0
|
||||
end
|
||||
end
|
||||
do return end
|
||||
::ERROR::TEXT.show(text.dataCorrupted,350,360,35,"flicker",.5)
|
||||
end
|
||||
|
||||
function mergeStat(stat,delta)
|
||||
for k,v in next,delta do
|
||||
if type(v)=="table"then
|
||||
mergeStat(stat[k],v)
|
||||
else
|
||||
stat[k]=stat[k]+v
|
||||
end
|
||||
end
|
||||
end
|
||||
function randomTarget(P)
|
||||
if #players.alive>1 then
|
||||
local R
|
||||
repeat
|
||||
R=players.alive[rnd(#players.alive)]
|
||||
until R~=P
|
||||
return R
|
||||
end
|
||||
end--return a random opponent for P
|
||||
function freshMostDangerous()
|
||||
game.mostDangerous,game.secDangerous=nil
|
||||
local m,m2=0,0
|
||||
for i=1,#players.alive do
|
||||
local h=#players.alive[i].field
|
||||
if h>=m then
|
||||
game.mostDangerous,game.secDangerous=players.alive[i],game.mostDangerous
|
||||
m,m2=h,m
|
||||
elseif h>=m2 then
|
||||
game.secDangerous=players.alive[i]
|
||||
m2=h
|
||||
end
|
||||
end
|
||||
end
|
||||
function freshMostBadge()
|
||||
game.mostBadge,game.secBadge=nil
|
||||
local m,m2=0,0
|
||||
for i=1,#players.alive do
|
||||
local h=players.alive[i].badge
|
||||
if h>=m then
|
||||
game.mostBadge,game.secBadge=players.alive[i],game.mostBadge
|
||||
m,m2=h,m
|
||||
elseif h>=m2 then
|
||||
game.secBadge=players.alive[i]
|
||||
m2=h
|
||||
end
|
||||
end
|
||||
end
|
||||
function royaleLevelup()
|
||||
game.stage=game.stage+1
|
||||
local spd
|
||||
TEXT.show(text.royale_remain(#players.alive),640,200,40,"beat",.3)
|
||||
if game.stage==2 then
|
||||
spd=30
|
||||
elseif game.stage==3 then
|
||||
spd=15
|
||||
game.garbageSpeed=.6
|
||||
if players[1].alive then BGM.play("cruelty")end
|
||||
elseif game.stage==4 then
|
||||
spd=10
|
||||
local _=players.alive
|
||||
for i=1,#_ do
|
||||
_[i].gameEnv.pushSpeed=3
|
||||
end
|
||||
elseif game.stage==5 then
|
||||
spd=5
|
||||
game.garbageSpeed=1
|
||||
elseif game.stage==6 then
|
||||
spd=3
|
||||
if players[1].alive then BGM.play("final")end
|
||||
end
|
||||
for i=1,#players.alive do
|
||||
players.alive[i].gameEnv.drop=spd
|
||||
end
|
||||
if curMode.lv==3 then
|
||||
for i=1,#players.alive do
|
||||
local P=players.alive[i]
|
||||
P.gameEnv.drop=int(P.gameEnv.drop*.3)
|
||||
if P.gameEnv.drop==0 then
|
||||
P.curY=P.y_img
|
||||
P.gameEnv._20G=true
|
||||
if P.AI_mode=="CC"then CC_switch20G(P)end--little cheating,never mind
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function pauseGame()
|
||||
if not SCN.swapping then
|
||||
restartCount=0--Avoid strange darkness
|
||||
if not game.result then
|
||||
game.pauseCount=game.pauseCount+1
|
||||
end
|
||||
for i=1,#players do
|
||||
local l=players[i].keyPressing
|
||||
for j=1,#l do
|
||||
if l[j]then
|
||||
players[i]:releaseKey(j)
|
||||
end
|
||||
end
|
||||
end
|
||||
SCN.swapTo("pause","none")
|
||||
end
|
||||
end
|
||||
function resumeGame()
|
||||
SCN.swapTo("play","none")
|
||||
end
|
||||
function loadGame(M)
|
||||
--rec={}
|
||||
stat.lastPlay=M
|
||||
curMode=Modes[M]
|
||||
local lang=setting.lang
|
||||
drawableText.modeName:set(text.modes[M][1])
|
||||
drawableText.levelName:set(text.modes[M][2])
|
||||
needResetGameData=true
|
||||
SCN.swapTo("play","fade_togame")
|
||||
SFX.play("enter")
|
||||
end
|
||||
function resetPartGameData()
|
||||
game={
|
||||
result=false,
|
||||
pauseTime=0,
|
||||
pauseCount=0,
|
||||
garbageSpeed=1,
|
||||
warnLVL0=0,
|
||||
warnLVL=0,
|
||||
}
|
||||
frame=150-setting.reTime*15
|
||||
destroyPlayers()
|
||||
curMode.load()
|
||||
TEXT.clear()
|
||||
if modeEnv.task then
|
||||
for i=1,#players do
|
||||
players[i].newTask(modeEnv.task)
|
||||
end
|
||||
end
|
||||
if modeEnv.royaleMode then
|
||||
for i=1,#players do
|
||||
players[i]:changeAtk(randomTarget(players[i]))
|
||||
end
|
||||
end
|
||||
BG.set(modeEnv.bg)
|
||||
BGM.play(modeEnv.bgm)
|
||||
if modeEnv.royaleMode then
|
||||
for i=1,#players do
|
||||
players[i]:changeAtk(randomTarget(players[i]))
|
||||
end
|
||||
game.stage=1
|
||||
game.garbageSpeed=.3
|
||||
end
|
||||
restoreVirtualKey()
|
||||
collectgarbage()
|
||||
end
|
||||
function resetGameData()
|
||||
game={
|
||||
result=false,
|
||||
pauseTime=0,--Time paused
|
||||
pauseCount=0,--Pausing count
|
||||
garbageSpeed=1,--garbage timing speed
|
||||
warnLVL0=0,
|
||||
warnLVL=0,
|
||||
}
|
||||
frame=150-setting.reTime*15
|
||||
destroyPlayers()
|
||||
modeEnv=curMode.env
|
||||
curMode.load()--bg/bgm need redefine in custom,so up here
|
||||
if modeEnv.task then
|
||||
for i=1,#players do
|
||||
players[i].newTask(modeEnv.task)
|
||||
end
|
||||
end
|
||||
BG.set(modeEnv.bg)
|
||||
BGM.play(modeEnv.bgm)
|
||||
|
||||
TEXT.clear()
|
||||
FX_badge={}
|
||||
FX_attack={}
|
||||
if modeEnv.royaleMode then
|
||||
for i=1,#players do
|
||||
players[i]:changeAtk(randomTarget(players[i]))
|
||||
end
|
||||
game.stage=1
|
||||
game.garbageSpeed=.3
|
||||
end
|
||||
restoreVirtualKey()
|
||||
stat.game=stat.game+1
|
||||
freeRow.reset(30*#players)
|
||||
SFX.play("ready")
|
||||
collectgarbage()
|
||||
end
|
||||
function gameStart()
|
||||
SFX.play("start")
|
||||
for P=1,#players do
|
||||
P=players[P]
|
||||
P:popNext()
|
||||
P.timing=true
|
||||
P.control=true
|
||||
end
|
||||
end
|
||||
@@ -44,6 +44,10 @@ if setting.lang==1 then
|
||||
"jstris 也很好玩!",
|
||||
"tetr.io 也很好玩!",
|
||||
"nullpomino 也很好玩!",
|
||||
"↑↑↓↓←→←→BABA",
|
||||
"草(日本语)",
|
||||
"dym,永远的神",
|
||||
"iced,永远的神",
|
||||
}
|
||||
elseif setting.lang==2 then
|
||||
L={
|
||||
@@ -90,6 +94,10 @@ elseif setting.lang==2 then
|
||||
"jstris 也很好玩!",
|
||||
"tetr.io 也很好玩!",
|
||||
"nullpomino 也很好玩!",
|
||||
"↑↑↓↓←→←→BABA",
|
||||
"草(日本语)",
|
||||
"dym,永远的神",
|
||||
"iced,永远的神",
|
||||
}
|
||||
elseif setting.lang==3 then
|
||||
L={
|
||||
@@ -137,6 +145,11 @@ elseif setting.lang==3 then
|
||||
"Also try jstris!",
|
||||
"Also try tetr.io!",
|
||||
"Also try nullpomino!",
|
||||
"↑↑↓↓←→←→BABA",
|
||||
"wwwwww",
|
||||
"diaoyoumei so bully",
|
||||
"iced so bully",
|
||||
"diao so bully",
|
||||
}
|
||||
elseif setting.lang==4 then
|
||||
L={'!','@','#','$','%','^','&','*','(',')','-','=','_','+','[',']','{','}','\\','|',';',':','\'','"',',','<','.','>','/','?'}
|
||||
|
||||
@@ -1749,7 +1749,7 @@ function LANG.getLen()
|
||||
end
|
||||
function LANG.set(l)
|
||||
text=langList[l]
|
||||
for S,L in next,widgetList do
|
||||
for S,L in next,Widgets do
|
||||
for N,W in next,L do
|
||||
W.text=text.WidgetText[S][N]
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
modes={
|
||||
return{
|
||||
{"sprint_10", id=1, x=0, y=0, size=35,shape=1,icon="sprint", unlock={2,3}},
|
||||
{"sprint_20", id=2, x=-300, y=0, size=45,shape=1,icon="sprint", unlock={}},
|
||||
{"sprint_40", id=3, x=0, y=-400, size=55,shape=1,icon="sprint", unlock={4,9,71,72,73}},
|
||||
@@ -82,10 +82,4 @@ modes={
|
||||
{"custom_clear", id=71, x=200, y=-350, size=45,shape=3,icon="custom", unlock={}},
|
||||
{"custom_puzzle", id=72, x=200, y=-200, size=45,shape=3,icon="puzzle", unlock={}},
|
||||
{"sprintPenta", id=73, x=-200, y=-200, size=45,shape=3,icon="sprint", unlock={}},
|
||||
}
|
||||
modeRanks={}
|
||||
for i=1,#modes do
|
||||
modeRanks[i]=false
|
||||
assert(i==modes[i].id,"ModeID error:"..i)
|
||||
end
|
||||
modeRanks[1]=0
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
local new=love.graphics.setNewFont
|
||||
local set=love.graphics.setFont
|
||||
local F,cur={}
|
||||
return function(s)
|
||||
local f=F[s]
|
||||
if s~=cur then
|
||||
if f then
|
||||
set(f)
|
||||
else
|
||||
f=new("font.ttf",s)
|
||||
F[s]=f
|
||||
set(f)
|
||||
end
|
||||
cur=s
|
||||
end
|
||||
return f
|
||||
end
|
||||
@@ -1,71 +0,0 @@
|
||||
local min=math.min
|
||||
local mini=love.window.isMinimized
|
||||
local tickEvent={}
|
||||
function tickEvent.finish(P)
|
||||
if SCN.cur~="play"then return true end
|
||||
P.endCounter=P.endCounter+1
|
||||
if P.endCounter>120 then pauseGame()end
|
||||
end
|
||||
function tickEvent.lose(P)
|
||||
P.endCounter=P.endCounter+1
|
||||
if P.endCounter>80 then
|
||||
for i=1,#P.field do
|
||||
for j=1,10 do
|
||||
if P.visTime[i][j]>0 then
|
||||
P.visTime[i][j]=P.visTime[i][j]-1
|
||||
end
|
||||
end
|
||||
end
|
||||
if P.endCounter==120 then
|
||||
for _=#P.field,1,-1 do
|
||||
freeRow.discard(P.field[_])
|
||||
freeRow.discard(P.visTime[_])
|
||||
P.field[_],P.visTime[_]=nil
|
||||
end
|
||||
if #players==1 and SCN.cur=="play"then
|
||||
pauseGame()
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
function tickEvent.throwBadge(A,data)
|
||||
data[2]=data[2]-1
|
||||
if data[2]%4==0 then
|
||||
local S,R=data[1],data[1].lastRecv
|
||||
local x1,y1,x2,y2
|
||||
if S.small then
|
||||
x1,y1=S.centerX,S.centerY
|
||||
else
|
||||
x1,y1=S.x+308*S.size,S.y+450*S.size
|
||||
end
|
||||
if R.small then
|
||||
x2,y2=R.centerX,R.centerY
|
||||
else
|
||||
x2,y2=R.x+66*R.size,R.y+344*R.size
|
||||
end
|
||||
FX_badge[#FX_badge+1]={x1,y1,x2,y2,t=0}
|
||||
--generate badge object
|
||||
|
||||
if not A.ai and data[2]%8==0 then
|
||||
SFX.play("collect")
|
||||
end
|
||||
end
|
||||
if data[2]<=0 then return true end
|
||||
end
|
||||
function tickEvent.bgmFadeOut(_,id)
|
||||
local src=BGM.list[id]
|
||||
local v=src:getVolume()-.025*setting.bgm*.1
|
||||
src:setVolume(v>0 and v or 0)
|
||||
if v<=0 then
|
||||
src:stop()
|
||||
return true
|
||||
end
|
||||
end
|
||||
function tickEvent.bgmFadeIn(_,id)
|
||||
local src=BGM.list[id]
|
||||
local v=min(src:getVolume()+.025*setting.bgm*.1,setting.bgm*.1)
|
||||
src:setVolume(v)
|
||||
if v>=setting.bgm*.1 then return true end
|
||||
end
|
||||
return tickEvent
|
||||
78
player.lua
78
player.lua
@@ -239,7 +239,7 @@ local function Pupdate_alive(P,dt)
|
||||
local C=P.AI_keys
|
||||
P.AI_delay=P.AI_delay-1
|
||||
if not C[1]then
|
||||
P.AI_stage=AI_think[P.AI_mode][P.AI_stage](P,C)
|
||||
P.AI_stage=AIfunc[P.AI_mode][P.AI_stage](P,C)
|
||||
elseif P.AI_delay<=0 then
|
||||
P:pressKey(C[1])P:releaseKey(C[1])
|
||||
rem(C,1)
|
||||
@@ -581,10 +581,12 @@ local function Pdraw_norm(P)
|
||||
gc.setColor(1,1,1,trans)
|
||||
local x=30*(P.curX+P.sc[2]-1)-15
|
||||
gc.draw(IMG.spinCenter,x,600-30*(P.curY+P.sc[1]-1)+15,nil,nil,nil,4,4)
|
||||
gc.translate(0,dy)
|
||||
gc.setColor(1,1,1,.5)
|
||||
gc.draw(IMG.spinCenter,x,600-30*(P.y_img+P.sc[1]-1)+15,nil,nil,nil,4,4)
|
||||
goto E
|
||||
if P.gameEnv.ghost then
|
||||
gc.translate(0,dy)
|
||||
gc.setColor(1,1,1,.5)
|
||||
gc.draw(IMG.spinCenter,x,600-30*(P.y_img+P.sc[1]-1)+15,nil,nil,nil,4,4)
|
||||
goto E
|
||||
end
|
||||
end--Rotate center
|
||||
gc.translate(0,dy)
|
||||
end
|
||||
@@ -1770,6 +1772,60 @@ end
|
||||
--------------------------</Methods>--------------------------
|
||||
|
||||
--------------------------<Events>--------------------------
|
||||
local tick={}
|
||||
function tick.finish(P)
|
||||
if SCN.cur~="play"then return true end
|
||||
P.endCounter=P.endCounter+1
|
||||
if P.endCounter>120 then pauseGame()end
|
||||
end
|
||||
function tick.lose(P)
|
||||
P.endCounter=P.endCounter+1
|
||||
if P.endCounter>80 then
|
||||
for i=1,#P.field do
|
||||
for j=1,10 do
|
||||
if P.visTime[i][j]>0 then
|
||||
P.visTime[i][j]=P.visTime[i][j]-1
|
||||
end
|
||||
end
|
||||
end
|
||||
if P.endCounter==120 then
|
||||
for _=#P.field,1,-1 do
|
||||
freeRow.discard(P.field[_])
|
||||
freeRow.discard(P.visTime[_])
|
||||
P.field[_],P.visTime[_]=nil
|
||||
end
|
||||
if #players==1 and SCN.cur=="play"then
|
||||
pauseGame()
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
function tick.throwBadge(A,data)
|
||||
data[2]=data[2]-1
|
||||
if data[2]%4==0 then
|
||||
local S,R=data[1],data[1].lastRecv
|
||||
local x1,y1,x2,y2
|
||||
if S.small then
|
||||
x1,y1=S.centerX,S.centerY
|
||||
else
|
||||
x1,y1=S.x+308*S.size,S.y+450*S.size
|
||||
end
|
||||
if R.small then
|
||||
x2,y2=R.centerX,R.centerY
|
||||
else
|
||||
x2,y2=R.x+66*R.size,R.y+344*R.size
|
||||
end
|
||||
FX_badge[#FX_badge+1]={x1,y1,x2,y2,t=0}
|
||||
--generate badge object
|
||||
|
||||
if not A.ai and data[2]%8==0 then
|
||||
SFX.play("collect")
|
||||
end
|
||||
end
|
||||
if data[2]<=0 then return true end
|
||||
end
|
||||
|
||||
local function gameOver()
|
||||
FILE.saveData()
|
||||
local M=curMode
|
||||
@@ -1787,7 +1843,7 @@ local function gameOver()
|
||||
for i=1,#M.unlock do
|
||||
local m=M.unlock[i]
|
||||
if not modeRanks[m]then
|
||||
modeRanks[m]=modes[m].score and 0 or 6
|
||||
modeRanks[m]=Modes[m].score and 0 or 6
|
||||
_=true
|
||||
end
|
||||
end
|
||||
@@ -1857,7 +1913,7 @@ function player.win(P,result)
|
||||
if P.human then
|
||||
gameOver()
|
||||
end
|
||||
TASK.new(tickEvent.finish,P)
|
||||
TASK.new(tick.finish,P)
|
||||
end
|
||||
function player.lose(P)
|
||||
if P.life>0 then
|
||||
@@ -1901,7 +1957,7 @@ function player.lose(P)
|
||||
end
|
||||
P.lastRecv=A
|
||||
if P.id==1 or A.id==1 then
|
||||
TASK.new(tickEvent.throwBadge,A,{P,max(3,P.badge)*4})
|
||||
TASK.new(tick.throwBadge,A,{P,max(3,P.badge)*4})
|
||||
end
|
||||
freshMostBadge()
|
||||
end
|
||||
@@ -1934,7 +1990,9 @@ function player.lose(P)
|
||||
end
|
||||
end
|
||||
gameOver()
|
||||
TASK.new(#players>1 and tickEvent.lose or tickEvent.finish,P)
|
||||
TASK.new(#players>1 and tick.lose or tick.finish,P)
|
||||
else
|
||||
TASK.new(tick.lose,P)
|
||||
end
|
||||
if #players.alive==1 then
|
||||
players.alive[1]:win()
|
||||
@@ -2090,6 +2148,7 @@ function player.act.insLeft(P,auto)
|
||||
end
|
||||
if x0~=P.curX then
|
||||
if P.gameEnv.easyFresh or y0~=P.curY then P:freshLockDelay()end
|
||||
P.spinLast=false
|
||||
end
|
||||
if P.gameEnv.shakeFX then
|
||||
P.fieldOff.vx=-P.gameEnv.shakeFX*.5
|
||||
@@ -2112,6 +2171,7 @@ function player.act.insRight(P,auto)
|
||||
end
|
||||
if x0~=P.curX then
|
||||
if P.gameEnv.easyFresh or y0~=P.curY then P:freshLockDelay()end
|
||||
P.spinLast=false
|
||||
end
|
||||
if P.gameEnv.shakeFX then
|
||||
P.fieldOff.vx=P.gameEnv.shakeFX*.5
|
||||
|
||||
@@ -29,7 +29,7 @@ function sceneInit.load()
|
||||
#BGM.list,
|
||||
#SFX.list,
|
||||
IMG.getCount(),
|
||||
#modes,
|
||||
#Modes,
|
||||
1,
|
||||
},
|
||||
skip=false,--if skipping
|
||||
@@ -68,7 +68,7 @@ function sceneInit.mode(org)
|
||||
local cam=mapCam
|
||||
cam.zoomK=org=="main"and 5 or 1
|
||||
if cam.sel then
|
||||
local M=modes[cam.sel]
|
||||
local M=Modes[cam.sel]
|
||||
cam.x,cam.y=M.x*cam.k+180,M.y*cam.k
|
||||
cam.x1,cam.y1=cam.x,cam.y
|
||||
end
|
||||
@@ -246,7 +246,7 @@ function sceneInit.stat()
|
||||
end
|
||||
function sceneInit.history()
|
||||
BG.set("strap")
|
||||
sceneTemp={require("updateLog"),1}--scroll pos
|
||||
sceneTemp={require("parts/updateLog"),1}--scroll pos
|
||||
end
|
||||
function sceneInit.quit()
|
||||
love.timer.sleep(.3)
|
||||
@@ -293,7 +293,7 @@ function SCN.swapUpdate()
|
||||
if S.time==S.mid then
|
||||
SCN.init(S.tar,SCN.cur)
|
||||
SCN.cur=S.tar
|
||||
WIDGET.set(widgetList[S.tar])
|
||||
WIDGET.set(Widgets[S.tar])
|
||||
collectgarbage()
|
||||
--Scene swapped this moment
|
||||
end
|
||||
|
||||
10
timer.lua
10
timer.lua
@@ -18,9 +18,9 @@ function Tmr.load()
|
||||
elseif S.phase==4 then
|
||||
IMG.loadOne(S.cur)
|
||||
elseif S.phase==5 then
|
||||
local m=modes[S.cur]
|
||||
modes[S.cur]=require("modes/"..m[1])
|
||||
local M=modes[S.cur]
|
||||
local m=Modes[S.cur]
|
||||
Modes[S.cur]=require("modes/"..m[1])
|
||||
local M=Modes[S.cur]
|
||||
M.saveFileName,M.id=m[1],m.id
|
||||
M.x,M.y,M.size,M.shape=m.x,m.y,m.size,m.shape
|
||||
M.unlock=m.unlock
|
||||
@@ -105,7 +105,7 @@ function Tmr.mode(dt)
|
||||
cam.keyCtrl=true
|
||||
end
|
||||
local x,y=(cam.x1-180)/cam.k1,cam.y1/cam.k1
|
||||
local MM,R=modes,modeRanks
|
||||
local MM,R=Modes,modeRanks
|
||||
for _=1,#MM do
|
||||
if R[_]then
|
||||
local __
|
||||
@@ -142,7 +142,7 @@ function Tmr.mode(dt)
|
||||
cam.zoomMethod=_=="play"and 1 or _=="mode"and 2
|
||||
if cam.zoomMethod==1 then
|
||||
if cam.sel then
|
||||
local M=modes[cam.sel]
|
||||
local M=Modes[cam.sel]
|
||||
cam.x=cam.x*.8+M.x*cam.k*.2
|
||||
cam.y=cam.y*.8+M.y*cam.k*.2
|
||||
end
|
||||
|
||||
326
toolfunc.lua
326
toolfunc.lua
@@ -1,11 +1,26 @@
|
||||
local tm,gc=love.timer,love.graphics
|
||||
local kb,data=love.keyboard,love.data
|
||||
local int,abs,rnd=math.floor,math.abs,math.random
|
||||
local max,min=math.max,math.min
|
||||
local sub,find=string.sub,string.find
|
||||
local format,char,byte=string.format,string.char,string.byte
|
||||
local ins,rem=table.insert,table.remove
|
||||
local gc=love.graphics
|
||||
|
||||
local fontData=love.filesystem.newFile("font.ttf")
|
||||
local newFont=gc.setNewFont
|
||||
local setNewFont=gc.setFont
|
||||
local fontCache,currentFontSize={}
|
||||
function setFont(s)
|
||||
local f=fontCache[s]
|
||||
if s~=currentFontSize then
|
||||
if f then
|
||||
setNewFont(f)
|
||||
else
|
||||
f=newFont(fontData,s)
|
||||
fontCache[s]=f
|
||||
setNewFont(f)
|
||||
end
|
||||
currentFontSize=s
|
||||
end
|
||||
return f
|
||||
end
|
||||
|
||||
local int=math.floor
|
||||
local format=string.format
|
||||
function toTime(s)
|
||||
if s<60 then
|
||||
return format("%.3fs",s)
|
||||
@@ -24,301 +39,4 @@ function mText(s,x,y)
|
||||
end
|
||||
function mDraw(s,x,y,a,k)
|
||||
gc.draw(s,x,y,a,k,nil,s:getWidth()*.5,s:getHeight()*.5)
|
||||
end
|
||||
function destroyPlayers()
|
||||
for i=#players,1,-1 do
|
||||
local P=players[i]
|
||||
if P.canvas then P.canvas:release()end
|
||||
while P.field[1]do
|
||||
freeRow.discard(rem(P.field))
|
||||
freeRow.discard(rem(P.visTime))
|
||||
end
|
||||
if P.AI_mode=="CC"then
|
||||
BOT.free(P.bot_opt)
|
||||
BOT.free(P.bot_wei)
|
||||
BOT.destroy(P.AI_bot)
|
||||
P.AI_mode=nil
|
||||
end
|
||||
players[i]=nil
|
||||
end
|
||||
for i=#players.alive,1,-1 do
|
||||
players.alive[i]=nil
|
||||
end
|
||||
players.human=0
|
||||
collectgarbage()
|
||||
end
|
||||
--Single-usage funcs
|
||||
|
||||
function restoreVirtualKey()
|
||||
for i=1,#VK_org do
|
||||
local B,O=virtualkey[i],VK_org[i]
|
||||
B.ava=O.ava
|
||||
B.x=O.x
|
||||
B.y=O.y
|
||||
B.r=O.r
|
||||
B.isDown=false
|
||||
B.pressTime=0
|
||||
end
|
||||
if not modeEnv.Fkey then
|
||||
virtualkey[9].ava=false
|
||||
end
|
||||
end
|
||||
function copyBoard()
|
||||
local str=""
|
||||
local H=0
|
||||
for y=20,1,-1 do
|
||||
for x=1,10 do
|
||||
if preField[y][x]~=0 then
|
||||
H=y
|
||||
goto L
|
||||
end
|
||||
end
|
||||
end
|
||||
::L::
|
||||
for y=1,H do
|
||||
local S=""
|
||||
local L=preField[y]
|
||||
for x=1,10 do
|
||||
S=S..char(L[x]+1)
|
||||
end
|
||||
str=str..S
|
||||
end
|
||||
love.system.setClipboardText("Techmino sketchpad:"..data.encode("string","base64",data.compress("string","deflate",str)))
|
||||
TEXT.show(text.copySuccess,350,360,40,"appear",.5)
|
||||
end
|
||||
function pasteBoard()
|
||||
local str=love.system.getClipboardText()
|
||||
local fX,fY=1,1--*ptr for Field(r*10+(c-1))
|
||||
local _,Bid
|
||||
local p=find(str,":")--ptr*
|
||||
if p then str=sub(str,p+1)end
|
||||
_,str=pcall(data.decode,"string","base64",str)
|
||||
if not _ then goto ERROR end
|
||||
_,str=pcall(data.decompress,"string","deflate",str)
|
||||
if not _ then goto ERROR end
|
||||
p=1
|
||||
while true do
|
||||
_=byte(str,p)--1byte
|
||||
if not _ then
|
||||
if fX~=1 then goto ERROR
|
||||
else break
|
||||
end
|
||||
end--str end
|
||||
__=_%32-1--block id
|
||||
if __>17 then goto ERROR end--illegal blockid
|
||||
_=int(_/32)--mode id
|
||||
preField[fY][fX]=__
|
||||
if fX<10 then
|
||||
fX=fX+1
|
||||
else
|
||||
if fY==20 then break end
|
||||
fX=1;fY=fY+1
|
||||
end
|
||||
p=p+1
|
||||
end
|
||||
|
||||
for y=fY+1,20 do
|
||||
for x=1,10 do
|
||||
preField[y][x]=0
|
||||
end
|
||||
end
|
||||
do return end
|
||||
::ERROR::TEXT.show(text.dataCorrupted,350,360,35,"flicker",.5)
|
||||
end
|
||||
|
||||
function mergeStat(stat,delta)
|
||||
for k,v in next,delta do
|
||||
if type(v)=="table"then
|
||||
mergeStat(stat[k],v)
|
||||
else
|
||||
stat[k]=stat[k]+v
|
||||
end
|
||||
end
|
||||
end
|
||||
function randomTarget(P)
|
||||
if #players.alive>1 then
|
||||
local R
|
||||
repeat
|
||||
R=players.alive[rnd(#players.alive)]
|
||||
until R~=P
|
||||
return R
|
||||
end
|
||||
end--return a random opponent for P
|
||||
function freshMostDangerous()
|
||||
game.mostDangerous,game.secDangerous=nil
|
||||
local m,m2=0,0
|
||||
for i=1,#players.alive do
|
||||
local h=#players.alive[i].field
|
||||
if h>=m then
|
||||
game.mostDangerous,game.secDangerous=players.alive[i],game.mostDangerous
|
||||
m,m2=h,m
|
||||
elseif h>=m2 then
|
||||
game.secDangerous=players.alive[i]
|
||||
m2=h
|
||||
end
|
||||
end
|
||||
end
|
||||
function freshMostBadge()
|
||||
game.mostBadge,game.secBadge=nil
|
||||
local m,m2=0,0
|
||||
for i=1,#players.alive do
|
||||
local h=players.alive[i].badge
|
||||
if h>=m then
|
||||
game.mostBadge,game.secBadge=players.alive[i],game.mostBadge
|
||||
m,m2=h,m
|
||||
elseif h>=m2 then
|
||||
game.secBadge=players.alive[i]
|
||||
m2=h
|
||||
end
|
||||
end
|
||||
end
|
||||
function royaleLevelup()
|
||||
game.stage=game.stage+1
|
||||
local spd
|
||||
TEXT.show(text.royale_remain(#players.alive),640,200,40,"beat",.3)
|
||||
if game.stage==2 then
|
||||
spd=30
|
||||
elseif game.stage==3 then
|
||||
spd=15
|
||||
game.garbageSpeed=.6
|
||||
if players[1].alive then BGM.play("cruelty")end
|
||||
elseif game.stage==4 then
|
||||
spd=10
|
||||
local _=players.alive
|
||||
for i=1,#_ do
|
||||
_[i].gameEnv.pushSpeed=3
|
||||
end
|
||||
elseif game.stage==5 then
|
||||
spd=5
|
||||
game.garbageSpeed=1
|
||||
elseif game.stage==6 then
|
||||
spd=3
|
||||
if players[1].alive then BGM.play("final")end
|
||||
end
|
||||
for i=1,#players.alive do
|
||||
players.alive[i].gameEnv.drop=spd
|
||||
end
|
||||
if curMode.lv==3 then
|
||||
for i=1,#players.alive do
|
||||
local P=players.alive[i]
|
||||
P.gameEnv.drop=int(P.gameEnv.drop*.3)
|
||||
if P.gameEnv.drop==0 then
|
||||
P.curY=P.y_img
|
||||
P.gameEnv._20G=true
|
||||
if P.AI_mode=="CC"then CC_switch20G(P)end--little cheating,never mind
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function pauseGame()
|
||||
if not SCN.swapping then
|
||||
restartCount=0--Avoid strange darkness
|
||||
if not game.result then
|
||||
game.pauseCount=game.pauseCount+1
|
||||
end
|
||||
for i=1,#players do
|
||||
local l=players[i].keyPressing
|
||||
for j=1,#l do
|
||||
if l[j]then
|
||||
players[i]:releaseKey(j)
|
||||
end
|
||||
end
|
||||
end
|
||||
SCN.swapTo("pause","none")
|
||||
end
|
||||
end
|
||||
function resumeGame()
|
||||
SCN.swapTo("play","none")
|
||||
end
|
||||
function loadGame(M)
|
||||
--rec={}
|
||||
stat.lastPlay=M
|
||||
curMode=modes[M]
|
||||
local lang=setting.lang
|
||||
drawableText.modeName:set(text.modes[M][1])
|
||||
drawableText.levelName:set(text.modes[M][2])
|
||||
needResetGameData=true
|
||||
SCN.swapTo("play","fade_togame")
|
||||
SFX.play("enter")
|
||||
end
|
||||
function resetPartGameData()
|
||||
game={
|
||||
result=false,
|
||||
pauseTime=0,
|
||||
pauseCount=0,
|
||||
garbageSpeed=1,
|
||||
warnLVL0=0,
|
||||
warnLVL=0,
|
||||
}
|
||||
frame=150-setting.reTime*15
|
||||
destroyPlayers()
|
||||
curMode.load()
|
||||
TEXT.clear()
|
||||
if modeEnv.task then
|
||||
for i=1,#players do
|
||||
TASK.new(modeEnv.task,players[i])
|
||||
end
|
||||
end
|
||||
if modeEnv.royaleMode then
|
||||
for i=1,#players do
|
||||
players[i]:changeAtk(randomTarget(players[i]))
|
||||
end
|
||||
end
|
||||
BG.set(modeEnv.bg)
|
||||
BGM.play(modeEnv.bgm)
|
||||
if modeEnv.royaleMode then
|
||||
for i=1,#players do
|
||||
players[i]:changeAtk(randomTarget(players[i]))
|
||||
end
|
||||
game.stage=1
|
||||
game.garbageSpeed=.3
|
||||
end
|
||||
restoreVirtualKey()
|
||||
collectgarbage()
|
||||
end
|
||||
function resetGameData()
|
||||
game={
|
||||
result=false,
|
||||
pauseTime=0,--Time paused
|
||||
pauseCount=0,--Pausing count
|
||||
garbageSpeed=1,--garbage timing speed
|
||||
warnLVL0=0,
|
||||
warnLVL=0,
|
||||
}
|
||||
frame=150-setting.reTime*15
|
||||
destroyPlayers()
|
||||
modeEnv=curMode.env
|
||||
curMode.load()--bg/bgm need redefine in custom,so up here
|
||||
if modeEnv.task then
|
||||
for i=1,#players do
|
||||
TASK.new(modeEnv.task,players[i])
|
||||
end
|
||||
end
|
||||
BG.set(modeEnv.bg)
|
||||
BGM.play(modeEnv.bgm)
|
||||
|
||||
TEXT.clear()
|
||||
FX_badge={}
|
||||
FX_attack={}
|
||||
if modeEnv.royaleMode then
|
||||
for i=1,#players do
|
||||
players[i]:changeAtk(randomTarget(players[i]))
|
||||
end
|
||||
game.stage=1
|
||||
game.garbageSpeed=.3
|
||||
end
|
||||
restoreVirtualKey()
|
||||
stat.game=stat.game+1
|
||||
freeRow.reset(30*#players)
|
||||
SFX.play("ready")
|
||||
collectgarbage()
|
||||
end
|
||||
function gameStart()
|
||||
SFX.play("start")
|
||||
for P=1,#players do
|
||||
P=players[P]
|
||||
P:popNext()
|
||||
P.timing=true
|
||||
P.control=true
|
||||
end
|
||||
end
|
||||
@@ -7,54 +7,25 @@ local S=[=[
|
||||
Alan
|
||||
幽灵3383
|
||||
靏鸖龘龘
|
||||
込余
|
||||
[rmb10+]:
|
||||
八零哥
|
||||
蕴空之灵
|
||||
gggf127
|
||||
dtg
|
||||
ThTsOd
|
||||
Fireboos
|
||||
金巧
|
||||
10元
|
||||
立斐
|
||||
Deep_Sea
|
||||
时雪
|
||||
yyangdid
|
||||
sfqr
|
||||
心痕
|
||||
Sasoric
|
||||
夏小亚
|
||||
仁参
|
||||
乐↗乐↘
|
||||
喜欢c4w的ztcjoin
|
||||
面包
|
||||
蠢熏
|
||||
潘一栗
|
||||
Lied
|
||||
星街书婉
|
||||
込余
|
||||
祝西
|
||||
829
|
||||
e m*12
|
||||
我永远爱白银诺艾尔(鹏
|
||||
PCX
|
||||
kagura77
|
||||
呆喂
|
||||
GlowingEmbers
|
||||
轩辕辚
|
||||
HimuroAki
|
||||
TCV100
|
||||
tech有养成系统了@7065
|
||||
HAGE KANOBU
|
||||
闪电和拐棍
|
||||
葡萄味的曼妥思
|
||||
世界沃德
|
||||
蓝绿
|
||||
八零哥 蕴空之灵 gggf127 dtg
|
||||
ThTsOd Fireboos 金巧 10元
|
||||
立斐 Deep_Sea 时雪 yyangdid
|
||||
sfqr 心痕 Sasoric 夏小亚
|
||||
仁参 乐↗乐↘ 喜欢c4w的ztcjoin 面包
|
||||
蠢熏 潘一栗 Lied 星街书婉
|
||||
祝西 829 e m*12 我永远爱白银诺艾尔(鹏
|
||||
PCX kagura77 呆喂 GlowingEmbers
|
||||
轩辕辚 HimuroAki TCV100 tech有养成系统了@7065
|
||||
HAGE KANOBU 闪电和拐棍 葡萄味的曼妥思 世界沃德
|
||||
蓝绿 天生的魔法师 saki 琳雨空
|
||||
|
||||
Thanks!!!
|
||||
|
||||
Future outlook:
|
||||
New mode:
|
||||
PUYO
|
||||
game tutorial
|
||||
finesse tutorial
|
||||
game Abbr. test
|
||||
@@ -71,8 +42,9 @@ Future outlook:
|
||||
dig zen
|
||||
sprint_symmetry
|
||||
hidden: sound only
|
||||
reverb mode (often repeat a piece many times)
|
||||
KPP-locked mode
|
||||
reverb (often repeat a piece many times)
|
||||
KPP-locked
|
||||
parkour
|
||||
Other:
|
||||
mod system with:
|
||||
block hidden
|
||||
@@ -86,13 +58,17 @@ Future outlook:
|
||||
15 puzzle
|
||||
mine sweeper
|
||||
2048
|
||||
tank battle
|
||||
time-based-rank for master advanced mode(1:58/2:28/3:03/300P/100P)
|
||||
简易防沉迷系统
|
||||
next SFX
|
||||
full-key control
|
||||
dragging control
|
||||
"next" SFX
|
||||
new layout of player (rectangle so stupid)
|
||||
better drop FX
|
||||
60+ fps supporting
|
||||
in-game document
|
||||
lang setting page
|
||||
dragging control
|
||||
game recording
|
||||
new widgets (joystick etc.)
|
||||
custom sequence(TTT!)
|
||||
@@ -103,14 +79,28 @@ Future outlook:
|
||||
network game
|
||||
new AI: task-Z
|
||||
|
||||
0.8.25: Custom Sequence Update
|
||||
new:
|
||||
--TODO: custom sequence
|
||||
changed:
|
||||
little easier to get S in PC challenge (easy mode)
|
||||
easier to get S in infinite mode
|
||||
code:
|
||||
file sorted
|
||||
fixed:
|
||||
hard move won't deactive "spin"
|
||||
do not clear dead enemies' field
|
||||
show ghost's center when ghost is off
|
||||
|
||||
0.8.24: Bug Fixed
|
||||
new:
|
||||
ready to refuse auto-formating stats. if update from versions too old
|
||||
changed:
|
||||
little changing of pentomini wallkicks
|
||||
little changing of pentomino wallkick list
|
||||
fixed:
|
||||
incorrect color of P/Q
|
||||
rank of petomino may be [custom]
|
||||
|
||||
0.8.23: Details Update
|
||||
new:
|
||||
new hidden BGM: Hay what kind of feeling
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mobileHide=(system=="Android"or system=="iOS")and function()return true end
|
||||
local mobileHide=(system=="Android"or system=="iOS")and function()return true end
|
||||
local function BACK()SCN.back()end
|
||||
local virtualkeySet={
|
||||
{
|
||||
{1, 80, 720-200, 80},--moveLeft
|
||||
@@ -87,7 +88,7 @@ local function setLang(n) return function()LANG.set(n)setting.lang=n end end
|
||||
local newButton,newSwitch,newSlider=WIDGET.new.button,WIDGET.new.switch,WIDGET.new.slider
|
||||
|
||||
local C=color
|
||||
local widgetList={
|
||||
local Widgets={
|
||||
load={},intro={},quit={},
|
||||
main={
|
||||
play= newButton(150,280,200,160,C.lightRed, 55,function()SCN.push()SCN.swapTo("mode")end, nil,"setting"),
|
||||
@@ -103,7 +104,7 @@ local widgetList={
|
||||
draw= newButton(1100, 440,240,90,C.lightYellow, 40,function()SCN.push()SCN.swapTo("draw")end,function()return mapCam.sel~=71 and mapCam.sel~=72 end),
|
||||
custom= newButton(1100, 540,240,90,C.lightGreen, 40,function()SCN.push()SCN.swapTo("custom")end,function()return mapCam.sel~=71 and mapCam.sel~=72 end),
|
||||
start= newButton(1040, 655,180,80,C.lightGrey, 40,function()if mapCam.sel then SCN.push()loadGame(mapCam.sel)end end,function()return not mapCam.sel end),
|
||||
back= newButton(1200, 655,120,80,C.white, 40,SCN.back),
|
||||
back= newButton(1200, 655,120,80,C.white, 40,BACK),
|
||||
--function()SCN.push()SCN.swapTo("custom")end
|
||||
},
|
||||
music={
|
||||
@@ -111,7 +112,7 @@ local widgetList={
|
||||
up= newButton(1100, 200,120,120,C.white,55,pressKey("up")),
|
||||
play= newButton(1100, 340,120,120,C.white,35,pressKey("space"),function()return setting.bgm==0 end),
|
||||
down= newButton(1100, 480,120,120,C.white,55,pressKey("down")),
|
||||
back= newButton(640, 630,230,90, C.white,40,SCN.back),
|
||||
back= newButton(640, 630,230,90, C.white,40,BACK),
|
||||
},
|
||||
custom={
|
||||
up= newButton(1000, 360,100,100,C.white, 45,function()sceneTemp=(sceneTemp-2)%#customID+1 end),
|
||||
@@ -123,7 +124,7 @@ local widgetList={
|
||||
set3= newButton(640, 340,240,75, C.lightYellow, 35,pressKey("3")),
|
||||
set4= newButton(640, 430,240,75, C.lightYellow, 35,pressKey("4")),
|
||||
set5= newButton(640, 520,240,75, C.lightYellow, 35,pressKey("5")),
|
||||
back= newButton(640, 630,180,60, C.white, 35,SCN.back),
|
||||
back= newButton(640, 630,180,60, C.white, 35,BACK),
|
||||
},
|
||||
draw={
|
||||
b1= newButton(500+65*1, 150,58,58,C.red, 30,setPen(1)),--B1
|
||||
@@ -151,7 +152,7 @@ local widgetList={
|
||||
demo= newSwitch(755, 640,30,function()return sceneTemp.demo end,function()sceneTemp.demo=not sceneTemp.demo end),
|
||||
copy= newButton(920, 640,120,120,C.lightRed, 35,copyBoard),
|
||||
paste= newButton(1060, 640,120,120,C.lightBlue, 35,pasteBoard),
|
||||
back= newButton(1200, 640,120,120,C.white, 35,SCN.back),
|
||||
back= newButton(1200, 640,120,120,C.white, 35,BACK),
|
||||
},
|
||||
play={
|
||||
pause= newButton(1235,45,80,80,C.white,25,pauseGame),
|
||||
@@ -167,7 +168,7 @@ local widgetList={
|
||||
setting=newButton(1120,70,240,90,C.lightBlue,35,function()
|
||||
SCN.push()SCN.swapTo("setting_sound")
|
||||
end),
|
||||
quit= newButton(640,600,240,100,C.white,35,SCN.back),
|
||||
quit= newButton(640,600,240,100,C.white,35,BACK),
|
||||
},
|
||||
setting_game={
|
||||
graphic=newButton(200,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_video")end, nil,"sound"),
|
||||
@@ -185,7 +186,7 @@ local widgetList={
|
||||
quickR= newSwitch(1050,340,35, SETval("quickR"), SETrev("quickR"), nil,"swap"),
|
||||
swap= newSwitch(1050,440,19, SETval("swap"), SETrev("swap"), nil,"fine"),
|
||||
fine= newSwitch(1050,540,20, SETval("fine"), SETrev("fine"), nil,"back"),
|
||||
back= newButton(1140,650,200,80,C.white,40,SCN.back, nil,"graphic"),
|
||||
back= newButton(1140,650,200,80,C.white,40,BACK, nil,"graphic"),
|
||||
},
|
||||
setting_video={
|
||||
sound= newButton(200,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_sound")end, nil,"game"),
|
||||
@@ -216,7 +217,7 @@ local widgetList={
|
||||
power= newSwitch(1050,500,35,SETval("powerInfo"),function()
|
||||
setting.powerInfo=not setting.powerInfo
|
||||
end,nil,"back"),
|
||||
back= newButton(1140,650,200,80,C.white,40,SCN.back,nil,"sound"),
|
||||
back= newButton(1140,650,200,80,C.white,40,BACK,nil,"sound"),
|
||||
},
|
||||
setting_sound={
|
||||
game= newButton(200,80,240,80,C.lightCyan,35,function()SCN.swapTo("setting_game")end, nil,"graphic"),
|
||||
@@ -226,7 +227,7 @@ local widgetList={
|
||||
vib= newSlider(180,440,400,5 ,28,function()VIB(2)end, SETval("vib"), SETsto("vib"), nil,"voc"),
|
||||
voc= newSlider(750,440,400,10,32,function()VOC.play("nya")end, SETval("voc"), SETsto("voc"), nil,"stereo"),
|
||||
stereo= newSlider(180,630,400,10,35,function()SFX.play("move",1,-1)SFX.play("lock",1,1)end, SETval("stereo"), SETsto("stereo"),function()return setting.sfx==0 end,"back"),
|
||||
back= newButton(1140,650,200,80,C.white,40,SCN.back,nil,"game"),
|
||||
back= newButton(1140,650,200,80,C.white,40,BACK,nil,"game"),
|
||||
},
|
||||
setting_control={
|
||||
das= newSlider(226,200,910, 26, 30,nil,SETval("das"), SETsto("das"), nil,"arr"),
|
||||
@@ -242,10 +243,10 @@ local widgetList={
|
||||
_.sddas,_.sdarr=0,2
|
||||
_.ihs,_.irs,_.ims=false,false,false
|
||||
end,nil,"back"),
|
||||
back= newButton(1140,650,200,80,C.white,40,SCN.back,nil,"das"),
|
||||
back= newButton(1140,650,200,80,C.white,40,BACK,nil,"das"),
|
||||
},
|
||||
setting_key={
|
||||
back=newButton(1140,650,200,80,C.white,45,SCN.back),
|
||||
back=newButton(1140,650,200,80,C.white,45,BACK),
|
||||
},
|
||||
setting_skin={
|
||||
prev= newButton(700,100,140,100,C.white,50,function()SKIN.prevSet()end),
|
||||
@@ -284,7 +285,7 @@ local widgetList={
|
||||
end
|
||||
SFX.play("hold")
|
||||
end),
|
||||
back= newButton(1140,650,200,80,C.white,40,SCN.back),
|
||||
back= newButton(1140,650,200,80,C.white,40,BACK),
|
||||
},
|
||||
setting_touch={
|
||||
default=newButton(520,80,170,80,C.white,35,function()
|
||||
@@ -310,7 +311,7 @@ local widgetList={
|
||||
SCN.push()
|
||||
SCN.swapTo("setting_touchSwitch")
|
||||
end),
|
||||
back= newButton(760,180,170,80,C.white,40,SCN.back),
|
||||
back= newButton(760,180,170,80,C.white,40,BACK),
|
||||
size= newSlider(450,265,460,14,40,nil,function()
|
||||
return VK_org[sceneTemp.sel].r/10-1
|
||||
end,
|
||||
@@ -354,38 +355,38 @@ local widgetList={
|
||||
SCN.swapTo("setting_trackSetting")
|
||||
end,function()return not setting.VKTrack end),
|
||||
alpha= newSlider(840,540,400,10,40,nil,SETval("VKAlpha"),SETsto("VKAlpha")),
|
||||
back= newButton(1120,620,200,80,C.white,45,SCN.back),
|
||||
back= newButton(1120,620,200,80,C.white,45,BACK),
|
||||
},
|
||||
setting_trackSetting={
|
||||
VKDodge=newSwitch(400,200, 35,SETval("VKDodge"),SETrev("VKDodge")),
|
||||
VKTchW= newSlider(140,310,1000,10,35,nil,SETval("VKTchW"),function(i)setting.VKTchW=i;setting.VKCurW=math.max(setting.VKCurW,i)end),
|
||||
VKCurW= newSlider(140,370,1000,10,35,nil,SETval("VKCurW"),function(i)setting.VKCurW=i;setting.VKTchW=math.min(setting.VKTchW,i)end),
|
||||
back= newButton(1080,600,240,80,C.white,45,SCN.back),
|
||||
back= newButton(1080,600,240,80,C.white,45,BACK),
|
||||
},
|
||||
setting_lang={
|
||||
chi= newButton(160,100,200,120,C.white,45,setLang(1),nil,"chi2"),
|
||||
chi2= newButton(380,100,200,120,C.white,45,setLang(2),nil,"eng"),
|
||||
eng= newButton(600,100,200,120,C.white,45,setLang(3),nil,"str"),
|
||||
str= newButton(820,100,200,120,C.white,45,setLang(4),nil,"back"),
|
||||
back= newButton(640,600,200,80,C.white,40,SCN.back,nil,"chi"),
|
||||
back= newButton(640,600,200,80,C.white,40,BACK,nil,"chi"),
|
||||
},
|
||||
help={
|
||||
staff= newButton(980,500,150,80,C.white,32,function()SCN.push()SCN.swapTo("staff")end,nil,"his"),
|
||||
his= newButton(1160,500,150,80,C.white,32,function()SCN.push()SCN.swapTo("history")end,nil,"qq"),
|
||||
qq= newButton(980,600,150,80,C.white,32,function()love.system.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end,mobileHide,"back"),
|
||||
back= newButton(640,600,200,80,C.white,40,SCN.back,nil,"staff"),
|
||||
back= newButton(640,600,200,80,C.white,40,BACK,nil,"staff"),
|
||||
},
|
||||
staff={
|
||||
back= newButton(1160,630,150,80,C.white,40,SCN.back),
|
||||
back= newButton(1160,630,150,80,C.white,40,BACK),
|
||||
},
|
||||
history={
|
||||
prev= newButton(1155,170,180,180,C.white,65,pressKey("up"),function()return sceneTemp[2]==1 end),
|
||||
next= newButton(1155,400,180,180,C.white,65,pressKey("down"),function()return sceneTemp[2]==#sceneTemp[1]end),
|
||||
back= newButton(1155,600,180,90,C.white,40,SCN.back),
|
||||
back= newButton(1155,600,180,90,C.white,40,BACK),
|
||||
},
|
||||
stat={
|
||||
path= newButton(980,620,250,80,C.white,25,function()love.system.openURL(love.filesystem.getSaveDirectory())end,mobileHide,"back"),
|
||||
back= newButton(640,620,200,80,C.white,40,SCN.back,nil,"path"),
|
||||
back= newButton(640,620,200,80,C.white,40,BACK,nil,"path"),
|
||||
},
|
||||
}
|
||||
mobileHide,SETval,SETsto,SETrev=nil
|
||||
@@ -393,11 +394,11 @@ pressKey,setPen,prevSkin,nextSkin=nil
|
||||
nextDir,VKAdisp,VKAcode,setLang=nil
|
||||
newButton,newSwitch,newSlider=nil
|
||||
|
||||
for _,L in next,widgetList do
|
||||
for _,L in next,Widgets do
|
||||
for _,W in next,L do
|
||||
if W.next then
|
||||
W.next,L[W.next].prev=L[W.next],W
|
||||
end
|
||||
end
|
||||
end
|
||||
return widgetList
|
||||
return Widgets
|
||||
Reference in New Issue
Block a user