Compare commits

..

6 Commits

Author SHA1 Message Date
MrZ_26
fd5fac4e8a 0.7.32α 2020-02-04 19:37:53 +08:00
MrZ_26
1641440886 0.7.31+α 2020-02-04 19:37:41 +08:00
MrZ_26
c14124d00c 0.7.30α 2020-02-04 19:37:25 +08:00
MrZ_26
f261906f1a 0.7.28+α 2020-02-04 19:37:06 +08:00
MrZ_26
48b68a876b 0.7.27+α 2020-02-04 19:36:54 +08:00
MrZ_26
72040f3855 0.7.25α 2020-02-04 19:36:36 +08:00
54 changed files with 5551 additions and 4407 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
SFX/error.ogg Normal file

Binary file not shown.

BIN
SFX/error_long.ogg Normal file

Binary file not shown.

BIN
SFX/welcome.ogg Normal file

Binary file not shown.

39
ai.lua
View File

@@ -66,13 +66,13 @@ function CC_switch20G(P)
BOT.addNext(P.AI_bot,CCblockID[P.next[i].id])
end
CC_updateField(P)
P.hold={bk={{}},id=0,color=0,name=0}P.holded=false
P.hd={bk={{}},id=0,color=0,name=0}P.holded=false
P.cur=rem(P.next,1)
P.sc,P.dir=scs[P.cur.id],0
P.r,P.c=#P.cur.bk,#P.cur.bk[1]
P.curX,P.curY=blockPos[P.cur.id],21+ceil(P.fieldBeneath/30)-P.r+min(int(#P.field*.2),2)
P.freshNext()
P:freshNext()
BOT.addNext(P.AI_bot,CCblockID[P.next[P.AIdata.next].id])
collectgarbage()
end
@@ -119,9 +119,8 @@ local function ifoverlapAI(f,bk,x,y)
end end
end
local function resetField(f0,f,start)
::L::if f[start]then
while f[start]do
removeRow(f,start)
goto L
end
for i=start,#f0 do
f[i]=getNewRow(0)
@@ -145,12 +144,11 @@ local function getScore(field,cb,cy)
clear=clear+1
::L::
end
if #field==0 then return 9e99 end--PC best
if #field==0 then return 1e99 end--PC best
for x=1,10 do
local h=#field
::L::if field[h][x]==0 and h>1 then
while field[h][x]==0 and h>1 do
h=h-1
goto L
end
height[x]=h
if x>3 and x<8 and h>highest then highest=h end
@@ -188,7 +186,7 @@ end
-------------------------------------------------
AI_think={
["9S"]={
function(ctrl)
function(P,ctrl)
local Tfield={}--test field
local field_org=P.field
for i=1,#field_org do
@@ -197,16 +195,15 @@ AI_think={
Tfield[i][j]=field_org[i][j]
end
end
local best={x=1,dir=0,hold=false,score=-9e99}
local best={x=1,dir=0,hold=false,score=-1e99}
for ifhold=0,P.gameEnv.hold and 1 or 0 do
local bn=ifhold==0 and P.cur.id or P.hold.id>0 and P.hold.id or P.next[1].id
local bn=ifhold==0 and P.cur.id or P.hd.id>0 and P.hd.id or P.next[1].id
for dir=0,dirCount[bn] do--each dir
local cb=blocks[bn][dir]
for cx=1,11-#cb[1]do--each pos
local cy=#Tfield+1
::L::if not ifoverlapAI(Tfield,cb,cx,cy-1)then
while not ifoverlapAI(Tfield,cb,cx,cy-1)do
cy=cy-1
goto L
end--move to bottom
for i=1,#cb do
local y=cy+i-1
@@ -244,26 +241,26 @@ AI_think={
ctrl[p]=6
return 2
end,
function()
function(P)
P.AI_delay=P.AI_delay0
if Timer()-P.modeData.point>P.modeData.event then
P.modeData.point=Timer()
P.modeData.event=P.AI_delay0+rnd(2,10)
changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3)
P:changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3)
end
return 1
end,
},
["CC"]={
function()
function(P)
if P.AI_needFresh then
CC_updateField(P)
P.AI_needFresh=false
end
BOT.think(P.AI_bot)
return 2
end,
function(ctrl)
end,--start thinking
function(P,ctrl)
if BOT.ifDead(P.AI_bot)then ins(ctrl,6)return 3 end
local success,hold,move=BOT.getMove(P.AI_bot)
if success then
@@ -281,15 +278,15 @@ AI_think={
else
return 2--stay this stage
end
end,
function()
end,--poll keys
function(P)
P.AI_delay=P.AI_delay0
if Timer()-P.modeData.point>P.modeData.event then
P.modeData.point=Timer()
P.modeData.event=P.AI_delay0+rnd(2,10)
changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3)
P:changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3)
end
return 1
end,
end,--check if time to change target
},
}--AI think stage

View File

@@ -2,21 +2,8 @@ local gc=love.graphics
local rem=table.remove
local format=string.format
Task={}
function Task:update()
if(not self.P or self.P and scene=="play")and self:code(self.P,self.data)then
local e=#Task
for i=1,e do
if Task[i]==self then
Task[e],Task[i]=nil,Task[e]
return
end
end
end
end
function newTask(code,P,data)
Task[#Task+1]={
update=Task.update,
code=code,
P=P,
data=data,
@@ -44,12 +31,7 @@ function clearTask(opt)
end
end
local a={a=1,b=2}
local x,y=pairs(a)
assert(x==next)
assert(y==a)
--java王宇翔
local button,switch,slider={type="button"},{type="switch"},{type="slider"}--WIDGET OBJECT LIB
local button={type="button"}
function newButton(x,y,w,h,color,font,code,hide,N)
local _={
x=x-w*.5,y=y-h*.5,
@@ -61,7 +43,7 @@ function newButton(x,y,w,h,color,font,code,hide,N)
next=N,
}for k,v in next,button do _[k]=v end return _
end
function button:ifAbove(x,y)
function button:isAbove(x,y)
return x>self.x and x<self.x+self.w and y>self.y and y<self.y+self.h
end
function button:FX()
@@ -88,9 +70,10 @@ function button:draw()
end
end
function button:getInfo()
print(format("x=%d,y=%d,w=%d,h=%d,font=%d",self.x,self.y,self.w,self.h,self.font))
print(format("x=%d,y=%d,w=%d,h=%d,font=%d",self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font))
end
local switch={type="switch"}
function newSwitch(x,y,font,disp,code,hide,N)
local _={
x=x,y=y,font=font,
@@ -100,7 +83,7 @@ function newSwitch(x,y,font,disp,code,hide,N)
next=N,
}for k,v in next,switch do _[k]=v end return _
end
function switch:ifAbove(x,y)
function switch:isAbove(x,y)
return x>self.x and x<self.x+100 and y>self.y-20 and y<self.y+20
end
function switch:FX()
@@ -125,7 +108,6 @@ function switch:draw()
--frame
local t=self.text
if t then
if type(t)=="function"then t=t()end
gc.setColor(1,1,1)
setFont(self.font)
gc.printf(t,x-412,y+20-self.font*.7,400,"right")
@@ -135,6 +117,7 @@ function switch:getInfo()
print(format("x=%d,y=%d,font=%d",self.x,self.y,self.font))
end
local slider={type="slider"}
function newSlider(x,y,w,unit,font,change,disp,code,hide,N)
local _={
x=x,y=y,
@@ -147,7 +130,7 @@ function newSlider(x,y,w,unit,font,change,disp,code,hide,N)
next=N,
}for k,v in next,slider do _[k]=v end return _
end
function slider:ifAbove(x,y)
function slider:isAbove(x,y)
return x>self.x-10 and x<self.x+self.w+10 and y>self.y-20 and y<self.y+20
end
function slider:FX(pos)

View File

@@ -1,4 +1,5 @@
gameVersion="Alpha V0.7.24"
math.randomseed(os.time())
gameVersion="Alpha V0.7.32"
function love.conf(t)
t.identity="Techmino"--Save directory name
t.version="11.1"
@@ -9,7 +10,12 @@ function love.conf(t)
t.audio.mixwithsystem=true--Switch on to keep sysBGM
local W=t.window
W.title="Techmino "..gameVersion
if math.random()>.26 then
W.title="Techmino "..gameVersion
else
math.randomseed(tonumber(os.date("%Y%j")))
W.title="Your lucky number today:"..math.random(100,626)
end
W.icon="/image/icon.png"
W.width,W.height=1280,720
W.minwidth,W.minheight=640,360
@@ -17,7 +23,7 @@ function love.conf(t)
W.resizable=1
W.fullscreentype="desktop"--"exclusive"
W.fullscreen=X
W.vsync=X--0→∞fps
W.vsync=0--0→∞fps
W.msaa=X--The number of samples to use with multi-sampled antialiasing (number)
W.depth=X--Bits per sample in the depth buffer
W.stencil=1--The number of bits per sample in the stencil buffer

File diff suppressed because it is too large Load Diff

97
default_data.lua Normal file
View File

@@ -0,0 +1,97 @@
setting={
das=10,arr=2,
sddas=0,sdarr=2,
quickR=true,swap=true,
fine=false,
--game
ghost=true,center=true,
smo=true,grid=false,
dropFX=3,
shakeFX=3,
atkFX=3,
frameMul=100,
--
fullscreen=false,
bg=true,
bgblock=true,
lang=1,
skin=1,
--graphic
sfx=10,bgm=7,
vib=3,voc=0,
stereo=6,
--sound
keyMap={
{"left","right","x","z","c","up","down","space","tab","r"},
{},{},{},{},{},{},{},
--keyboard
{"dpleft","dpright","a","b","y","dpup","dpdown","rightshoulder","x","leftshoulder"},
{},{},{},{},{},{},{},
--joystick
},
VKSwitch=true,
VKTrack=true,--If tracked
VKDodge=false,--If repel
VKTchW=3,--Touch Weight
VKCurW=4,--CurPos Weight
VKIcon=true,
VKAlpha=3,
--control
}
local L=setting.keyMap
for i=1,#L do
for j=1,20 do
if not L[i][j]then
L[i][j]=""
end
end
end
stat={
run=0,game=0,time=0,
extraPiece=0,extraRate=0,
key=0,rotate=0,hold=0,piece=0,row=0,
atk=0,send=0,recv=0,pend=0,
clear_1=0,clear_2=0,clear_3=0,clear_4=0,
spin_0=0,spin_1=0,spin_2=0,spin_3=0,
b2b=0,b3b=0,pc=0,score=0,
}
--Things related to virtualkey
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
end
end
local O,_=true,false
VK_org={--Original set,for restore VK' position
{ava=O,x=80, y=720-200, r=80},--moveLeft
{ava=O,x=320, y=720-200, r=80},--moveRight
{ava=O,x=1280-80, y=720-200, r=80},--rotRight
{ava=O,x=1280-200, y=720-80, r=80},--rotLeft
{ava=O,x=1280-200, y=720-320, r=80},--rotFlip
{ava=O,x=200, y=720-320, r=80},--hardDrop
{ava=O,x=200, y=720-80, r=80},--softDrop
{ava=O,x=1280-320, y=720-200, r=80},--hold
{ava=O,x=1280-80, y=280, r=80},--func
{ava=O,x=80, y=280, r=80},--restart
{ava=_,x=100, y=50, r=80},--insLeft
{ava=_,x=200, y=50, r=80},--insRight
{ava=_,x=300, y=50, r=80},--insDown
{ava=_,x=400, y=50, r=80},--down1
{ava=_,x=500, y=50, r=80},--down4
{ava=_,x=600, y=50, r=80},--down10
{ava=_,x=700, y=50, r=80},--dropLeft
{ava=_,x=800, y=50, r=80},--dropRight
{ava=_,x=900, y=50, r=80},--addToLeft
{ava=_,x=1000, y=50, r=80},--addToRight
}
virtualkey={}
for i=1,#VK_org do
virtualkey[i]={}
end

89
document.txt Normal file
View File

@@ -0,0 +1,89 @@
游戏方法:
控制系统提供的一个个方块,每填满场地的一行就会将其消除,根据消除方式会给对手攻击(如果有对手的话)
完成当前游戏模式中的目标或者是活到最后即算胜利.
旋转系统:
使用Techmino专属旋转系统,细节不赘述
spin判定:
结合了不可移动判定和三角判定,是否为mini也与这二者有关,细节不赘述
攻击系统:
消1/2/3/4攻击0/1/2/4
spin1/2/3攻击2/4/6,若mini则减半
b2b:增加1~2(tetris)/1~3(spin)攻击
b3b:满b2b效果+1额外抵挡
PC:其它攻击与6~8(本局内递增)取高+2额外抵挡
连击:0,0,1,1,2,2,3,3,4,4,3……
back to back(B2B)点数说明:
B2B点数的范围在0~1200
在40及以上特殊消除时B2B,在1000以上特殊消除时B3B,1200封顶
消四+100
空spin加20,不超过1000
spin1~3+50/100/180 (mini*.5)
普通消除-250
1000以上空放一块-40(不减到低于1000)
攻击延迟:
消2/3的攻击生效最快,消四其次,spin攻击生效较慢,高连击生效最慢
b2b或者b3b增加攻击力的同时也会减缓一点生效速度,mini大幅减缓生效速度
抵消逻辑:
发动攻击时,若缓冲条有攻击则先用额外抵挡再用攻击力1:1抵消最先受到的攻击
没有用上的额外抵挡会被丢弃,最后剩下的攻击力会发送给对手
模式说明:
竞速:
用你最快的速度消除40行(据难度而定)吧!
马拉松:
根据总消行数,速度会逐渐加快,消除两百行吧!(easy和hard就是normal开始和结束的速度,消除200行不加速)
大师:
马拉松进化版,如果觉得马拉松太简单了久玩这个吧,每一个难度都是一层境界,L难度和U难度攒到500点数通关,final难度为上级者专属游戏模式,不建议游玩.
经典:
使用低速控制设置在高速下落时尽可能消除更多的行,没有通关目标.(到90有"彩蛋")
禅:
闲得无聊,只是想单纯地打打块地时候可以玩此模式,无重力消除200行.
无尽:
无尽模式,边上会显示玩家的消行数和攻击效率,适合科研(术语).
单挑:
和一个电脑玩家单挑,带加号的和最后一个模式是超强机器人(仅限Windows平台),试试你能稳定打败多难的对手吧!
回合制:
玩法同单挑模式,只不过只有当一个人放下一个方块后另一个人才能放下一块.
仅TSD:
这个模式中,玩家必须用TSD(T spin double)的方式消除,否则直接判负,你能连续打出多少个TSD呢?
隐形:
根据不同难度,场地内(甚至当前方块)会隐形,看看你能活多久吧!(GM难度为类似TGM3的GM Roll,用于上级者练习)
挖掘:
每隔一定时间,系统会向场地的低端添加一行垃圾行,间隔会随着波数增加而越来越短,你能顶住几波呢?
生存:
每隔一定时间,系统会向玩家的垃圾缓冲槽中添加垃圾行,释放速度和间隔会随着波数增加而越来越短,玩家可以将其抵消也可以让其释放,尽可能活更久的时间.
防守:
系统会向玩家的垃圾缓冲槽中添加难消除的垃圾行,释放速度和间隔会随着波数增加而越来越短,玩家要尽量抵消他们来让自己存活更久.
进攻:
当玩家的攻击缓冲槽空时,系统会向玩家的垃圾缓冲槽中添加大量的垃圾行(高难度下后期甚至会远超过20),释放速度和间隔都会随着波数增加而越来越短,垃圾上涨速度也会提升.赶紧在其释放之前将攻击抵消到不会一下致命的量!
科研:
玩家只被允许做特殊消除(spin/全消/消四),在带+的难度中不允许消四,U难度下玩家甚至只被允许每一个方块都使用最简操作控制,任何违反规则的行为都会判负.
C4W练习:(或者说是4w练习)
系统直接提供给玩家"留4列"的场地,玩家可以自由练习4w消除,该技巧在某些时候实战很有用.(需要学会spin,否则意义不是很大)
全清训练:
系统会连续给玩家提供"标准开局PC套路"的场地和四个方块(不允许使用hold),玩家需要一直完成PC,否则判负.
全清挑战:
在消除一百行的限制内,你能全清几次?
49人混战:
许多玩家同时进行一局游戏其它的是AI,不是真人).随着玩家数量的减少,方块下落/垃圾生效速度/垃圾升起速度都会增加.淘汰其它玩家后可以获得一个徽章和该玩家持有的徽章,增强自己的攻击力.
玩家可选四个攻击模式:
1.随机:每次攻击后10%随机挑选一个玩家锁定
2.最多徽章:攻击后或者锁定玩家死亡时锁定徽章最多的玩家
3.最高:攻击后或者锁定玩家死亡时锁定场地最高的玩家(每秒刷新)
4.反击:攻击所有锁定自己的玩家AOE,若无则伏击随机玩家
坚持到最后的玩家就是胜利者.
99人混战:
同49人混战,只是增加到了99名玩家,难度系数也有调整,对设备的要求也较高.
干旱:
系统提供的方块序列变得奇怪了!你能消除100行不死吗,或者,多快?
多人:
使用键盘或者多个手柄(也许?)
自定义:
玩家可以自由调整下落速度等等几乎大多数设置(不包括上述各种游戏模式的特殊效果),也可以画一个场地去消除或者是作为提示模板来玩方块拼图.在拼图模式下,按功能键切换是否显示提示模板.其中打"X"的格子不允许有方块,空的格子可以是任何状态,玩家能获得的七种普通方块必须完全符合,垃圾行方块的为止只要有方块就可以,但是不能是空气,玩家拼出自己画的图后就会判定胜利.

BIN
font.ttf

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 40 KiB

BIN
image/virtualkey.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

View File

@@ -1,4 +1,13 @@
local BK="返回"
local actName={
"左移:","右移:",
"顺时针旋转:","逆时针旋转:","180°旋转:",
"硬降:","软降:",
"暂存:","功能键:",
"重新开始:",
"左瞬移:","右瞬移:","软降到底:","软降一格:","软降四格:","软降十格:",
"落在最左:","落在最右:","列在最左:","列在最右:",
}
return{
atkModeName={"随机","徽章","击杀","反击"},
royale_remain=function(n)return"剩余 "..n.." 名玩家"end,
@@ -61,11 +70,17 @@ return{
snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"},
keyboard="键盘",joystick="手柄",
space="空格",enter="回车",
setting2Help="方向键选择/翻页,回车修改,esc返回",
ctrlSetHelp="方向键选择/翻页,回车修改,esc返回",
setting_game="游戏设置",
setting_graphic="画面设置",
setting_sound="声音设置",
musicRoom="音乐室",
nowPlaying="正在播放:",
VKTchW="触摸点权重",
VKOrgW="原始点权重",
VKCurW="当前点权重",
actName={"左移:","右移:","顺时针旋转:","逆时针旋转:","180°旋转","硬降:","软降:","暂存:","功能键:","重新开始:","左瞬移:","右瞬移:","软降到底:"},
actName=actName,
modeName={
[0]="自定义",
"竞速","马拉松","大师","经典","","无尽","单挑","回合制","仅TSD","隐形",
@@ -100,17 +115,15 @@ return{
load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",},
tips={
"不是动画,真的在加载!",
"整个游戏都是MrZ完成的!",
"大满贯10连击消四全清!",
"<方块研究所>有一个Nspire-CX版本!",
"B2B2B???",
"B2B2B2B存在吗?",
"MEGACMB!",
"ALLSPIN!",
"O型回旋三清?",
"只用一个输入设备就可以游玩了",
"O spin triple!",
"Miya:喵!",
"225238922,哔哩哔哩 干杯~",
"225238922 哔哩哔哩 干杯~",
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
"合群了就会消失,但是消失不代表没有意义",
"学会使用两个旋转键,三个更好",
@@ -125,9 +138,12 @@ return{
"2.7182818284590452353",
"Let-The-Bass-Kick!",
"使用love2d引擎制作",
"哪里不舒服的话先看看设置有没有你想要",
"有疑问?先看设置有没有你想要的",
"有建议的话可以把信息反馈给作者~",
"本游戏不叫铁壳米诺",
"不要按F8",
"秘密代码:626",
"CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
},
stat={
"游戏运行次数:",
@@ -147,6 +163,8 @@ return{
"B2B数:",
"PC数:",
"效率:",
"多余操作:",
"最简操作率:",
},
help={
"好像也没啥好帮助的吧?就当是关于了",
@@ -157,15 +175,24 @@ return{
"使用LOVE2D引擎",
"作者:MrZ 邮箱:1046101471@qq.com",
"程序:MrZ 美术:MrZ 音乐:MrZ 音效:MrZ 语音:Miya",
"使用工具:VScode,GFIE,Beepbox,Goldwave,Cold_Clear",
"特别感谢:Farter,Flyz,196,Teatube,T830,[所有测试人员]和 你!",
"错误或者建议请附带相关信息发送到作者邮箱~",
},
used=[[
使用工具:
Beepbox
GFIE
Goldwave
使用库:
Cold_Clear[MinusKelvin]
simple-love-lights[dylhunn]
]],
support="支持作者",
group="官方QQ群",
warning="禁 止 私 自 传 播",
WidgetText={
main={
lang="文-Lang",
qplay="快速开始",
play="开始",
setting="设置",
@@ -198,11 +225,11 @@ return{
start1="消除开始",
start2="拼图开始",
draw="画图(D)",
set1="40行",
set2="1v1",
set3="无尽",
set4="隐形",
set5="极限",
set1="40行(1)",
set2="1v1(2)",
set3="无尽(3)",
set4="隐形(4)",
set5="极限(5)",
back=BK,
},
draw={
@@ -229,27 +256,26 @@ return{
pause={
resume= "继续",
restart="重新开始",
setting="设置",
quit= "退出",
},
setting={
game= "游戏设置",
graphic="画面设置",
sound= "声音设置",
ctrl= "控制设置",
touch= "触屏设置",
lang= function()return langName[setting.lang]end,
back= "保存&返回",
},
setting_game={
graphic="←画面设置",
sound="声音设置→",
dasD="-",dasU="+",
arrD="-",arrU="+",
sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+",
holdR="长按重新开始",
quickR="快速重新开始",
swap="组合键切换攻击模式",
fine="极简操作提示音",
ctrl="键位设置",
touch="触屏设置",
back=BK,
},
setting_graphic={
sound="←声音设置",
game="游戏设置→",
ghost="阴影",
grid="网格",
center="旋转中心",
@@ -265,22 +291,41 @@ return{
back=BK,
},
setting_sound={
game="←游戏设置",
graphic="画面设置→",
sfx="音效",
bgm="音乐",
vib="震动",
voc="语音",
back=BK,
},
setting_control={
setting_key={
back=BK,
},
setting_touch={
hide=function()return setting.virtualkeySwitch and"隐藏虚拟按键"or"显示虚拟按键"end,
hide="显示虚拟按键",
track="按键自动跟踪",
tkset="跟踪设置",
default="默认组合",
snap=function()return text.snapLevelName[snapLevel]end,
alpha=function()return setting.virtualkeyAlpha.."0%"end,
alpha=function()return setting.VKAlpha.."0%"end,
icon="图标",
size="大小",
toggle="开关",
back=BK,
},
setting_touchSwitch={
b1= actName[1],b2=actName[2],b3=actName[3],b4=actName[4],
b5= actName[5],b6=actName[6],b7=actName[7],b8=actName[8],
b9= actName[9],b10=actName[10],b11=actName[11],b12=actName[12],
b13=actName[13],b14=actName[14],b15=actName[15],b16=actName[16],
b17=actName[17],b18=actName[18],b19=actName[19],b20=actName[20],
norm="标准",
pro="专业",
back=BK,
},
setting_trackSetting={
VKDodge="自动避让",
back=BK,
},
help={

View File

@@ -1,4 +1,13 @@
local BK="返回"
local actName={
"左移:","右移:",
"顺时针旋转:","逆时针旋转:","180°旋转:",
"硬降:","软降:",
"暂存:","功能键:",
"重新开始:",
"左瞬移:","右瞬移:","软降到底:","软降一格:","软降四格:","软降十格:",
"落在最左:","落在最右:","列在最左:","列在最右:",
}
return{
atkModeName={"随机","徽章","击杀","反击"},
royale_remain=function(n)return"剩余 "..n.." 名玩家"end,
@@ -61,11 +70,17 @@ return{
snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"},
keyboard="键盘",joystick="手柄",
space="空格",enter="回车",
setting2Help="方向键选择/翻页,回车修改,esc返回",
ctrlSetHelp="方向键选择/翻页,回车修改,esc返回",
setting_game="游戏设置",
setting_graphic="画面设置",
setting_sound="声音设置",
musicRoom="音乐室",
nowPlaying="正在播放:",
VKTchW="触摸点权重",
VKOrgW="原始点权重",
VKCurW="当前点权重",
actName={"左移:","右移:","顺时针旋转:","逆时针旋转:","180°旋转","硬降:","软降:","暂存:","功能键:","重新开始:","左瞬移:","右瞬移:","软降到底:"},
actName=actName,
modeName={
[0]="自定义",
"竞速","马拉松","大师","经典","","无尽","单挑","回合制","仅TSD","隐形",
@@ -100,17 +115,15 @@ return{
load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",},
tips={
"不是动画,真的在加载!",
"整个游戏都是MrZ完成的!",
"大满贯10连击消四全清!",
"<方块研究所>有一个Nspire-CX版本!",
"B2B2B???",
"B2B2B2B存在吗?",
"MEGACMB!",
"ALLSPIN!",
"O型回旋三清?",
"只用一个输入设备就可以游玩了",
"O型回旋三清!",
"Miya:喵!",
"225238922,哔哩哔哩 干杯~",
"225238922 哔哩哔哩 干杯~",
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
"合群了就会消失,但是消失不代表没有意义",
"学会使用两个旋转键,三个更好",
@@ -125,9 +138,12 @@ return{
"2.7182818284590452353",
"Let-The-Bass-Kick!",
"使用love2d引擎制作",
"哪里不舒服的话先看看设置有没有你想要",
"有疑问?先看设置有没有你想要的",
"有建议的话可以把信息反馈给作者~",
"郑重声明本游戏不叫[铁壳米诺]",
"不要按F8",
"秘密代码:626",
"CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
},
stat={
"游戏运行次数:",
@@ -147,6 +163,8 @@ return{
"满贯数:",
"全清数:",
"效率:",
"多余操作:",
"最简操作率:",
},
help={
"好像也没啥好帮助的吧?就当是关于了",
@@ -157,15 +175,24 @@ return{
"使用LOVE2D引擎",
"作者:MrZ 邮箱:1046101471@qq.com",
"程序:MrZ 美术:MrZ 音乐:MrZ 音效:MrZ 语音:Miya",
"使用工具:VScode,GFIE,Beepbox,Goldwave,Cold_Clear",
"特别感谢:Farter,Flyz,196,Teatube,T830,[所有测试人员]和 你!",
"错误或者建议请附带相关信息发送到作者邮箱~",
},
used=[[
使用工具:
Beepbox
GFIE
Goldwave
使用库:
Cold_Clear[MinusKelvin]
simple-love-lights[dylhunn]
]],
support="支持作者",
group="官方QQ群",
warning="禁 止 私 自 传 播",
WidgetText={
main={
lang="文-Lang",
qplay="快速开始",
play="开始",
setting="设置",
@@ -198,11 +225,11 @@ return{
start1="消除开始",
start2="拼图开始",
draw="画图(D)",
set1="40行",
set2="1v1",
set3="无尽",
set4="隐形",
set5="极限",
set1="40行(1)",
set2="1v1(2)",
set3="无尽(3)",
set4="隐形(4)",
set5="极限(5)",
back=BK,
},
draw={
@@ -229,27 +256,27 @@ return{
pause={
resume= "继续",
restart="重新开始",
setting="设置",
quit= "退出",
},
setting={
game= "游戏设置",
graphic="画面设置",
sound= "声音设置",
ctrl= "控制设置",
touch= "触屏设置",
lang= function()return langName[setting.lang]end,
back= "保存&返回",
},
setting_game={
graphic="←画面设置",
sound="声音设置→",
dasD="-",dasU="+",
arrD="-",arrU="+",
sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+",
holdR="长按重新开始",
quickR="快速重新开始",
swap="组合键切换攻击模式",
fine="极简操作提示音",
ctrl="键位设置",
touch="触屏设置",
back=BK,
},
setting_graphic={
sound="←声音设置",
game="游戏设置→",
ghost="阴影",
grid="网格",
center="旋转中心",
@@ -265,22 +292,41 @@ return{
back=BK,
},
setting_sound={
game="←游戏设置",
graphic="画面设置→",
sfx="音效",
bgm="音乐",
vib="震动",
voc="语音",
back=BK,
},
setting_control={
setting_key={
back=BK,
},
setting_touch={
hide=function()return setting.virtualkeySwitch and"隐藏虚拟按键"or"显示虚拟按键"end,
hide="显示虚拟按键",
track="按键自动跟踪",
tkset="跟踪设置",
default="默认组合",
snap=function()return text.snapLevelName[snapLevel]end,
alpha=function()return setting.virtualkeyAlpha.."0%"end,
alpha=function()return setting.VKAlpha.."0%"end,
icon="图标",
size="大小",
toggle="开关",
back=BK,
},
setting_touchSwitch={
b1= actName[1],b2=actName[2],b3=actName[3],b4=actName[4],
b5= actName[5],b6=actName[6],b7=actName[7],b8=actName[8],
b9= actName[9],b10=actName[10],b11=actName[11],b12=actName[12],
b13=actName[13],b14=actName[14],b15=actName[15],b16=actName[16],
b17=actName[17],b18=actName[18],b19=actName[19],b20=actName[20],
norm="标准",
pro="专业",
back=BK,
},
setting_trackSetting={
VKDodge="自动避让",
back=BK,
},
help={
@@ -298,4 +344,4 @@ return{
back=BK,
},
},
}--部分译文
}

View File

@@ -1,4 +1,11 @@
local BK="Back"
local actName={
"Move Left:","Move Right:",
"Rotate Right:","Rotate Left:","Rotate Flip:",
"Hard Drop:","Soft Drop:","Hold:","Function:","Restart:",
"Instant Left:","Instant Right:","Ins Down:","Down 1:","Down 4:","Down 10:",
"Left Drop:","Right Drop:","Left INS:","Right INS:",
}
return{
atkModeName={"Random","Badges","K.O.s","Counters"},
royale_remain=function(n)return n.." Players Remain"end,
@@ -61,11 +68,17 @@ return{
snapLevelName={"Free pos","Snap-10","Snap-20","Snap-40","Snap-60","Snap-80"},
keyboard="Keyboard",joystick="Joystick",
space="Space",enter="Enter",
setting2Help="Arrowkey to select/change slot,Enter to change,Esc back",
ctrlSetHelp="Arrowkey to select/change slot,Enter to change,Esc back",
setting_game="Game setting",
setting_graphic="Graphic setting",
setting_sound="Sound setting",
musicRoom="Music Room",
nowPlaying="Now Playing:",
VKTchW="Touch weight",
VKOrgW="Origion weight",
VKCurW="CurPos weight",
actName={"Move Left:","Move Right:","Rotate Right:","Rotate Left:","Rotate Flip:","Hard Drop:","Soft Drop:","Hold:","Function:","Restart:","Instant Left:","Instant Right:","Ins Down:"},
actName=actName,
modeName={
[0]="Custom",
"Sprint","Marathon","Master","Classic","Zen","Infinite","1v1","Round","TSD-only","Blind",
@@ -100,17 +113,15 @@ return{
load={"Loading VOICE","Loading BGM","Loading SFX","Finished",},
tips={
"Not animation,real loading!",
"The WHOLE game is made by MrZ!",
"Back to Back 10 combo Techrash PC!",
"Techmino has a Nspire-CX edition!",
"B2B2B???",
"Is B2B2B2B possible?",
"MEGACMB!",
"ALLSPIN!",
"O spin triple?",
"You can play with any input device!",
"O spin triple!",
"Miya:Nya!",
"225238922,Bilibili cheers!",
"225238922 Bilibili cheers!",
"Playing too much = taking drugs",
"Disappearing doesn't mean useless",
"Try to use two rotate button,three better",
@@ -126,8 +137,12 @@ return{
"Let-The-Bass-Kick!",
"Powered by love2d",
"Find out what's in the setting!",
"Any suggestions to author!~",
"Techmino=Technique+tetromino",
"Any suggestions to author!",
"DO NOT PRESS F8",
"Secret code:626",
"Techmino=Technique+Tetromino",
"CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
},
stat={
"Games run:",
@@ -137,7 +152,7 @@ return{
"Rotate:",
"Hold:",
"Block used:",
"Rows cleared:",
"Lines cleared:",
"Attack:",
"Sent:",
"Receive:",
@@ -147,6 +162,8 @@ return{
"B2B:",
"PC:",
"Efficiency:",
"Finesse error:",
"Finesse rate:",
},
help={
"I don't think you need \"help\".",
@@ -156,16 +173,25 @@ return{
"",
"Powered by LOVE2D",
"Author:MrZ E-mail:1046101471@qq.com",
"Programe:MrZ Art:MrZ Music:MrZ SFX:MrZ VOICE:Miya",
"Tool used:VScode,GFIE,Beepbox,Goldwave,Cold_Clear",
"Program:MrZ Art:MrZ Music:MrZ SFX:MrZ VOICE:Miya",
"Special thanks:Farter,Flyz,196,Teatube,T830,[all test staff] and YOU!",
"Any bugs/suggestions to my E-mail.",
},
used=[[
Tool used:
Beepbox
GFIE
Goldwave
Lib used:
Cold_Clear[MinusKelvin]
simple-love-lights[dylhunn]
]],
support="Support Author",
group="Official QQ Group",
warning="DO NOT DISTRIBUTE",
WidgetText={
main={
lang="文-Lang",
qplay="Qplay",
play="Play",
setting="Settings",
@@ -198,11 +224,11 @@ return{
start1="Clear Start",
start2="Puzzle Start",
draw="Draw(D)",
set1="40L",
set2="1v1",
set3="infinite",
set4="blind",
set5="master",
set1="40L(1)",
set2="1v1(2)",
set3="infinite(3)",
set4="blind(4)",
set5="master(5)",
back=BK,
},
draw={
@@ -229,27 +255,26 @@ return{
pause={
resume="Resume",
restart="Restart",
setting="Setting",
quit="Quit",
},
setting={
game= "Game Settings",
graphic="Graphic Settings",
sound= "Sound Settings",
ctrl= "Control Settings",
touch= "Touch Settings",
lang= function()return langName[setting.lang]end,
back= "Save&Back",
},
setting_game={
graphic="←Graphic",
sound="Sound→",
dasD="-",dasU="+",
arrD="-",arrU="+",
sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+",
holdR="Hold R to restart",
quickR="Quick restart",
swap="Combo key to change ATK mode",
fine="Finesse error SFX",
ctrl="Key Setting",
touch="Touch Setting",
back=BK,
},
setting_graphic={
sound="←Sound",
game="Game→",
ghost="Ghost",
grid="Grid",
center="Center",
@@ -261,26 +286,45 @@ return{
shakeFX="Shake FX level",
atkFX="ATK FX level",
fullscreen="Fullscreen",
frame="drawFPS",
frame="draw FPS",
back=BK,
},
setting_sound={
game="←Game",
graphic="Graphic→",
sfx="SFX",
bgm="BGM",
vib="VIB",
voc="VOC",
back=BK,
},
setting_control={
setting_key={
back=BK,
},
setting_touch={
hide=function()return setting.virtualkeySwitch and"Hide Virtual Key"or"Show Virtual Key"end,
hide="Show Virtual Key",
track="Auto track",
tkset="Track setting",
default="Defaults",
snap=function()return text.snapLevelName[snapLevel]end,
alpha=function()return setting.virtualkeyAlpha.."0%"end,
alpha=function()return setting.VKAlpha.."0%"end,
icon="Icon",
size="Size",
toggle="Toggle",
back=BK,
},
setting_touchSwitch={
b1= actName[1],b2=actName[2],b3=actName[3],b4=actName[4],
b5= actName[5],b6=actName[6],b7=actName[7],b8=actName[8],
b9= actName[9],b10=actName[10],b11=actName[11],b12=actName[12],
b13=actName[13],b14=actName[14],b15=actName[15],b16=actName[16],
b17=actName[17],b18=actName[18],b19=actName[19],b20=actName[20],
norm="Normal",
pro="Professioanl",
back=BK,
},
setting_trackSetting={
VKDodge="Auto Dodge",
back=BK,
},
help={

80
light.lua Normal file
View File

@@ -0,0 +1,80 @@
--LIGHT MODULE(Optimized by MrZ,Original on github/love2d community/simple-love-lights)
--Heavily based on mattdesl's libGDX implementation:
--https://github.com/mattdesl/lwjgl-basics/wiki/2D-Pixel-Perfect-Shadows
local gc=love.graphics
local C=gc.clear
local shadowMapShader=gc.newShader("shadowMapShader.cs")--Shader for caculating the 1D shadow map.
local lightRenderShader=gc.newShader("lightRenderShader.cs")--Shader for rendering blurred lights and shadows.
Lights={}--Lightsource objects
local Lights=Lights
--Private--
local function move(L,x,y)
L.x,L.y=x,y
end
local function setPow(L,pow)
L.size=pow
end
local function destroy(L)
L.blackCanvas:release()
L.shadowCanvas:release()
L.renderCanvas:release()
end
local function draw(L)
local r,g,b,a=love.graphics.getColor()
gc.setCanvas(L.blackCanvas)C()
gc.setCanvas(L.shadowCanvas)C()
gc.setCanvas(L.renderCanvas)C()
lightRenderShader:send("xresolution",L.size);
shadowMapShader:send("yresolution",L.size);
--初始化数据
local X=L.x-L.size*.5
local Y=L.y-L.size*.5
--整束光的左上角
gc.translate(-X,-Y)
L.blackCanvas:renderTo(L.blackFn)
gc.translate(X,Y)
--渲染遮光物
gc.setShader(shadowMapShader)
gc.setCanvas(L.shadowCanvas)
gc.draw(L.blackCanvas)
--根据遮光物渲染阴影画布
gc.setShader(lightRenderShader)
gc.setCanvas(L.renderCanvas)
gc.draw(L.shadowCanvas,0,0,0,1,L.size)
--根据阴影画布渲染光画布
gc.setShader()gc.setCanvas()gc.setBlendMode("add")
--准备渲染
gc.setColor(r,g,b,a)
gc.draw(L.renderCanvas,X,Y+L.size,0,1,-1)
--渲染到屏幕
gc.setBlendMode("alpha")
--复位
end
--Public--
function drawLight()
for i=1,#Lights do
Lights[i]:draw()
end
end
function clearLight(L)
for i=1,#Lights do
Lights[i]:destroy()
Lights[i]=nil
end
end
function addLight(x,y,R,F)
local id=#Lights+1
Lights[id]={
id=id,
x=x,y=y,size=R,
blackCanvas=gc.newCanvas(R,R),--遮挡物画布
shadowCanvas=gc.newCanvas(R,1),--1D视深画布
renderCanvas=gc.newCanvas(R,R),--灯光画布
blackFn=F,--遮挡物绘图函数
--方法
move=move,
setPow=setPow,
draw=draw,
destroy=destroy,
}
end

30
lightRenderShader.cs Normal file
View File

@@ -0,0 +1,30 @@
#define PI 3.14
extern float xresolution;
//从1D距离map采样
float samp(vec2 coord,float r,Image u_texture){
return step(r,Texel(u_texture,coord).r);
}
vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){
//直角转极坐标用于采样1D材质的y总是0
vec2 norm=texture_coords.st*2.-1.;
float r=length(norm);
vec2 tc=vec2((atan(norm.y,norm.x)+PI)/(2.*PI),0.);
//根据离光源距离放大模糊系数,模拟影子淡出
float blur=(1./xresolution)*smoothstep(0.,1.,r);
//简易高斯模糊
float sum=
samp(vec2(tc.x-4.*blur,tc.y),r,texture)*.5
+samp(vec2(tc.x-3.*blur,tc.y),r,texture)*.9
+samp(vec2(tc.x-2.*blur,tc.y),r,texture)*.12
+samp(vec2(tc.x-1.*blur,tc.y),r,texture)*.15
+samp(tc,r,texture)*.16//The center tex coord,which gives us hard shadows.
+samp(vec2(tc.x+1.*blur,tc.y),r,texture)*.15
+samp(vec2(tc.x+2.*blur,tc.y),r,texture)*.12
+samp(vec2(tc.x+3.*blur,tc.y),r,texture)*.9
+samp(vec2(tc.x+4.*blur,tc.y),r,texture)*.5;
//sum值为亮度(0~1)
//乘上距离得到逐渐变淡的光线
return vec4(vec3(1.),sum*smoothstep(1.,.1,r));
}

434
list.lua
View File

@@ -1,10 +1,13 @@
local gc=love.graphics
local tc,kb=love.touch,love.keyboard
local sys=love.system
local fs=love.filesystem
local mobile=system=="Android"or system=="iOS"
actName={"moveLeft","moveRight","rotRight","rotLeft","rotFlip","hardDrop","softDrop","hold","func","restart","insLeft","insRight","insDown"}
actName={
"moveLeft","moveRight",
"rotRight","rotLeft","rotFlip",
"hardDrop","softDrop",
"hold","func",
"restart",
"insLeft","insRight","insDown","down1","down4","down10",
"dropLeft","dropRight","addLeft","addRight",--Super contorl system
}
color={
red={1,0,0},
green={0,1,0},
@@ -53,6 +56,9 @@ blockColor={
color.darkGreen,
}
sfx={
"welcome",
"error","error_long",
--Stereo sfxs
"button","swipe",
"ready","start","win","fail","collect",
"move","rotate","rotatekick","hold",
@@ -64,6 +70,7 @@ sfx={
"spin_0","spin_1","spin_2","spin_3",
"emit","blip_1","blip_2",
"perfectclear",
--mono sfxs
}
bgm={
"blank",
@@ -159,7 +166,7 @@ customRange={
RCPB={10,33,200,33,105,5,105,60}
snapLevelValue={1,10,20,40,60,80}
up0to4={[0]="000%UP","025%UP","050%UP","075%UP","100%UP",}
sectionName={"M7","M8","M9","M","MK","MV","MO","MM","GM"}
modeID={
[0]="custom",
"sprint","marathon","master","classic","zen","infinite","solo","round","tsd","blind",
@@ -178,10 +185,10 @@ modeLevel={
tsd={"NORMAL","HARD"},
blind={"EASY","HARD","HARD+","LUNATIC","ULTIMATE","GM"},
dig={"NORMAL","LUNATIC"},
survivor={"EASY","NORMAL","HARD","LUNATIC","ULTIMATE","EXTRA"},
survivor={"EASY","NORMAL","HARD","LUNATIC","ULTIMATE"},
defender={"NORMAL","LUNATIC"},
attacker={"HARD","ULTIMATE"},
tech={"NORMAL","NORMAL+","HARD","HARD+","LUNATIC","LUNATIC+",},
tech={"NORMAL","NORMAL+","HARD","HARD+","LUNATIC","LUNATIC+","ULTIMATE","ULTIMATE+",},
c4wtrain={"NORMAL","LUNATIC"},
pctrain={"NORMAL","EXTRA"},
pcchallenge={"NORMAL","HARD","LUNATIC"},
@@ -206,65 +213,76 @@ for i=1,7 do blocks[i+7]=blocks[i]end
local virtualkeySet={
{
{80,720-200,6400,80},--moveLeft
{320,720-200,6400,80},--moveRight
{1280-80,720-200,6400,80},--rotRight
{1280-200,720-80,6400,80},--rotLeft
{1280-200,720-320,6400,80},--rotFlip
{200,720-320,6400,80},--hardDrop
{200,720-80,6400,80},--softDrop
{1280-320,720-200,6400,80},--hold
{1280-80,280,6400,80},--func
{80,280,6400,80},--restart
},--Farter's set 3
{1, 80, 720-200, 80},--moveLeft
{2, 320, 720-200, 80},--moveRight
{3, 1280-80, 720-200, 80},--rotRight
{4, 1280-200, 720-80, 80},--rotLeft
{5, 1280-200, 720-320, 80},--rotFlip
{6, 200, 720-320, 80},--hardDrop
{7, 200, 720-80, 80},--softDrop
{8, 1280-320, 720-200, 80},--hold
{9, 1280-80, 280, 80},--func
{10,80, 280, 80},--restart
},--Farter's set,thanks
{
{1280-320,720-200,6400,80},--moveLeft
{1280-80,720-200,6400,80},--moveRight
{200,720-80,6400,80},--rotRight
{80,720-200,6400,80},--rotLeft
{200,720-320,6400,80},--rotFlip
{1280-200,720-320,6400,80},--hardDrop
{1280-200,720-80,6400,80},--softDrop
{320,720-200,6400,80},--hold
{80,280,6400,80},--func
{1280-80,280,6400,80},--restart
},--Mirrored farter's set 3
{1, 1280-320, 720-200, 80},--moveLeft
{2, 1280-80, 720-200, 80},--moveRight
{3, 200, 720-80, 80},--rotRight
{4, 80, 720-200, 80},--rotLeft
{5, 200, 720-320, 80},--rotFlip
{6, 1280-200, 720-320, 80},--hardDrop
{7, 1280-200, 720-80, 80},--softDrop
{8, 320, 720-200, 80},--hold
{9, 80, 280, 80},--func
{10,1280-80, 280, 80},--restart
},--Mirrored farter's set,sknaht
{
{80,720-80,6400,80},--moveLeft
{240,720-80,6400,80},--moveRight
{1280-240,720-80,6400,80},--rotRight
{1280-400,720-80,6400,80},--rotLeft
{1280-240,720-240,6400,80},--rotFlip
{1280-80,720-80,6400,80},--hardDrop
{1280-80,720-240,6400,80},--softDrop
{1280-80,720-400,6400,80},--hold
{80,360,6400,80},--func
{80,80,6400,80},--restart
},--Author's set
{1, 80, 720-80, 80},--moveLeft
{2, 240, 720-80, 80},--moveRight
{3, 1280-240, 720-80, 80},--rotRight
{4, 1280-400, 720-80, 80},--rotLeft
{5, 1280-240, 720-240, 80},--rotFlip
{6, 1280-80, 720-80, 80},--hardDrop
{7, 1280-80, 720-240, 80},--softDrop
{8, 1280-80, 720-400, 80},--hold
{9, 80, 360, 80},--func
{10,80, 80, 80},--restart
},--Author's set,not recommend
{
{1280-400,720-80,6400,80},--moveLeft
{1280-80,720-80,6400,80},--moveRight
{240,720-80,6400,80},--rotRight
{80,720-80,6400,80},--rotLeft
{240,720-240,6400,80},--rotFlip
{1280-240,720-240,6400,80},--hardDrop
{1280-240,720-80,6400,80},--softDrop
{1280-80,720-240,6400,80},--hold
{80,720-240,6400,80},--func
{80,320,6400,80},--restart
{1, 1280-400, 720-80, 80},--moveLeft
{2, 1280-80, 720-80, 80},--moveRight
{3, 240, 720-80, 80},--rotRight
{4, 80, 720-80, 80},--rotLeft
{5, 240, 720-240, 80},--rotFlip
{6, 1280-240, 720-240, 80},--hardDrop
{7, 1280-240, 720-80, 80},--softDrop
{8, 1280-80, 720-240, 80},--hold
{9, 80, 720-240, 80},--func
{10,80, 320, 80},--restart
},--Keyboard set
{
{1200-370,40,1600,40},--moveLeft
{1200-280,40,1600,40},--moveRight
{1200-530,40,1600,40},--rotRight
{1200-610,40,1600,40},--rotLeft
{1200-450,40,1600,40},--rotFlip
{1200-50,40,1600,40},--hardDrop
{1200-130,40,1600,40},--softDrop
{1200-210,40,1600,40},--hold
{1200-690,40,1600,40},--func
{1200-770,40,1600,40},--restart
},--PC key feedback
{10,70, 50,27},--restart
{9, 130, 50,27},--func
{4, 190, 50,27},--rotLeft
{3, 250, 50,27},--rotRight
{5, 310, 50,27},--rotFlip
{1, 370, 50,27},--moveLeft
{2, 430, 50,27},--moveRight
{8, 490, 50,27},--hold
{7, 550, 50,27},--softDrop1
{6, 610, 50,27},--hardDrop
{11,670, 50,27},--insLeft
{12,730, 50,27},--insRight
{13,790, 50,27},--insDown
{14,850, 50,27},--down1
{15,910, 50,27},--down4
{16,970, 50,27},--down10
{17,1030, 50,27},--dropLeft
{18,1090, 50,27},--dropRight
{19,1150, 50,27},--addLeft
{20,1210, 50,27},--addRight
},--PC key feedback(top&in a row)
}
local customSet={
{20,20,1,1,7,1,1,1,3,4,1,2,3},
@@ -280,66 +298,79 @@ local function useDefaultSet(n)
curBG=customRange.bg[customSel[12]]
BGM(customRange.bgm[customSel[13]])
end
local function VKAdisp(n)
return function()
return VK_org[n].ava
end
end
local function VKAcode(n)
return function()
VK_org[n].ava=not VK_org[n].ava
end
end
Widget={
load={},
intro={},
load={},intro={},quit={},
main={
qplay= newButton(160, 300,150,150,color.lightRed, 40,function()loadGame(modeSel,levelSel)end, nil,"play"),
play= newButton(380, 300,240,240,color.red, 70,function()gotoScene("mode")end, nil,"setting"),
setting=newButton(640, 300,240,240,color.lightBlue,55,function()gotoScene("setting")end, nil,"music"),
music= newButton(900, 300,240,240,color.lightCyan,42,function()gotoScene("music")end, nil,"stat"),
stat= newButton(640, 560,240,240,color.cyan, 55,function()gotoScene("stat")end, nil,"help"),
help= newButton(900, 560,240,240,color.yellow, 55,function()gotoScene("help")end, nil,"quit"),
quit= newButton(1180,620,120,120,color.lightGrey,50,function()gotoScene("quit")end, nil,"qplay"),
play= newButton(150,280,200,160,color.red, 60,function()scene.push()scene.swapTo("mode")end, nil,"setting"),
setting=newButton(370,280,200,160,color.lightBlue, 50,function()scene.push()scene.swapTo("setting_game")end, nil,"music"),
music= newButton(590,280,200,160,color.lightPurple,37,function()scene.push()scene.swapTo("music")end, nil,"help"),
help= newButton(150,460,200,160,color.yellow, 55,function()scene.push()scene.swapTo("help")end, nil,"stat"),
stat= newButton(370,460,200,160,color.cyan, 48,function()scene.push()scene.swapTo("stat")end, nil,"qplay"),
qplay= newButton(540,415,100,70,color.lightGreen, 28,function()scene.push()loadGame(modeSel,levelSel)end, nil,"lang"),
lang= newButton(590,505,200,70,color.lightRed, 50,function()
setting.lang=setting.lang%#langName+1
swapLanguage(setting.lang)
end,nil,"quit"),
quit= newButton(370,620,280,100,color.lightGrey, 60,function()scene.swapTo("quit")end, nil,"play"),
},
mode={
up= newButton(1000,210,200,140,color.white, 80,function()love.keypressed("up")end,function()return modeSel==1 end),
down= newButton(1000,430,200,140,color.white, 80,function()love.keypressed("down")end,function()return modeSel==#modeID end),
up= newButton(1000, 210,200,140,color.white, 80,function()love.keypressed("up")end,function()return modeSel==1 end),
down= newButton(1000, 430,200,140,color.white, 80,function()love.keypressed("down")end,function()return modeSel==#modeID end),
left= newButton(190, 160,100,80, color.white, 40,function()love.keypressed("left")end,function()return levelSel==1 end),
right= newButton(350, 160,100,80, color.white, 40,function()love.keypressed("right")end,function()return levelSel==#modeLevel[modeID[modeSel]]end),
start= newButton(1000,600,250,100,color.green, 50,function()loadGame(modeSel,levelSel)end),
custom= newButton(275, 420,200,90, color.yellow, 40,function()gotoScene("custom")end),
back= newButton(640, 630,230,90, color.white, 45,back),
start= newButton(1000, 600,250,100,color.green, 50,function()scene.push()loadGame(modeSel,levelSel)end),
custom= newButton(275, 420,200,90, color.yellow, 40,function()scene.push()scene.swapTo("custom")end),
back= newButton(640, 630,230,90, color.white, 45,scene.back),
},
music={
bgm= newSlider(760,80,400,8,40,nil,function()return setting.bgm end,function(i)setting.bgm=i;BGM(bgmPlaying)end),
up= newButton(1100,200,120,120,color.white,60,function()love.keypressed("up")end),
play= newButton(1100,340,120,120,color.white,40,function()love.keypressed("space")end,function()return setting.bgm==0 end),
down= newButton(1100,480,120,120,color.white,60,function()love.keypressed("down")end),
back= newButton(640, 630,230,90, color.white,45,back),
bgm= newSlider(760, 80,400,10,40,nil,function()return setting.bgm end,function(i)setting.bgm=i;BGM(bgmPlaying)end),
up= newButton(1100, 200,120,120,color.white,60,function()love.keypressed("up")end),
play= newButton(1100, 340,120,120,color.white,40,function()love.keypressed("space")end,function()return setting.bgm==0 end),
down= newButton(1100, 480,120,120,color.white,60,function()love.keypressed("down")end),
back= newButton(640, 630,230,90, color.white,45,scene.back),
},
custom={
up= newButton(1000,220,100,100,color.white, 50,function()sel=(sel-2)%#customID+1 end),
down= newButton(1000,460,100,100,color.white, 50,function()sel=sel%#customID+1 end),
up= newButton(1000, 220,100,100,color.white, 50,function()sel=(sel-2)%#customID+1 end),
down= newButton(1000, 460,100,100,color.white, 50,function()sel=sel%#customID+1 end),
left= newButton(880, 340,100,100,color.white, 50,function()love.keypressed("left")end),
right= newButton(1120,340,100,100,color.white, 50,function()love.keypressed("right")end),
start1= newButton(880, 580,220,70, color.green, 40,function()loadGame(0,1)end),
start2= newButton(1120,580,220,70, color.lightPurple, 40,function()loadGame(0,2)end),
draw= newButton(1000,90, 190,85, color.cyan, 40,function()gotoScene("draw")end),
right= newButton(1120, 340,100,100,color.white, 50,function()love.keypressed("right")end),
start1= newButton(880, 580,220,70, color.green, 40,function()scene.push()loadGame(0,1)end),
start2= newButton(1120, 580,220,70, color.lightPurple, 40,function()scene.push()loadGame(0,2)end),
draw= newButton(1000, 90, 190,85, color.cyan, 40,function()scene.push()scene.swapTo("draw")end),
set1= newButton(640, 160,240,75, color.lightRed, 40,function()useDefaultSet(1)end),
set2= newButton(640, 250,240,75, color.lightRed, 40,function()useDefaultSet(2)end),
set3= newButton(640, 340,240,75, color.lightRed, 40,function()useDefaultSet(3)end),
set4= newButton(640, 430,240,75, color.lightRed, 40,function()useDefaultSet(4)end),
set5= newButton(640, 520,240,75, color.lightRed, 40,function()useDefaultSet(5)end),
back= newButton(640, 630,180,60, color.white, 40,back),
back= newButton(640, 630,180,60, color.white, 40,scene.back),
},
draw={
any= newButton(700, 80, 120,120,color.lightGrey, 45,function()pen=0 end),
block1= newButton(840, 80, 120,120,color.red, 65,function()pen=1 end),
block2= newButton(980, 80, 120,120,color.green, 65,function()pen=2 end),
block3= newButton(1120,80, 120,120,color.orange, 65,function()pen=3 end),
block4= newButton(840, 220,120,120,color.blue, 65,function()pen=4 end),
block5= newButton(980, 220,120,120,color.magenta, 65,function()pen=5 end),
block6= newButton(1120,220,120,120,color.yellow, 65,function()pen=6 end),
block7= newButton(840, 360,120,120,color.cyan, 65,function()pen=7 end),
gb1= newButton(980, 360,120,120,color.darkGrey, 65,function()pen=9 end),
gb2= newButton(1120,360,120,120,color.grey, 65,function()pen=10 end),
gb3= newButton(840, 500,120,120,color.darkPurple, 65,function()pen=11 end),
gb4= newButton(980, 500,120,120,color.darkRed, 65,function()pen=12 end),
gb5= newButton(1120,500,120,120,color.darkGreen, 65,function()pen=13 end),
space= newButton(840, 640,120,120,color.grey, 70,function()pen=-1 end),
clear= newButton(1120,640,120,120,color.white, 45,function()love.keypressed("delete")end),
back= newButton(1235,45, 80, 80, color.white, 35,back),
block1= newButton(920, 80, 120,120,color.red, 65,function()pen=1 end),
block2= newButton(1060, 80, 120,120,color.green, 65,function()pen=2 end),
block3= newButton(1200, 80, 120,120,color.orange, 65,function()pen=3 end),
block4= newButton(920, 220,120,120,color.blue, 65,function()pen=4 end),
block5= newButton(1060, 220,120,120,color.magenta, 65,function()pen=5 end),
block6= newButton(1200, 220,120,120,color.yellow, 65,function()pen=6 end),
block7= newButton(920, 360,120,120,color.cyan, 65,function()pen=7 end),
gb1= newButton(1060, 360,120,120,color.darkGrey, 65,function()pen=9 end),
gb2= newButton(1200, 360,120,120,color.grey, 65,function()pen=10 end),
gb3= newButton(920, 500,120,120,color.darkPurple, 65,function()pen=11 end),
gb4= newButton(1060, 500,120,120,color.darkRed, 65,function()pen=12 end),
gb5= newButton(1200, 500,120,120,color.darkGreen, 65,function()pen=13 end),
clear= newButton(780, 80, 120,120,color.white, 45,function()love.keypressed("delete")end),
any= newButton(780, 220,120,120,color.lightGrey, 45,function()pen=0 end),
space= newButton(780, 360,120,120,color.grey, 70,function()pen=-1 end),
back= newButton(1200, 640,120,120,color.white, 40,scene.back),
},
play={
pause= newButton(1235,45,80,80,color.white,30,pauseGame),
@@ -350,26 +381,20 @@ Widget={
clearTask("play")
updateStat()
resetGameData()
gotoScene("play","none")
scene.swapTo("play","none")
end),
quit= newButton(640,600,240,100,color.white,50,back),
},
setting={
game= newButton(640,100,320,70,color.white,40,function()gotoScene("setting_game") end,nil,"graphic"),
graphic=newButton(640,180,320,70,color.white,40,function()gotoScene("setting_graphic") end,nil,"sound"),
sound= newButton(640,260,320,70,color.white,40,function()gotoScene("setting_sound") end,nil,"ctrl"),
ctrl= newButton(640,340,320,70,color.white,40,function()gotoScene("setting_control") end,nil,"touch"),
touch= newButton(640,420,320,70,color.white,40,function()gotoScene("setting_touch") end,nil,"lang"),
lang= newButton(640,500,320,70,color.red,40,function()
setting.lang=setting.lang%#langName+1
swapLanguage(setting.lang)
end,nil,"back"),
back= newButton(640,620,300,70,color.white,40,back, nil,"game"),
setting=newButton(1150,80,200,100,color.yellow,45,function()
scene.push()
scene.swapTo("setting_sound")
end),
quit= newButton(640,600,240,100,color.white,50,scene.back),
},
setting_game={
dasD= newButton(150,120,50,50,color.white,40,function()setting.das=(setting.das-1)%31 end, nil,"dasU"),
dasU= newButton(370,120,50,50,color.white,40,function()setting.das=(setting.das+1)%31 end, nil,"arrD"),
arrD= newButton(450,120,50,50,color.white,40,function()
graphic=newButton(200,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_graphic")end, nil,"sound"),
sound= newButton(1080,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_sound")end, nil,"dasD"),
dasD= newButton(180,230,50,50,color.white,40,function()setting.das=(setting.das-1)%31 end, nil,"dasU"),
dasU= newButton(400,230,50,50,color.white,40,function()setting.das=(setting.das+1)%31 end, nil,"arrD"),
arrD= newButton(500,230,50,50,color.white,40,function()
setting.arr=(setting.arr-1)%16
if setting.arr>setting.das then
setting.das=setting.arr
@@ -377,7 +402,7 @@ Widget={
SFX("blip_1",.4)
end
end,nil,"arrU"),
arrU= newButton(670,120,50,50,color.white,40,function()
arrU= newButton(720,230,50,50,color.white,40,function()
setting.arr=(setting.arr+1)%16
if setting.arr>setting.das then
setting.das=setting.arr
@@ -385,95 +410,148 @@ Widget={
SFX("blip_1",.4)
end
end,nil,"sddasD"),
sddasD= newButton(150,230,50,50,color.white,40,function()setting.sddas=(setting.sddas-1)%11 end, nil,"sddasU"),
sddasU= newButton(370,230,50,50,color.white,40,function()setting.sddas=(setting.sddas+1)%11 end, nil,"sdarrD"),
sdarrD= newButton(450,230,50,50,color.white,40,function()setting.sdarr=(setting.sdarr-1)%4 end, nil,"sdarrU"),
sdarrU= newButton(670,230,50,50,color.white,40,function()setting.sdarr=(setting.sdarr+1)%4 end, nil,"holdR"),
holdR= newSwitch(510,330,40,function()return setting.holdR end,function()setting.holdR=not setting.holdR end, nil,"swap"),
swap= newSwitch(510,420,25,function()return setting.swap end,function()setting.swap=not setting.swap end, nil,"back"),
back= newButton(640,620,300,70,color.white,40,back,nil,"dasD"),
sddasD= newButton(180,340,50,50,color.white,40,function()setting.sddas=(setting.sddas-1)%11 end, nil,"sddasU"),
sddasU= newButton(400,340,50,50,color.white,40,function()setting.sddas=(setting.sddas+1)%11 end, nil,"sdarrD"),
sdarrD= newButton(500,340,50,50,color.white,40,function()setting.sdarr=(setting.sdarr-1)%4 end, nil,"sdarrU"),
sdarrU= newButton(720,340,50,50,color.white,40,function()setting.sdarr=(setting.sdarr+1)%4 end, nil,"quickR"),
quickR= newSwitch(560,430,40,function()return setting.quickR end,function()setting.quickR=not setting.quickR end, nil,"swap"),
swap= newSwitch(560,510,25,function()return setting.swap end,function()setting.swap=not setting.swap end, nil,"fine"),
fine= newSwitch(560,590,25,function()return setting.fine end,function()setting.fine=not setting.fine end, nil,"ctrl"),
ctrl= newButton(1020,230,320,80,color.white,40,function()scene.push()scene.swapTo("setting_key")end, nil,"touch"),
touch= newButton(1020,340,320,80,color.white,40,function()scene.push()scene.swapTo("setting_touch")end, nil,"back"),
back= newButton(1160,600,160,160,color.white,55,scene.back,nil,"graphic"),
},
setting_graphic={
ghost= newSwitch(310,90,40, function()return setting.ghost end, function()setting.ghost= not setting.ghost end, nil,"center"),
center= newSwitch(580,90,40, function()return setting.center end, function()setting.center= not setting.center end, nil,"smo"),
smo= newSwitch(310,170,25, function()return setting.smo end, function()setting.smo= not setting.smo end, nil,"grid"),
grid= newSwitch(580,170,40, function()return setting.grid end, function()setting.grid= not setting.grid end, nil,"dropFX"),
dropFX= newSlider(310,260,373,3,40,nil,function()return setting.dropFX end, function(i)setting.dropFX=i end, nil,"shakeFX"),
shakeFX=newSlider(310,340,373,3,40,nil,function()return setting.shakeFX end, function(i)setting.shakeFX=i end, nil,"atkFX"),
atkFX= newSlider(310,420,373,3,40,nil,function()return setting.atkFX end, function(i)setting.atkFX=i end, nil,"frame"),
frame= newSlider(310,500,373,10,40,nil,function()return setting.frameMul>35 and setting.frameMul/10 or setting.frameMul/5-4 end,function(i)setting.frameMul=i<5 and 5*i+20 or 10*i end,nil,"fullscreen"),
fullscreen=newSwitch(990,90,40,function()return setting.fullscreen end,function()
sound= newButton(200,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_sound")end, nil,"game"),
game= newButton(1080,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_game")end, nil,"ghost"),
ghost= newSwitch(310,180,40,function()return setting.ghost end, function()setting.ghost= not setting.ghost end, nil,"center"),
center= newSwitch(580,180,40,function()return setting.center end, function()setting.center= not setting.center end, nil,"smo"),
smo= newSwitch(310,260,25,function()return setting.smo end, function()setting.smo= not setting.smo end, nil,"grid"),
grid= newSwitch(580,260,40,function()return setting.grid end, function()setting.grid= not setting.grid end, nil,"dropFX"),
dropFX= newSlider(310,350,373,3,40,nil,function()return setting.dropFX end, function(i)setting.dropFX=i end, nil,"shakeFX"),
shakeFX=newSlider(310,430,373,3,40,nil,function()return setting.shakeFX end, function(i)setting.shakeFX=i end, nil,"atkFX"),
atkFX= newSlider(310,510,373,3,40,nil,function()return setting.atkFX end, function(i)setting.atkFX=i end, nil,"frame"),
frame= newSlider(310,590,373,10,40,nil,function()return setting.frameMul>35 and setting.frameMul/10 or setting.frameMul/5-4 end,function(i)setting.frameMul=i<5 and 5*i+20 or 10*i end,nil,"fullscreen"),
fullscreen=newSwitch(990,180,40,function()return setting.fullscreen end,function()
setting.fullscreen=not setting.fullscreen
love.window.setFullscreen(setting.fullscreen)
if not setting.fullscreen then
love.resize(gc.getWidth(),gc.getHeight())
love.resize(love.graphics.getWidth(),love.graphics.getHeight())
end
end,nil,"bg"),
bg= newSwitch(990,170,40,function()return setting.bg end,function()setting.bg=not setting.bg end, nil,"bgblock"),
bgblock=newSwitch(990,250,40,function()return setting.bgblock end,function()
bg= newSwitch(990,250,40,function()return setting.bg end,function()setting.bg=not setting.bg end, nil,"bgblock"),
bgblock=newSwitch(990,330,40,function()return setting.bgblock end,function()
setting.bgblock=not setting.bgblock--if not setting.bgblock then for i=1,16 do FX_BGblock.list[i].v=3*FX_BGblock.list[i].v end end
end,nil,"skin"),
skin= newButton(950,450,120,60,color.white,40,function()
setting.skin=setting.skin%6+1
skin= newButton(860,470,120,60,color.white,40,function()
setting.skin=setting.skin%8+1
changeBlockSkin(setting.skin)
end,nil,"back"),
back= newButton(600,620,300,70,color.white,40,back,nil,"ghost"),
},
back= newButton(1160,600,160,160,color.white,55,scene.back,nil,"sound"),
},
setting_sound={
sfx=newSlider(180,150,400,8,40,function()SFX("blip_1")end, function()return setting.sfx end,function(i)setting.sfx=i end,nil,"bgm"),
bgm=newSlider(750,150,400,8,40,function()BGM(bgmPlaying or"blank")end, function()return setting.bgm end,function(i)setting.bgm=i end,nil,"vib"),
vib=newSlider(180,340,400,5,40,function()VIB(1)end, function()return setting.vib end,function(i)setting.vib=i end,nil,"voc"),
voc=newSlider(750,340,400,8,40,function()VOICE("nya")end, function()return setting.voc end,function(i)setting.voc=i end,nil,"back"),
back=newButton(640,620,300,70,color.white,40,back,nil,"sfx"),
game= newButton(200,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_game")end, nil,"graphic"),
graphic=newButton(1080,80,240,80,color.lightGreen,40,function()scene.swapTo("setting_graphic")end, nil,"sfx"),
sfx=newSlider(180,250,400,10,40,function()SFX("blip_1")end, function()return setting.sfx end,function(i)setting.sfx=i end,nil,"bgm"),
bgm=newSlider(750,250,400,10,40,function()BGM(bgmPlaying or"blank")end, function()return setting.bgm end,function(i)setting.bgm=i end,nil,"vib"),
vib=newSlider(180,440,400,5,40,function()VIB(1)end, function()return setting.vib end,function(i)setting.vib=i end,nil,"voc"),
voc=newSlider(750,440,400,10,40,function()VOICE("nya")end, function()return setting.voc end,function(i)setting.voc=i end,nil,"back"),
back=newButton(1160,600,160,160,color.white,55,scene.back,nil,"game"),
},
setting_control={
back=newButton(840,630,180,60,color.white,40,back),
setting_key={
back=newButton(1140,650,200,80,color.white,50,scene.back),
},
setting_touch={
hide= newButton(640,210,500,80,color.white,45,function()
setting.virtualkeySwitch=not setting.virtualkeySwitch
end),
default=newButton(450,310,170,80,color.white,40,function()
for K=1,#virtualkey do
local b,b0=virtualkey[K],virtualkeySet[defaultSel][K]
b[1],b[2],b[3],b[4]=b0[1],b0[2],b0[3],b0[4]
end--Default virtualkey
hide= newSwitch(810,140,45,function()return setting.VKSwitch end,function()setting.VKSwitch=not setting.VKSwitch end),
track= newSwitch(810,220,45,function()return setting.VKTrack end,function()setting.VKTrack=not setting.VKTrack end),
tkset= newButton(450,220,170,80,color.white,30,function()
scene.push()
scene.swapTo("setting_trackSetting")
end,function()return not setting.VKTrack end),
default=newButton(450,320,170,80,color.white,40,function()
local D=virtualkeySet[defaultSel]
for i=1,#VK_org do
VK_org[i].ava=false
end
for n=1,#D do
local T=D[n]
if T[1]then
local B=VK_org[n]
B.ava=true
B.x,B.y,B.r=T[2],T[3],T[4]
end
end--Replace keys
defaultSel=defaultSel%5+1
end),
snap= newButton(640,310,170,80,color.white,40,function()
snap= newButton(640,320,170,80,color.white,40,function()
snapLevel=snapLevel%6+1
end),
alpha= newButton(830,310,170,80,color.white,45,function()
setting.virtualkeyAlpha=(setting.virtualkeyAlpha+1)%11
--VK=T,70,50,27/T,130,50,27/T,190,50,27/T,250,50,27/T,310,50,27/T,370,50,27/T,430,50,27/T,490,50,27/T,550,50,27/T,610,50,27/T,670,50,27/T,730,50,27/T,790,50,27/T,850,50,27/T,910,50,27/T,970,50,27/T,739,789,897/T,1090,50,27/T,1150,50,27/T,1210,50,27
alpha= newButton(830,320,170,80,color.white,45,function()
setting.VKAlpha=(setting.VKAlpha+1)%11
--Adjust virtualkey alpha
end),
icon= newButton(450,410,170,80,color.white,45,function()
setting.virtualkeyIcon=not setting.virtualkeyIcon
icon= newButton(495,420,260,80,color.white,45,function()
setting.VKIcon=not setting.VKIcon
--Switch virtualkey icon
end),
size= newButton(830,410,170,80,color.white,45,function()
size= newButton(785,420,260,80,color.white,45,function()
if sel then
local b=virtualkey[sel]
b[4]=b[4]+10
if b[4]==150 then b[4]=40 end
b[3]=b[4]^2
local B=VK_org[sel]
B.r=B.r+10
if B.r>=150 then B.r=B.r-110 end
end
end),
back= newButton(640,410,170,80,color.white,45,back),
toggle= newButton(495,520,260,80,color.white,45,function()
scene.push()
scene.swapTo("setting_touchSwitch")
end),
back= newButton(785,520,260,80,color.white,45,scene.back),
},
setting_touchSwitch={
b1= newSwitch(300,80, 40,VKAdisp(1),VKAcode(1)),
b2= newSwitch(300,140, 40,VKAdisp(2),VKAcode(2)),
b3= newSwitch(300,200, 40,VKAdisp(3),VKAcode(3)),
b4= newSwitch(300,260, 40,VKAdisp(4),VKAcode(4)),
b5= newSwitch(300,320, 40,VKAdisp(5),VKAcode(5)),
b6= newSwitch(300,380, 40,VKAdisp(6),VKAcode(6)),
b7= newSwitch(300,440, 40,VKAdisp(7),VKAcode(7)),
b8= newSwitch(300,500, 40,VKAdisp(8),VKAcode(8)),
b9= newSwitch(300,560, 40,VKAdisp(9),VKAcode(9)),
b10= newSwitch(300,620, 40,VKAdisp(10),VKAcode(10)),
b11= newSwitch(760,80, 40,VKAdisp(11),VKAcode(11)),
b12= newSwitch(760,140, 40,VKAdisp(12),VKAcode(12)),
b13= newSwitch(760,200, 40,VKAdisp(13),VKAcode(13)),
b14= newSwitch(760,260, 40,VKAdisp(14),VKAcode(14)),
b15= newSwitch(760,320, 40,VKAdisp(15),VKAcode(15)),
b16= newSwitch(760,380, 40,VKAdisp(16),VKAcode(16)),
b17= newSwitch(760,440, 40,VKAdisp(17),VKAcode(17)),
b18= newSwitch(760,500, 40,VKAdisp(18),VKAcode(18)),
b19= newSwitch(760,560, 40,VKAdisp(19),VKAcode(19)),
b20= newSwitch(760,620, 40,VKAdisp(20),VKAcode(20)),
norm= newButton(1080,150,240,80,color.white,50,function()for i=1,20 do VK_org[i].ava=i<11 end end),
pro= newButton(1080,300,240,80,color.white,40,function()for i=1,20 do VK_org[i].ava=true end end),
back= newButton(1080,600,240,80,color.white,50,scene.back),
},
setting_trackSetting={
VKDodge= newSwitch(400,200, 40,function()return setting.VKDodge end,function()setting.VKDodge=not setting.VKDodge end),
VKTchW= newSlider(140,310,1000,10,40,nil,function()return setting.VKTchW end,function(i)setting.VKTchW=i;setting.VKCurW=math.max(setting.VKCurW,i)end),
VKCurW= newSlider(140,370,1000,10,40,nil,function()return setting.VKCurW end,function(i)setting.VKCurW=i;setting.VKTchW=math.min(setting.VKTchW,i)end),
back= newButton(1080,600,240,80,color.white,50,scene.back),
},
help={
his= newButton(1050,520,230,60,color.white,40,function()gotoScene("history")end,nil,"back"),
qq= newButton(1050,600,230,60,color.white,40,function()sys.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end, function()return mobile end,"his"),
back= newButton(640, 600,180,60,color.white,40,back,nil,"qq"),
his= newButton(1050,520,230,60,color.white,40,function()scene.push()scene.swapTo("history")end,nil,"back"),
qq= newButton(1050,600,230,60,color.white,40,function()love.system.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end, function()return mobile end,"his"),
back= newButton(640, 600,180,60,color.white,40,scene.back,nil,"qq"),
},
history={
prev= newButton(1155,170,180,180,color.white,70,function()love.keypressed("up")end,function()return sel==1 end),
next= newButton(1155,400,180,180,color.white,70,function()love.keypressed("down")end,function()return sel==#updateLog-22 end),
back= newButton(1155,600,180,90,color.white,40,back),
back= newButton(1155,600,180,90,color.white,40,scene.back),
},
stat={
path= newButton(980,590,250,60,color.white,30,function()sys.openURL(fs.getSaveDirectory())end,function()return mobile end,"back"),
back= newButton(640,590,180,60,color.white,40,back,nil,"path"),
path= newButton(980,620,250,60,color.white,30,function()love.system.openURL(love.filesystem.getSaveDirectory())end,function()return mobile end,"back"),
back= newButton(640,620,180,60,color.white,40,scene.back,nil,"path"),
},
}
for S,L in next,Widget do

654
main.lua

File diff suppressed because it is too large Load Diff

595
paint.lua
View File

@@ -1,26 +1,10 @@
local gc=love.graphics
local mt=love.math
local gmatch=string.gmatch
local setFont=setFont
local int,abs,rnd,max,min,sin=math.floor,math.abs,math.random,math.max,math.min,math.sin
local format=string.format
local Timer=love.timer.getTime
local scr=scr
local attackColor={
{color.darkGrey,color.white},
{color.grey,color.white},
{color.lightPurple,color.white},
{color.lightRed,color.white},
{color.darkGreen,color.cyan},
}
local frameColor={
[0]=color.white,
color.lightGreen,
color.lightBlue,
color.lightPurple,
color.lightOrange,
}
local modeLevelColor={
EASY=color.cyan,
NORMAL=color.green,
@@ -66,6 +50,10 @@ local function dataOpt(i)
return stat.pc
elseif i==14 then
return format("%0.2f",stat.atk/stat.row)
elseif i==15 then
return stat.extraPiece
elseif i==16 then
return max(100-int(stat.extraRate/stat.piece*10000)*.01,0).."%"
end
end
local statOptL={
@@ -88,6 +76,8 @@ local function statOpt(i)
return stat.pc
elseif i==17 then
return format("%0.2f",stat.atk/stat.row)
elseif i==18 then
return stat.extraPiece.."["..(int(stat.extraRate/stat.piece*10000)*.01).."%]"
end
end
local miniTitle_rect={
@@ -102,7 +92,8 @@ local miniTitle_rect={
}
local function stencil_miniTitle()
for i=1,#miniTitle_rect do
gc.rectangle("fill",unpack(miniTitle_rect[i]))
local a,b,c,d=unpack(miniTitle_rect[i])
gc.rectangle("fill",250+a*30,150+b*30,c*30,d*30)
end
end
@@ -179,17 +170,6 @@ textFX={
gc.pop()
end,
}
local function drawDial(x,y,speed)
gc.setColor(1,1,1)
mStr(int(speed),x,y-18)
gc.draw(dialCircle,x,y,nil,nil,nil,32,32)
gc.setColor(1,1,1,.6)
gc.draw(dialNeedle,x,y,2.094+(speed<=175 and .02094*speed or 4.712-52.36/(speed-125)),nil,nil,5,4)
end
local function drawPixel(y,x,id)
gc.draw(blockSkin[id],30*x-30,600-30*y)
end
local function drawAtkPointer(x,y)
local t=sin(Timer()*20)
gc.setColor(.2,.7+t*.2,1,.6+t*.4)
@@ -198,100 +178,113 @@ local function drawAtkPointer(x,y)
gc.setColor(0,.6,1,.8-a)
gc.circle("line",x,y,30*(1+a),6)
end
local function VirtualkeyPreview()
for i=1,#virtualkey do
local c=sel==i and .8 or 1
gc.setColor(c,c,c,setting.virtualkeyAlpha*.1)
local b=virtualkey[i]
gc.setLineWidth(b[4]*.07)
gc.circle("line",b[1],b[2],b[4]-5)
if setting.virtualkeyIcon then gc.draw(virtualkeyIcon[i],b[1],b[2],nil,b[4]*.025,nil,18,18)end
if setting.VKSwitch then
for i=1,#VK_org do
local B=VK_org[i]
if B.ava then
local c=sel==i and .6 or 1
gc.setColor(c,1,c,setting.VKAlpha*.1)
gc.setLineWidth(B.r*.07)
gc.circle("line",B.x,B.y,B.r)
if setting.VKIcon then gc.draw(VKIcon[i],B.x,B.y,nil,B.r*.025,nil,18,18)end
end
end
end
end
local function drawVirtualkey()
local a=setting.virtualkeyAlpha*.1
local a=setting.VKAlpha*.1
for i=1,#virtualkey do
if i~=9 or modeEnv.Fkey then
local p,b=virtualkeyDown[i],virtualkey[i]
if p then gc.setColor(.7,.7,.7,a)
else gc.setColor(1,1,1,a)
end
gc.setLineWidth(b[4]*.07)
gc.circle("line",b[1],b[2]+virtualkeyPressTime[i],b[4]-5)
if setting.virtualkeyIcon then gc.draw(virtualkeyIcon[i],b[1],b[2]+virtualkeyPressTime[i],nil,b[4]*.025,nil,18,18)end
if virtualkeyPressTime[i]>0 then
gc.setColor(1,1,1,a*virtualkeyPressTime[i]*.1)
gc.circle("line",b[1],b[2],b[4]*(1.4-virtualkeyPressTime[i]*.04))
local B=virtualkey[i]
if B.ava then
local _=virtualkeyDown[i]and gc.setColor(.7,.7,.7,a)or gc.setColor(1,1,1,a)--Dark magic
gc.setLineWidth(B.r*.07)
local ΔY=virtualkeyPressTime[i]
gc.circle("line",B.x,B.y+ΔY,B.r)--Outline circle
if setting.VKIcon then
gc.draw(VKIcon[i],B.x,B.y+ΔY,nil,B.r*.025,nil,18,18)
end--Icon
if ΔY>0 then
gc.setColor(1,1,1,a*ΔY*.1)
gc.circle("line",B.x,B.y,B.r*(1.4-ΔY*.04))
end--Ripple
end
end
end
end
local scs={{1,2},nil,nil,nil,nil,{1.5,1.5},{0.5,2.5}}for i=2,5 do scs[i]=scs[1]end
local matrixT={}for i=0,15 do matrixT[i]={}for j=0,8 do matrixT[i][j]=mt.noise(i,j)+2 end end
local Pnt={}
Pnt.BG={
none=function()
local Pnt={BG={}}
function Pnt.BG.none()
gc.clear(.15,.15,.15)
end,
grey=function()
end
function Pnt.BG.grey()
gc.clear(.3,.3,.3)
end,
lightGrey=function()
end
function Pnt.BG.lightGrey()
gc.clear(.5,.5,.5)
end,
glow=function()
end
function Pnt.BG.glow()
local t=((sin(Timer()*.5)+sin(Timer()*.7)+sin(Timer()*.9+1)+sin(Timer()*1.5)+sin(Timer()*2+3))+5)*.05
gc.clear(t,t,t)
end,
game1=function()
end
function Pnt.BG.rgb()
gc.clear(
sin(Timer()*1.2)*.15+.5,
sin(Timer()*1.5)*.15+.5,
sin(Timer()*1.9)*.15+.5
)
end
function Pnt.BG.strap()
gc.setColor(1,1,1)
local x=Timer()%32*40
gc.draw(background2,x,0,nil,10)
gc.draw(background2,x-1280,0,nil,10)
end
function Pnt.BG.flink()
local t=.13-Timer()%3%1.7
if t<.25 then
gc.clear(t,t,t)
else
gc.clear(0,0,0)
end
end
function Pnt.BG.game1()
gc.setColor(1,1,1)
gc.draw(background1,640,360,Timer()*.15,12,nil,64,64)
end,--Rainbow
game2=function()
end--Rainbow
function Pnt.BG.game2()
gc.setColor(1,.5,.5)
gc.draw(background1,640,360,Timer()*.2,12,nil,64,64)
end,--Red rainbow
game3=function()
end--Red rainbow
function Pnt.BG.game3()
gc.setColor(.6,.6,1)
gc.draw(background1,640,360,Timer()*.25,12,nil,64,64)
end,--Blue rainbow
game4=function()
end--Blue rainbow
function Pnt.BG.game4()
gc.setColor(.1,.5,.5)
local x=Timer()%4*320
gc.draw(background2,x,0,nil,10)
gc.draw(background2,x-1280,0,nil,10)
end,--Fast strap
game5=function()
end--Fast strap
function Pnt.BG.game5()
local t=2.5-Timer()%20%6%2.5
if t<.5 then gc.clear(t,t,t)
else gc.clear(0,0,0)
end
end,--Lightning
game6=function()
end--Lightning
local scs={1,2,1,2,1,2,1,2,1,2,1.5,1.5,.5,2.5}
function Pnt.BG.game6()
local t=1.2-Timer()%10%3%1.2
if t<.5 then gc.clear(t,t,t)
else gc.clear(0,0,0)
end
gc.setColor(.3,.3,.3)
local r=7-int(Timer()*.5)%7
gc.draw(mouseBlock[r],640,360,Timer()%3.1416*6,400,400,scs[r][2]-.5,#blocks[r][0]-scs[r][1]+.5)
end,--Fast lightning&spining tetromino
rgb=function()
gc.clear(
sin(Timer()*1.2)*.15+.5,
sin(Timer()*1.5)*.15+.5,
sin(Timer()*1.9)*.15+.5
)
end,
strap=function()
gc.setColor(1,1,1)
local x=Timer()%32*40
gc.draw(background2,x,0,nil,10)
gc.draw(background2,x-1280,0,nil,10)
end,
matrix=function()
gc.draw(miniBlock[r],640,360,Timer()%3.1416*6,400,400,scs[2*r]-.5,#blocks[r][0]-scs[2*r-1]+.5)
end--Fast lightning&spining tetromino
local matrixT={}for i=0,15 do matrixT[i]={}for j=0,8 do matrixT[i][j]=love.math.noise(i,j)+2 end end
function Pnt.BG.matrix()
gc.clear(.15,.15,.15)
for i=0,15 do
for j=0,8 do
@@ -300,8 +293,7 @@ matrix=function()
gc.rectangle("fill",80*i,80*j,80,80)
end
end
end,
}
end
function Pnt.load()
gc.setLineWidth(4)
@@ -315,14 +307,14 @@ function Pnt.load()
mStr(loadTip,640,400)
end
function Pnt.intro()
gc.push()
gc.translate(250,150)
gc.scale(30)
gc.stencil(stencil_miniTitle,"replace",1)
gc.stencil(stencil_miniTitle,"replace",1)
gc.setStencilTest("equal",1)
gc.setColor(1,1,1,min(count,80)*.005)
gc.rectangle("fill",0,0,26,14)
gc.pop()
gc.push("transform")
gc.translate(250,150)
gc.scale(30)
gc.rectangle("fill",0,0,26,14)
gc.pop()
gc.setColor(1,1,1,.06)
for i=41,5,-2 do
gc.setLineWidth(i)
@@ -332,13 +324,15 @@ function Pnt.intro()
end
function Pnt.main()
gc.setColor(1,1,1)
gc.draw(coloredTitleImage,280,30,nil,1.3)
gc.draw(drawableText.warning,570,128)
gc.draw(coloredTitleImage,60,30,nil,1.3)
gc.draw(drawableText.warning,595-drawableText.warning:getWidth(),128)
setFont(35)
gc.print(gameVersion,290,125)
gc.print(system,840,95)
mStr(modeLevel[modeID[modeSel]][levelSel],160,180)
mStr(text.modeName[modeSel],160,380)
gc.print(gameVersion,70,125)
gc.print(system,610,100)
gc.print(modeLevel[modeID[modeSel]][levelSel],600,373)
setFont(30)
gc.print(text.modeName[modeSel],600,414)
players[1]:demoDraw()
end
function Pnt.mode()
gc.setColor(1,1,1)
@@ -415,7 +409,7 @@ function Pnt.draw()
for y=1,20 do for x=1,10 do
local B=preField[y][x]
if B>0 then
drawPixel(y,x,B)
gc.draw(blockSkin[B],30*x-30,600-30*y)
elseif B==-1 then
gc.line(30*x-25,605-30*y,30*x-5,625-30*y)
gc.line(30*x-25,625-30*y,30*x-5,605-30*y)
@@ -428,12 +422,12 @@ function Pnt.draw()
gc.translate(-200,-60)
if clearSureTime>0 then
gc.setColor(1,1,1,clearSureTime*.02)
gc.draw(drawableText.question,1100,570)
gc.draw(drawableText.question,760,11)
end
if pen>0 then
gc.setLineWidth(13)
gc.setColor(blockColor[pen])
gc.rectangle("line",945,605,70,70)
gc.rectangle("line",746,460,70,70)
elseif pen==-1 then
gc.setLineWidth(5)
gc.setColor(.9,.9,.9)
@@ -443,268 +437,8 @@ function Pnt.draw()
end
function Pnt.play()
for p=1,#players do
P=players[p]
if P.small then
P.frameWait=P.frameWait-1
if P.frameWait==0 then
P.frameWait=8
gc.setCanvas(P.canvas)
gc.clear(0,0,0,.4)
gc.push("transform")
gc.origin()
gc.setColor(1,1,1,P.result and max(20-P.endCounter,0)*.05 or 1)
local F=P.field
for j=1,#F do
for i=1,10 do if F[j][i]>0 then
gc.draw(blockSkinmini[F[j][i]],6*i-6,120-6*j)
end end
end--Field
if P.alive then
gc.setLineWidth(2)
gc.setColor(frameColor[P.strength])gc.rectangle("line",1,1,58,118)
end--Draw boarder
if modeEnv.royaleMode then
gc.setColor(1,1,1)
for i=1,P.strength do
gc.draw(badgeIcon,12*i-7,4,nil,.5)
end
end
if P.result then
gc.setColor(1,1,1,min(P.endCounter,60)*.01)
setFont(22)mStr(P.result,32,47)
setFont(20)mStr(P.rank,30,82)
end
gc.pop()
gc.setCanvas()
--draw content
end
gc.setColor(1,1,1)
gc.draw(P.canvas,P.x,P.y,nil,P.size*10)
if P.killMark then
gc.setLineWidth(3)
gc.setColor(1,0,0,min(P.endCounter,25)*.04)
gc.circle("line",P.centerX,P.centerY,(840-20*min(P.endCounter,30))*P.size)
end
--draw Canvas
else
gc.push("transform")
gc.translate(P.x,P.y)gc.scale(P.size)--Position
gc.setColor(0,0,0,.6)gc.rectangle("fill",0,0,600,690)--Background
gc.setLineWidth(7)
gc.setColor(frameColor[P.strength])gc.rectangle("line",0,0,600,690,3)--Big frame
gc.translate(150+P.fieldOffX,70+P.fieldOffY)
if P.gameEnv.grid then
gc.setLineWidth(1)
gc.setColor(1,1,1,.2)
for x=1,9 do gc.line(30*x,-10,30*x,600)end
for y=0,19 do
y=30*(y-int(P.fieldBeneath/30))+P.fieldBeneath
gc.line(0,y,300,y)
end
end--Grid lines
gc.translate(0,P.fieldBeneath)
gc.setScissor(scr.x+P.absFieldX*scr.k,scr.y+P.absFieldY*scr.k,300*P.size*scr.k,610*P.size*scr.k)
local dy,stepY=0,setting.smo and(P.falling/(P.gameEnv.fall+1))^2.5*30 or 30
local h=1
for j=int(P.fieldBeneath/30+1),#P.field do
while j==P.clearing[h]and P.falling>-1 do
h=h+1
dy=dy+stepY
gc.translate(0,-stepY)
gc.setColor(1,1,1,P.falling/P.gameEnv.fall)
gc.rectangle("fill",0,630-30*j,320,stepY)
end
for i=1,10 do
if P.field[j][i]>0 then
gc.setColor(1,1,1,min(P.visTime[j][i]*.05,1))
drawPixel(j,i,P.field[j][i])
end
end
end--Field
gc.translate(0,dy)
for i=1,#P.shade do
local S=P.shade[i]
gc.setColor(1,1,1,S[1]*.12)
for x=S[3],S[5]do
for y=S[6],S[4]do
drawPixel(y,x,S[2])
end
end
end--shade FX
if P.waiting==-1 then
if P.gameEnv.ghost then
gc.setColor(1,1,1,.3)
for i=1,P.r do for j=1,P.c do
if P.cur.bk[i][j]then
drawPixel(i+P.y_img-1,j+P.curX-1,P.cur.color)
end
end end
end--Ghost
-- local dy=setting.smo and(P.y_img~=P.curY and or 1)^4*30 or 0
local dy
if setting.smo then
if P.y_img~=P.curY then
dy=(min(P.dropDelay,1e99)/P.gameEnv.drop-1)*30
else
dy=0
end
--[[
if P.y_img~=P.curY then
dy=(min(P.dropDelay,8e98)/P.gameEnv.drop)^4*30
else
dy=(min(P.lockDelay,8e98)/P.gameEnv.lock)^(P.gameEnv._20G and 3 or 7)*30
end
]]
else
dy=0
end
gc.translate(0,-dy)
local trans=P.lockDelay/P.gameEnv.lock
if P.gameEnv.block then
gc.setColor(1,1,1,trans)
for i=1,P.r do for j=1,P.c do
if P.cur.bk[i][j]then
gc.rectangle("fill",30*(j+P.curX-1)-33,597-30*(i+P.curY-1),36,36)
end
end end--BlockShade(lockdelay indicator)
gc.setColor(1,1,1)
for i=1,P.r do for j=1,P.c do
if P.cur.bk[i][j]then
drawPixel(i+P.curY-1,j+P.curX-1,P.cur.color)
end
end end--Block
end
if P.gameEnv.center then
gc.setColor(1,1,1,trans)
local x=30*(P.curX+P.sc[2]-1)-30+15
gc.draw(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(spinCenter,x,600-30*(P.y_img+P.sc[1]-1)+15,nil,nil,nil,4,4)
goto E
end--Rotate center
gc.translate(0,dy)
end
::E::
gc.setScissor()--In-playField things
gc.setColor(1,1,1)
gc.draw(PTC.dust[p])
gc.translate(0,-P.fieldBeneath)
gc.setBlendMode("replace","alphamultiply")--SPEED UPUP(?)
gc.setLineWidth(2)
gc.rectangle("line",-1,-11,302,612)--Draw boarder
gc.rectangle("line",301,0,15,601)--Draw atkBuffer boarder
local h=0
for i=1,#P.atkBuffer do
local A=P.atkBuffer[i]
local bar=A.amount*30
if h+bar>600 then bar=600-h end
if not A.sent then
if A.time<20 then
bar=bar*(20*A.time)^.5*.05
--Appear
end
if A.countdown>0 then
gc.setColor(attackColor[A.lv][1])
gc.rectangle("fill",303,599-h,11,-bar+3)
gc.setColor(attackColor[A.lv][2])
gc.rectangle("fill",303,599-h+(-bar+3),11,-(-bar+3)*(1-A.countdown/A.cd0))
--Timing
else
local t=sin((Timer()-i)*30)*.5+.5
local c1,c2=attackColor[A.lv][1],attackColor[A.lv][2]
gc.setColor(c1[1]*t+c2[1]*(1-t),c1[2]*t+c2[2]*(1-t),c1[3]*t+c2[3]*(1-t))
gc.rectangle("fill",303,599-h,11,-bar+3)
--Warning
end
else
gc.setColor(attackColor[A.lv][1])
bar=bar*(20-A.time)*.05
gc.rectangle("fill",303,599-h,11,-bar+2)
--Disappear
end
h=h+bar
end--Buffer line
local a,b=P.b2b,P.b2b1 if a>b then a,b=b,a end
gc.setColor(.8,1,.2)
gc.rectangle("fill",-14,599,11,-b*.5)
gc.setColor(P.b2b<40 and color.white or P.b2b<=1e3 and color.lightRed or color.lightBlue)
gc.rectangle("fill",-14,599,11,-a*.5)
if Timer()%1<.5 then
gc.rectangle("fill",-15,b<40 and 578.5 or 98.5,13,3)
end
gc.setColor(1,1,1)
gc.rectangle("line",-16,-3,15,604)--Draw b2b bar boarder
--B2B indictator
gc.translate(-P.fieldOffX,-P.fieldOffY)
gc.setBlendMode("alpha")
if P.gameEnv.hold then
mDraw(drawableText.hold,-82,-10)
if P.holded then gc.setColor(.6,.6,.6)end
for i=1,#P.hold.bk do
local B=P.hold.bk
for j=1,#B[1]do
if B[i][j]then
drawPixel(i+17.5-#B*.5,j-2.7-#B[1]*.5,P.hold.color)
end
end
end
end--Hold
gc.setColor(1,1,1)
mDraw(drawableText.next,381,-10)
local N=1
::L::
if N<=P.gameEnv.next and P.next[N]then
local b,c=P.next[N].bk,P.next[N].color
for i=1,#b do for j=1,#b[1] do
if b[i][j]then
drawPixel(i+20-2.4*N-#b*.5,j+12.7-#b[1]*.5,c)
end
end end
N=N+1
goto L
end
--Next
gc.setColor(.8,.8,.8)
gc.draw(drawableText.modeName,-135,-65)
gc.draw(drawableText.levelName,437-drawableText.levelName:getWidth(),-65)
gc.setColor(1,1,1)
if frame<180 then
local count=179-frame
gc.push("transform")
gc.translate(155,220)
setFont(100)
if count%60>45 then gc.scale(1+(count%60-45)^2*.01,1)end
mStr(int(count/60+1),0,0)
gc.pop()
end--Draw starting counter
for i=1,#P.bonus do
P.bonus[i]:draw(min((30-abs(P.bonus[i].t-30))*.05,1)*(not P.bonus[i].inf and #P.field>(9-P.bonus[i].dy*.0333)and .7 or 1))
end--Effects
setFont(30)
gc.setColor(1,1,1)
mStr(format("%.2f",P.stat.time),-82,518)--Time
mStr(P.score1,-82,560)--Score
gc.draw(drawableText.bpm,390,490)
gc.draw(drawableText.kpm,350,583)
setFont(30)
drawDial(360,520,P.dropSpeed)
drawDial(405,575,P.keySpeed)
--Speed dials
gc.setColor(1,1,1)
if mesDisp[curMode.id]then mesDisp[curMode.id]()end--Other messages
if modeEnv.royaleMode then
if P.atkMode then
gc.setColor(1,.8,0,P.swappingAtkMode*.02)
gc.rectangle("fill",RCPB[2*P.atkMode-1],RCPB[2*P.atkMode],90,35,8,4)
end
gc.setColor(1,1,1,P.swappingAtkMode*.025)
gc.draw(royaleCtrlPad)
end
gc.pop()
end
end--Draw players
players[p]:draw()
end
gc.setLineWidth(5)
for i=1,#FX_attack do
local A=FX_attack[i]
@@ -726,9 +460,9 @@ function Pnt.play()
gc.rotate(A.t*.1)
gc.circle("fill",0,0,A.rad,A.corner)
gc.pop()
end
end--FX animation
gc.setColor(1,1,1)
if setting.virtualkeySwitch then drawVirtualkey()end
if setting.VKSwitch then drawVirtualkey()end
if modeEnv.royaleMode then
for i=1,#FX_badge do
local b=FX_badge[i]
@@ -742,25 +476,23 @@ function Pnt.play()
gc.draw(badgeIcon,b[3]-14,b[4]-14)
end
end
P=players[1]
local P=players[1]
gc.setLineWidth(5)
gc.setColor(.8,1,0,.2)
for i=1,#players[1].atker do
local p=players[1].atker[i]
for i=1,#P.atker do
local p=P.atker[i]
gc.line(p.centerX,p.centerY,P.centerX,P.centerY)
end
if P.atkMode~=4 then
if P.atking then drawAtkPointer(P.atking.centerX,P.atking.centerY)end
else
for i=1,#players[1].atker do
local p=players[1].atker[i]
for i=1,#P.atker do
local p=P.atker[i]
drawAtkPointer(p.centerX,p.centerY)
end
end
end
if restartCount>0 then
-- gc.setColor(1,.7,.7,.5+restartCount*.02)
-- gc.arc("fill",640,360,735,-1.5708,restartCount*0.3696-1.5708)
gc.setColor(0,0,0,restartCount/20)
gc.rectangle("fill",0,0,1280,720)
end
@@ -774,68 +506,89 @@ function Pnt.pause()
if pauseCount>0 then
gc.print(text.pauseCount..":["..pauseCount.."] "..format("%0.2f",pauseTime).."s",110,150)
end
for i=1,7 do
for i=1,8 do
gc.print(text.stat[i+3],110,30*i+270)
gc.print(dataOpt(i),305,30*i+270)
end
for i=8,14 do
gc.print(text.stat[i+3],860,30*i+60)
gc.print(dataOpt(i),1000,30*i+60)
for i=9,16 do
gc.print(text.stat[i+3],860,30*i+30)
gc.print(dataOpt(i),1050,30*i+30)
end
setFont(40)
if system~="Android"then
mStr(text.space.."/"..text.enter,640,335)
mStr(text.space.."/"..text.enter,640,190)
mStr("Ctrl+R",640,351)
gc.print("ESC",610,506)
end
mDraw(gamefinished and drawableText.finish or drawableText.pause,640,60-10*(5-pauseTimer*.1)^1.5)
end
function Pnt.setting_game()
gc.setColor(1,1,1)
mDraw(drawableText.setting_game,640,15)
setFont(40)
mStr("DAS:"..setting.das,260,95)
mStr("ARR:"..setting.arr,560,95)
mStr("DAS:"..setting.das,290,205)
mStr("ARR:"..setting.arr,610,205)
setFont(28)
mStr(text.softdropdas..setting.sddas,260,213)
mStr(text.softdroparr..setting.sdarr,560,213)
mStr(text.softdropdas..setting.sddas,290,323)
mStr(text.softdroparr..setting.sdarr,610,323)
end
function Pnt.setting_graphic()
gc.setColor(1,1,1)
gc.draw(blockSkin[7-int(Timer()*2)%7],1020,420,nil,2)
mDraw(drawableText.setting_graphic,640,15)
gc.draw(blockSkin[7-int(Timer()*2)%7],940,440,nil,2)
end
function Pnt.setting_control()
function Pnt.setting_sound()
gc.setColor(1,1,1)
mDraw(drawableText.setting_sound,640,15)
end
function Pnt.setting_key()
local a=.3+sin(Timer()*15)*.1
if keyboardSetting then
gc.setColor(1,.5,.5,a)
else
gc.setColor(.9,.9,.9,a)
end
gc.rectangle("fill",240,40*keyboardSet-10,200,40)
if joystickSetting then
gc.setColor(1,.5,.5,a)
else
gc.setColor(.9,.9,.9,a)
end
gc.rectangle("fill",440,40*joystickSet-10,200,40)
if keyboardSetting then gc.setColor(1,.3,.3,a)else gc.setColor(1,.7,.7,a)end
gc.rectangle("fill",
keyboardSet<11 and 240 or 840,
45*keyboardSet+20-450*int(keyboardSet/11),
200,45
)
if joystickSetting then gc.setColor(.3,.3,.1,a)else gc.setColor(.7,.7,1,a)end
gc.rectangle("fill",
joystickSet<11 and 440 or 1040,
45*joystickSet+20-450*int(joystickSet/11),
200,45
)
--Selection rect
gc.setColor(1,.3,.3)
mDraw(drawableText.keyboard,340,35)
mDraw(drawableText.keyboard,940,35)
gc.setColor(.3,.3,1)
mDraw(drawableText.joystick,540,35)
mDraw(drawableText.joystick,1140,35)
gc.setColor(1,1,1)
setFont(25)
for y=1,13 do
mStr(text.actName[y],150,40*y-5)
for x=1,2 do
mStr(setting.keyMap[curBoard+x*8-8][y],200*x+140,40*y-3)
setFont(31)
for N=1,20 do
if N<11 then
gc.printf(text.actName[N],47,45*N+22,180,"right")
mStr(setting.keyMap[curBoard][N],340,45*N+22)
mStr(setting.keyMap[curBoard+8][N],540,45*N+22)
else
gc.printf(text.actName[N],647,45*N-428,180,"right")
mStr(setting.keyMap[curBoard][N],940,45*N-428)
mStr(setting.keyMap[curBoard+8][N],1040,45*N-428)
end
gc.line(40,40*y-10,640,40*y-10)
end
for x=1,4 do
gc.line(200*x-160,30,200*x-160,550)
gc.setLineWidth(2)
for x=40,1240,200 do
gc.line(x,65,x,515)
end
for y=65,515,45 do
gc.line(40,y,1240,y)
end
gc.line(40,550,640,550)
mDraw(drawableText.keyboard,340,0)
mDraw(drawableText.joystick,540,0)
gc.draw(drawableText.setting2Help,50,620)
setFont(40)
gc.print("P"..int(curBoard*.5+.5).."/P4",420,560)
gc.print(curBoard.."/8",580,560)
gc.print("Player:",170,590)
gc.print(int(curBoard*.5+.5),300,590)
gc.print(curBoard.."/8",580,590)
gc.draw(drawableText.ctrlSetHelp,50,650)
end
function Pnt.setting_touch()
VirtualkeyPreview()
@@ -851,13 +604,21 @@ function Pnt.setting_touch()
end
end
end
function Pnt.help()
setFont(32)
function Pnt.setting_trackSetting()
gc.setColor(1,1,1)
for i=1,11 do
gc.printf(text.help[i],140,15+43*i,1000,"center")
mDraw(drawableText.VKTchW,140+50*setting.VKTchW,260)
mDraw(drawableText.VKOrgW,140+50*setting.VKTchW+50*setting.VKCurW,320)
mDraw(drawableText.VKCurW,640+50*setting.VKCurW,380)
end
function Pnt.help()
setFont(30)
gc.setColor(1,1,1)
for i=1,#text.help do
gc.printf(text.help[i],140,10+40*i,1000,"center")
end
gc.draw(titleImage,250,600,.2,1+.05*sin(Timer()*2),nil,206,35)
setFont(24)
gc.print(text.used,30,330)
gc.draw(titleImage,280,620,.1,1+.05*sin(Timer()*2),nil,206,35)
gc.setLineWidth(5)
gc.rectangle("line",17,17,260,260)
gc.rectangle("line",1077,17,186,186)
@@ -872,7 +633,7 @@ end
function Pnt.stat()
setFont(28)
gc.setColor(1,1,1)
for i=1,17 do
for i=1,18 do
gc.print(text.stat[i],400,30*i-5)
gc.print(statOpt(i),720,30*i-5)
end

2358
player.lua Normal file

File diff suppressed because it is too large Load Diff

212
scene.lua Normal file
View File

@@ -0,0 +1,212 @@
local scene={
cur="load",--Current scene
swapping=false,--ifSwapping
swap={
tar=nil, --Swapping target
style=nil, --Swapping target
mid=nil, --Loading point
time=nil, --Full swap time
draw=nil, --Swap draw
},
seq={"quit","slowFade"},--Back sequence
}
local sceneInit={
quit=love.event.quit,
load=function()
loading=1--Loading mode
loadnum=1--Loading counter
loadprogress=0--Loading bar(0~1)
loadTip=text.tips[math.random(#text.tips)]
end,
intro=function()
count=0
BGM("blank")
end,
main=function()
curBG="none"
BGM("blank")
destroyPlayers()
modeEnv={}
if not players[1]then
newDemoPlayer(1,900,35,1.1)
end--create demo player
collectgarbage()
end,
music=function()
if bgmPlaying then
for i=1,#musicID do
if musicID[i]==bgmPlaying then
sel=i
return
end
end
else
sel=1
end
end,
mode=function()
curBG="none"
BGM("blank")
destroyPlayers()
end,
custom=function()
sel=sel or 1
destroyPlayers()
curBG=customRange.bg[customSel[12]]
BGM(customRange.bgm[customSel[13]])
end,
draw=function()
curBG="none"
clearSureTime=0
pen,sx,sy=1,1,1
end,
play=function()
love.keyboard.setKeyRepeat(false)
restartCount=0
if needResetGameData then
resetGameData()
needResetGameData=nil
else
BGM(modeEnv.bgm)
end
curBG=modeEnv.bg
end,
pause=function()
curBG=modeEnv.bg
end,
setting_game=function()
curBG="none"
end,
setting_graphic=function()
curBG="none"
end,
setting_sound=function()
curBG="none"
end,
setting_key=function()
curBoard=1
keyboardSet=1
joystickSet=1
keyboardSetting=false
joystickSetting=false
end,
setting_touch=function()
curBG="game2"
defaultSel=1
sel=nil
snapLevel=1
end,
setting_touchSwitch=function()
curBG="matrix"
end,
help=function()
curBG="none"
end,
history=function()
updateLog=require"updateLog"
curBG="lightGrey"
sel=1
end,
quit=function()
love.timer.sleep(.3)
love.event.quit()
end,
}
local swapDeck_data={
{4,0,1,1},{6,0,15,1},{5,0,9,1},{6,0,6,1},
{1,0,3,1},{3,0,12,1},{1,1,8,1},{2,1,4,2},
{3,2,13,2},{4,1,12,2},{5,2,1,2},{7,1,11,2},
{2,1,9,3},{3,0,6,3},{4,2,14,3},{1,0,4,4},
{7,1,1,4},{6,0,2,4},{5,2,6,4},{6,0,14,5},
{3,3,15,5},{4,0,7,6},{7,1,10,5},{5,0,2,6},
{2,1,1,7},{1,0,4,6},{4,1,13,5},{1,1,6,7},
{5,3,11,5},{3,2,11,7},{6,0,8,7},{4,2,12,8},
{7,0,8,9},{1,0,2,8},{5,2,4,8},{6,0,15,8},
}--Block id [ZSLJTOI] ,dir,x,y
local gc=love.graphics
local swap={
none={1,0,NULL},
flash={8,1,function()gc.clear(1,1,1)end},
fade={30,15,function(t)
local t=t>15 and 2-t/15 or t/15
gc.setColor(0,0,0,t)
gc.rectangle("fill",0,0,1280,720)
end},
slowFade={120,40,function(t)
local t=t>40 and 1.5-t/80 or t/40
gc.setColor(0,0,0,t)
gc.rectangle("fill",0,0,1280,720)
end},
deck={50,8,function(t)
gc.setColor(1,1,1)
if t>8 then
local t=t<15 and 15 or t
for i=1,51-t do
local bn=swapDeck_data[i][1]
local b=blocks[bn][swapDeck_data[i][2]]
local cx,cy=swapDeck_data[i][3],swapDeck_data[i][4]
for y=1,#b do for x=1,#b[1]do
if b[y][x]then
gc.draw(blockSkin[bn],80*(cx+x-2),80*(10-cy-y),nil,8/3)
end
end end
end
end
if t<17 then
gc.setColor(1,1,1,1-(t>8 and t-8 or 8-t)*.125)
gc.rectangle("fill",0,0,1280,720)
end
end},
}--Scene swapping animations
local backFunc={
load=love.event.quit,
pause=function()
love.keyboard.setKeyRepeat(true)
updateStat()
saveData()
clearTask("play")
end,
setting_game=function()
saveSetting()
end,
}
function scene.init(s)
if sceneInit[s]then sceneInit[s]()end
end
function scene.push(tar,style)
if not scene.swapping then
local m=#scene.seq
scene.seq[m+1]=tar or scene.cur
scene.seq[m+2]=style or"fade"
end
end
function scene.pop()
scene.seq={}
end
function scene.swapTo(tar,style)
local S=scene.swap
if not scene.swapping and tar~=scene.cur then
scene.swapping=true
if not style then style="fade"end
S.tar=tar
S.style=style
S.time=swap[style][1]
S.mid=swap[style][2]
S.draw=swap[style][3]
widget_sel=nil
if style~="none"then SFX("swipe")end
end
end
function scene.back()
if not scene.swapping then
if backFunc[scene.cur] then backFunc[scene.cur]()end
--func when scene end
local m=#scene.seq
if m>0 then
scene.swapTo(scene.seq[m-1],scene.seq[m])
scene.seq[m],scene.seq[m-1]=nil
--Poll&Back to preScene
end
end
end
return scene

16
shadowMapShader.cs Normal file
View File

@@ -0,0 +1,16 @@
#define PI 3.14
extern float yresolution;
vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){
//Iterate through the occluder map's y-axis.
for(float y=0.;y<yresolution;y++){
//直角转极坐标
vec2 norm=vec2(texture_coords.s,y/yresolution)*2.-1.;
float theta=PI*1.5+norm.x*PI;
float r=(1.+norm.y)*.5;
//y/yresolution为到光源的距离(0~1)
//遮光物采样
vec4 data=Texel(texture,(vec2(-r*sin(theta),-r*cos(theta))*.5+.5));//vec2()..是遮光物采样的coord
if(data.a>.1)return vec4(vec3(y/yresolution),1.);//碰撞检测,像素透明度>.1即透光
}
return vec4(vec3(1),1.);//返回最远距离1
}

View File

@@ -1,5 +1,6 @@
local gc=love.graphics
local N,c=gc.newImage
local int=math.floor
local function T(s,t)return gc.newText(setFont(s),t)end
local function C(x,y)
c=gc.newCanvas(x,y)
@@ -15,16 +16,18 @@ for i=1,13 do
blockSkinmini[i]=C(6,6)
end
virtualkeyIcon={}
for i=1,10 do
virtualkeyIcon[i]=N("/image/virtualkey/"..actName[i]..".png")
local VKI=N("/image/virtualkey.png")
VKIcon={}
for i=1,#actName do
VKIcon[i]=C(36,36)
gc.draw(VKI,(i-1)%5*-36,int((i-1)*.2)*-36)
end
gc.setColor(1,1,1)
mouseBlock={}
miniBlock={}
for i=1,7 do
local b=blocks[i][0]
mouseBlock[i]=C(#b[1],#b)
miniBlock[i]=C(#b[1],#b)
gc.setColor(blockColor[i])
for y=1,#b do for x=1,#b[1]do
if b[y][x]then
@@ -61,15 +64,32 @@ payCode=N("/image/mess/paycode.png")
drawableText={
question=T(100,"?"),
bpm=T(15,"BPM"),kpm=T(15,"KPM"),
speedLV=T(20,"speed level"),
atk=T(20,"Attack"),
eff=T(20,"Efficiency"),
tsd=T(35,"TSD"),
line=T(25,"Lines"),
techrash=T(25,"Techrash"),
grade=T(25,"Grade"),
wave=T(30,"Wave"),
rpm=T(35,"RPM"),
combo=T(20,"Combo"),
mxcmb=T(20,"Max Combo"),
pc=T(22,"Perfect Clear"),
ko=T(25,"KO"),
modeName=T(30),levelName=T(30),
next=T(40),hold=T(40),
pause=T(120),finish=T(120),
custom=T(80),
setting_game=T(80),setting_graphic=T(80),setting_sound=T(80),
keyboard=T(25),joystick=T(25),
setting2Help=T(25),
ctrlSetHelp=T(30),
musicRoom=T(80),
nowPlaying=T(50),
warning=T(30),
VKTchW=T(30),
VKOrgW=T(30),
VKCurW=T(30),
}
c=gc.setCanvas()
gc.setCanvas()

250
timer.lua
View File

@@ -3,8 +3,8 @@ local Timer=love.timer.getTime
local int,abs,rnd,max,min,sin=math.floor,math.abs,math.random,math.max,math.min,math.sin
local ins,rem=table.insert,table.remove
return{
load=function()
local Tmr={}
function Tmr.load()
local t=Timer()
::R::
if loading==1 then
@@ -41,23 +41,27 @@ load=function()
for i=1,#sfx do sfx[i]=nil end
loading=4
loadnum=1
SFX("welcome",.2)
end
elseif loading==4 then
loadnum=loadnum+1
if loadnum==15 then
if loadnum==48 then
stat.run=stat.run+1
gotoScene("intro","none")
scene.swapTo("intro","none")
end
end
end,
intro=function()
end
function Tmr.intro()
count=count+1
if count==200 then count=80 end
end,
draw=function()
end
function Tmr.main(dt)
players[1]:update(dt)
end
function Tmr.draw()
if clearSureTime>0 then clearSureTime=clearSureTime-1 end
end,
play=function(dt)
end
function Tmr.play(dt)
frame=frame+1
stat.time=stat.time+dt
for i=#FX_attack,1,-1 do
@@ -72,7 +76,7 @@ play=function(dt)
end
if b.t<60 then
local L=FX_attack[i].drag
if #L==10 then
if #L==6*setting.atkFX then
rem(L,1)rem(L,1)
end
ins(L,b.x)ins(L,b.y)
@@ -103,7 +107,7 @@ play=function(dt)
SFX("ready")
end
for p=1,#players do
P=players[p]
local P=players[p]
if P.keyPressing[1]then
if P.moving>0 then P.moving=0 end
P.moving=P.moving-1
@@ -128,227 +132,17 @@ play=function(dt)
restartCount=max(restartCount-2,0)
end--Counting,include pre-das,directy RETURN,or restart counting
for p=1,#players do
P=players[p]
if P.timing then P.stat.time=P.stat.time+dt end
if P.alive then
if not P.small then
local v=0
for i=2,10 do v=v+i*(i-1)*7.2/(frame-P.keyTime[i])end P.keySpeed=P.keySpeed*.99+v*.1
v=0
for i=2,10 do v=v+i*(i-1)*7.2/(frame-P.dropTime[i])end P.dropSpeed=P.dropSpeed*.99+v*.1
--Update speeds
if modeEnv.royaleMode then
if P.keyPressing[9]then
P.swappingAtkMode=min(P.swappingAtkMode+2,30)
else
P.swappingAtkMode=P.swappingAtkMode+((#P.field>15 and P.swappingAtkMode>4 or P.swappingAtkMode>8)and -1 or 1)
end
end
end
if not P.human and P.control and P.waiting==-1 then
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](C)
elseif P.AI_delay<=0 then
pressKey(C[1],P)releaseKey(C[1],P)
local k=#C for i=1,k do C[i]=C[i+1]end--table.remove(C,1)
P.AI_delay=P.AI_delay0*2
end
end
if not P.keepVisible then
for j=1,#P.field do for i=1,10 do
if P.visTime[j][i]>0 then P.visTime[j][i]=P.visTime[j][i]-1 end
end end
end--Fresh visible time
if P.moving<0 then
if P.keyPressing[1]then
if -P.moving<=P.gameEnv.das then
P.moving=P.moving-1
elseif P.waiting==-1 then
local x=P.curX
if P.gameEnv.arr>0 then
act.moveLeft(true)
else
act.insLeft()
end
if x~=P.curX then P.moving=P.moving+P.gameEnv.arr-1 end
end
else
P.moving=0
end
elseif P.moving>0 then
if P.keyPressing[2]then
if P.moving<=P.gameEnv.das then
P.moving=P.moving+1
elseif P.waiting==-1 then
local x=P.curX
if P.gameEnv.arr>0 then
act.moveRight(true)
else
act.insRight()
end
if x~=P.curX then P.moving=P.moving-P.gameEnv.arr+1 end
end
else
P.moving=0
end
end
if P.keyPressing[7]and not P.keyPressing[9]then
local d=abs(P.downing)-P.gameEnv.sddas
P.downing=P.downing+1
if d>1 then
if P.gameEnv.sdarr>0 then
if d%P.gameEnv.sdarr==0 then
act.down1()
end
else
act.insDown()
end
end
else
P.downing=0
end
if P.falling>=0 then
P.falling=P.falling-1
if P.falling>=0 then
goto stop
else
local L=#P.clearing
if P.human and P.gameEnv.fall>0 and #P.field+L>P.clearing[L]then SFX("fall")end
for i=1,L do
P.clearing[i]=nil
end
end
end
if not P.control then goto stop end
if P.waiting>=0 then
P.waiting=P.waiting-1
if P.waiting==-1 then resetblock()end
goto stop
end
if P.curY~=P.y_img then
if P.dropDelay>=0 then
P.dropDelay=P.dropDelay-1
if P.dropDelay>0 then goto stop end
end
P.curY=P.curY-1
P.spinLast=false
if P.y_img~=P.curY then
P.dropDelay=P.gameEnv.drop
elseif P.AI_mode=="CC"then
P.AI_needFresh=true
if not P.AIdata._20G and P.gameEnv.drop<P.AI_delay0*.5 then
CC_switch20G(P)
end
end
if P.freshTime<=P.gameEnv.freshLimit then
P.lockDelay=P.gameEnv.lock
end
else
P.lockDelay=P.lockDelay-1
if P.lockDelay>=0 then goto stop end
drop()
if P.AI_mode=="CC"then
P.AI_needFresh=true
end
end
::stop::
if P.b2b1==P.b2b then
elseif P.b2b1<P.b2b then
P.b2b1=min(P.b2b1*.98+P.b2b*.02+.4,P.b2b)
else
P.b2b1=max(P.b2b1*.95+P.b2b*.05-.6,P.b2b)
end
--Alive
else
if not P.small then
P.keySpeed=P.keySpeed*.96+P.stat.key/P.stat.time*60*.04
P.dropSpeed=P.dropSpeed*.96+P.stat.piece/P.stat.time*60*.04
--Final average speeds
if modeEnv.royaleMode then
P.swappingAtkMode=min(P.swappingAtkMode+2,30)
end
end
if P.falling>=0 then
P.falling=P.falling-1
if P.falling>=0 then
goto stop
else
local L=#P.clearing
if P.human and P.gameEnv.fall>0 and #P.field+L>P.clearing[L]then SFX("fall")end
for i=1,L do
P.clearing[i]=nil
end
end
end::stop::
if P.endCounter<40 then
for j=1,#P.field do for i=1,10 do
if P.visTime[j][i]<20 then P.visTime[j][i]=P.visTime[j][i]+.5 end
end end--Make field visible
end
if P.b2b1>0 then P.b2b1=max(0,P.b2b1*.92-1)end
--Dead
end
if P.stat.score>P.score1 then
if P.stat.score-P.score1<10 then
P.score1=P.score1+1
else
P.score1=int(min(P.score1*.9+P.stat.score*.1+1))
end
end
for i=#P.shade,1,-1 do
local S=P.shade[i]
S[1]=S[1]-1+setting.dropFX*.25
if S[1]<=0 then
rem(P.shade,i)
end
end
if P.fieldOffY>0 then
P.fieldOffY=P.fieldOffY-(P.fieldOffY>3 and 2 or 1)
end
if P.fieldOffX~=0 then
P.fieldOffX=P.fieldOffX-(P.fieldOffX>0 and 1 or -1)
end
for i=#P.bonus,1,-1 do
local b=P.bonus[i]
if b.inf then
if b.t<30 then
b.t=b.t+.5
end
else
b.t=b.t+b.speed
if b.t>=60 then rem(P.bonus,i)end
end
end
for i=#P.atkBuffer,1,-1 do
local A=P.atkBuffer[i]
A.time=A.time+1
if not A.sent then
if A.countdown>0 then
A.countdown=max(A.countdown-garbageSpeed,0)
end
else
if A.time>20 then
rem(P.atkBuffer,i)
end
end
end
if P.fieldBeneath>0 then P.fieldBeneath=max(P.fieldBeneath-pushSpeed,0)end
if not P.small then
PTC.dust[p]:update(dt)
end
local P=players[p]
P:update(dt)
end
if modeEnv.royaleMode and frame%120==0 then freshMostDangerous()end
end,
pause=function(dt)
end
function Tmr.pause(dt)
if not gamefinished then
pauseTime=pauseTime+dt
end
if pauseTimer<50 and not wd.isMinimized()then
pauseTimer=pauseTimer+1
end
end,
}
end
return Tmr

View File

@@ -25,20 +25,26 @@ function mDraw(s,x,y)
gc.draw(s,x-s:getWidth()*.5,y)
end
function destroyPlayers()
if players then
for _,P in next,players do if P.id then
while P.field[1]do
removeRow(P.field)
removeRow(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
end end
for i=#players,1,-1 do
local P=players[i]
if P.canvas then P.canvas:release()end
while P.field[1]do
removeRow(P.field)
removeRow(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 getNewRow(val)
local t=rem(freeRow)
@@ -64,17 +70,18 @@ end
langName={"中文","全中文","English"}
local langID={"chi","chi_full","eng"}
local drawableTextLoad={
"next",
"hold",
"pause",
"finish",
"next","hold",
"pause","finish",
"custom",
"keyboard",
"joystick",
"setting2Help",
"setting_game",
"setting_graphic",
"setting_sound",
"keyboard","joystick",
"ctrlSetHelp",
"musicRoom",
"nowPlaying",
"warning",
"VKTchW","VKOrgW","VKCurW",
}
function swapLanguage(l)
text=require("language/"..langID[l])
@@ -122,20 +129,29 @@ function VIB(t)
love.system.vibrate(vibrateLevel[setting.vib+t])
end
end
function SFX(s,v)
function SFX(s,v,pos)
if setting.sfx>0 then
local S=sfx[s]--AU_Queue
local n=1
::L::if sfx[s][n]:isPlaying()then
while S[n]:isPlaying()do
n=n+1
if not sfx[s][n]then
sfx[s][n]=sfx[s][n-1]:clone()
sfx[s][n]:seek(0)
goto quit
if not S[n]then
S[n]=S[n-1]:clone()
S[n]:seek(0)
break
end
goto L
end::quit::
sfx[s][n]:setVolume((v or 1)*setting.sfx*.125)
sfx[s][n]:play()
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*setting.stereo*.1
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume((v or 1)*setting.sfx*.1)
S:play()
end
end
function getFreeVoiceChannel()
@@ -152,9 +168,8 @@ function VOICE(s,chn)
voiceQueue[chn][#voiceQueue[chn]+1]=voiceList[s][rnd(#voiceList[s])]
--添加到[chn]
else
local P=#voiceQueue
voiceQueue[P+1]={voiceList[s][rnd(#voiceList[s])]}
--新建[chn]
voiceQueue[getFreeVoiceChannel()]={voiceList[s][rnd(#voiceList[s])]}
--自动查找/创建空轨
end
end
end
@@ -177,7 +192,7 @@ function BGM(s)
bgmPlaying=s
else
if bgmPlaying then
local v=setting.bgm*.125
local v=setting.bgm*.1
bgm[bgmPlaying]:setVolume(v)
if v>0 then
bgm[bgmPlaying]:play()
@@ -192,104 +207,88 @@ function BGM(s)
end
end
local swapDeck_data={
{4,0,1,1},{6,0,15,1},{5,0,9,1},{6,0,6,1},
{1,0,3,1},{3,0,12,1},{1,1,8,1},{2,1,4,2},
{3,2,13,2},{4,1,12,2},{5,2,1,2},{7,1,11,2},
{2,1,9,3},{3,0,6,3},{4,2,14,3},{1,0,4,4},
{7,1,1,4},{6,0,2,4},{5,2,6,4},{6,0,14,5},
{3,3,15,5},{4,0,7,6},{7,1,10,5},{5,0,2,6},
{2,1,1,7},{1,0,4,6},{4,1,13,5},{1,1,6,7},
{5,3,11,5},{3,2,11,7},{6,0,8,7},{4,2,12,8},
{7,0,8,9},{1,0,2,8},{5,2,4,8},{6,0,15,8},
}--Block id [ZSLJTOI] ,dir,x,y
local swap={
none={2,1,d=function()end},
flash={8,1,d=function()gc.clear(1,1,1)end},
fade={30,15,d=function()
local t=1-abs(sceneSwaping.time*.06667-1)
gc.setColor(0,0,0,t)
gc.rectangle("fill",0,0,1280,720)
end},
deck={50,8,d=function()
local t=sceneSwaping.time
gc.setColor(1,1,1)
if t>8 then
local t=max(t,15)
for i=1,51-t do
local bn=swapDeck_data[i][1]
local b=blocks[bn][swapDeck_data[i][2]]
local cx,cy=swapDeck_data[i][3],swapDeck_data[i][4]
for y=1,#b do for x=1,#b[1]do
if b[y][x]then
gc.draw(blockSkin[bn],80*(cx+x-2),80*(10-cy-y),nil,8/3)
end
end end
function updateStat()
local S=players[1].stat
for k,v in next,S do
stat[k]=stat[k]+S[k]
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()
mostDangerous,secDangerous=nil
local m,m2=0,0
for i=1,#players.alive do
local h=#players.alive[i].field
if h>=m then
mostDangerous,secDangerous=players.alive[i],mostDangerous
m,m2=h,m
elseif h>=m2 then
secDangerous=players.alive[i]
m2=h
end
end
end
function freshMostBadge()
mostBadge,secBadge=nil
local m,m2=0,0
for i=1,#players.alive do
local h=players.alive[i].badge
if h>=m then
mostBadge,secBadge=players.alive[i],mostBadge
m,m2=h,m
elseif h>=m2 then
secBadge=players.alive[i]
m2=h
end
end
end
function royaleLevelup()
gameStage=gameStage+1
local spd
if(gameStage==3 or gameStage>4)and players[1].alive then
players[1]:showText(text.royale_remain(#players.alive),"beat",50,-100,.3)
end
if gameStage==2 then
spd=30
elseif gameStage==3 then
spd=15
garbageSpeed=.6
if players[1].alive then BGM("cruelty")end
elseif gameStage==4 then
spd=10
pushSpeed=3
elseif gameStage==5 then
spd=5
garbageSpeed=1
elseif gameStage==6 then
spd=3
if players[1].alive then BGM("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
if t<17 then
gc.setColor(1,1,1,(8-abs(t-8))*.125)
gc.rectangle("fill",0,0,1280,720)
end
end},
}--Scene swapping animations
function gotoScene(s,style)
if not sceneSwaping and s~=scene then
style=style or"fade"
sceneSwaping={
tar=s,style=style,
time=swap[style][1],mid=swap[style][2],
draw=swap[style].d
}
widget_sel=nil
if style~="none"then
SFX("swipe")
end
end
end
function updateStat()
for k,v in next,players[1].stat do
stat[k]=stat[k]+v
end
end
local prevMenu={
load=love.event.quit,
intro="quit",
main="intro",
music="main",
mode="main",
custom="mode",
draw=function()
gotoScene("custom")
end,
play=function()
kb.setKeyRepeat(true)
updateStat()
clearTask("play")
gotoScene(curMode.id~="custom"and"mode"or"custom","deck")
end,
pause=nil,
setting=function()
saveSetting()
gotoScene("main")
end,
setting_game= "setting",
setting_graphic="setting",
setting_sound= "setting",
setting_control="setting",
setting_touch= "setting",
help="main",
history="help",
stat="main",
}prevMenu.pause=prevMenu.play
function back()
local t=prevMenu[scene]
if type(t)=="string"then
gotoScene(t)
else
t()
end
end
function pauseGame()
pauseTimer=0--Pause timer for animation
if not gamefinished then
@@ -299,17 +298,108 @@ function pauseGame()
local l=players.alive[i].keyPressing
for j=1,#l do
if l[j]then
releaseKey(j,players.alive[i])
players.alive[i]:releaseKey(j)
end
end
end
gotoScene("pause","none")
scene.swapTo("pause","none")
end
function resumeGame()
gotoScene("play","fade")
scene.swapTo("play","fade")
end
function loadGame(mode,level)
--rec={}
curMode={id=modeID[mode],lv=level}
drawableText.modeName:set(text.modeName[mode])
drawableText.levelName:set(modeLevel[modeID[mode]][level])
needResetGameData=true
scene.swapTo("play","deck")
end
function resetPartGameData()
frame=30
destroyPlayers()
loadmode[curMode.id]()
if modeEnv.task then
for i=1,#players do
newTask(Event_task[modeEnv.task],players[i])
end
end
if modeEnv.royaleMode then
for i=1,#players do
players[i]:changeAtk(randomTarget(players[i]))
end
end
restoreVirtualKey()
collectgarbage()
end
function resetGameData()
gamefinished=false
frame=0
garbageSpeed=1
pushSpeed=3
pauseTime=0--Time paused
pauseCount=0--Times paused
destroyPlayers()
local E=defModeEnv[curMode.id]
modeEnv=E[curMode.lv]or E[1]
loadmode[curMode.id]()--bg/bgm need redefine in custom,so up here
if modeEnv.task then
for i=1,#players do
newTask(Event_task[modeEnv.task],players[i])
end
end
curBG=modeEnv.bg
BGM(modeEnv.bgm)
FX_badge={}
FX_attack={}
for _,v in next,PTC.dust do
v:release()
end
for i=1,#players do
if not players[i].small then
PTC.dust[i]=PTC.dust0:clone()
PTC.dust[i]:start()
end
end
if modeEnv.royaleMode then
for i=1,#players do
players[i]:changeAtk(randomTarget(players[i]))
end
mostBadge,mostDangerous,secBadge,secDangerous=nil
gameStage=1
garbageSpeed=.3
pushSpeed=2
end
restoreVirtualKey()
stat.game=stat.game+1
local m,p=#freeRow,40*#players+1
while freeRow[p]do
m,freeRow[m]=m-1
end
for i=1,20 do
virtualkeyDown[i]=X
virtualkeyPressTime[i]=0
end
freeRow.L=#freeRow
SFX("ready")
collectgarbage()
end
function gameStart()
SFX("start")
for P=1,#players do
P=players[P]
P:resetblock()
P.timing=true
P.control=true
end
end
local dataOpt={
"run","game","time",
"extraPiece","extraRate",
"key","rotate","hold","piece","row",
"atk","send","recv","pend",
"clear_1","clear_2","clear_3","clear_4",
@@ -319,9 +409,6 @@ local dataOpt={
function loadData()
userData:open("r")
local t=userData:read()
if not find(t,"spin")then
t=love.data.decompress("string","zlib",t)
end
t=splitS(t,"\r\n")
userData:close()
for i=1,#t do
@@ -345,53 +432,42 @@ function saveData()
t[i]=dataOpt[i].."="..toS(stat[dataOpt[i]])
end
t=concat(t,"\r\n")
t=love.data.compress("string","zlib",t)
userData:open("w")
userData:write(t)
userData:close()
end
function loadSetting()
userSetting:open("r")
local t=userSetting:read()
if not find(t,"virtual")then
t=love.data.decompress("string","zlib",t)
end
t=splitS(t,"\r\n")
userSetting:close()
for i=1,#t do
local p=find(t[i],"=")
if p then
local t,v=sub(t[i],1,p-1),sub(t[i],p+1)
if t=="sfx"or t=="bgm"or t=="voc"then
setting[t]=toN(v:match("[012345678]"))or setting[t]
if
--声音
t=="sfx"or t=="bgm"or t=="voc"or t=="stereo"or
--三个触摸设置项
t=="VKTchW"or t=="VKCurW"or t=="VKAlpha"
then
v=toN(v)
if v==int(v)and v>=0 and v<=10 then
setting[t]=v
end
elseif t=="vib"then
setting.vib=toN(v:match("[012345]"))or 0
elseif t=="fullscreen"then
setting.fullscreen=v=="true"
love.window.setFullscreen(setting.fullscreen)
elseif t=="keymap"then
v=splitS(v,"/")
for i=1,16 do
local v1=splitS(v[i],",")
for j=1,#v1 do
setting.keyMap[i][j]=v1[j]
end
end
elseif t=="virtualkey"then
v=splitS(v,"/")
for i=1,10 do
if v[i]then
virtualkey[i]=splitS(v[i],",")
for j=1,4 do
virtualkey[i][j]=toN(virtualkey[i][j])
end
end
end
elseif t=="virtualkeyAlpha"then
setting.virtualkeyAlpha=min(int(abs(toN(v))),10)
elseif t=="ghost"or t=="center"or t=="grid"or t=="swap"or t=="bg"or t=="bgblock"or t=="smo"then
setting[t]=v=="true"
elseif t=="virtualkeyIcon"or t=="virtualkeySwitch"then
elseif
--开关设置们
t=="bg"or
t=="ghost"or t=="center"or t=="grid"or t=="swap"or
t=="quickR"or t=="fine"or t=="bgblock"or t=="smo"or
t=="VKSwitch"or t=="VKTrack"or t=="VKDodge"or t=="VKIcon"
then
setting[t]=v=="true"
elseif t=="frameMul"then
setting.frameMul=min(max(toN(v)or 100,0),100)
@@ -403,7 +479,26 @@ function loadSetting()
elseif t=="lang"then
setting[t]=toN(v:match("[123]"))or 1
elseif t=="skin"then
setting[t]=toN(v:match("[123456]"))or 1
setting[t]=toN(v:match("[12345678]"))or 1
elseif t=="keymap"then
v=splitS(v,"/")
for i=1,16 do
local v1=splitS(v[i],",")
for j=1,#v1 do
setting.keyMap[i][j]=v1[j]
end
end
elseif t=="VK"then
v=splitS(v,"/")
local SK
for i=1,#v do
if v[i]then
SK=splitS(v[i],",")
local K=VK_org[i]
K.ava=SK[1]=="T"
K.x,K.y,K.r=toN(SK[2]),toN(SK[3]),toN(SK[4])
end
end
end
end
end
@@ -411,8 +506,9 @@ end
local saveOpt={
"das","arr",
"sddas","sdarr",
"holdR",
"quickR",
"swap",
"fine",
"ghost","center",
"smo","grid",
@@ -429,18 +525,24 @@ local saveOpt={
"sfx","bgm",
"vib","voc",
"stereo",
"virtualkeyAlpha",
"virtualkeyIcon",
"virtualkeySwitch",
"VKSwitch",
"VKTrack",
"VKDodge",
"VKIcon",
"VKAlpha",
}
function saveSetting()
local vk={}
for i=1,10 do
for j=1,4 do
virtualkey[i][j]=int(virtualkey[i][j]+.5)
end--Saving a integer is better?
vk[i]=concat(virtualkey[i],",")
local vk={}--virtualkey table
for i=1,#VK_org do
local V=VK_org[i]
vk[i]=concat({
V.ava and"T"or"F",
int(V.x+.5),
int(V.y+.5),
V.r,
},",")
end--pre-pack virtualkey setting
local map={}
for i=1,16 do
@@ -448,14 +550,12 @@ function saveSetting()
end
local t={
"keymap="..toS(concat(map,"/")),
"virtualkey="..toS(concat(vk,"/")),
"VK="..toS(concat(vk,"/")),
}
for i=1,#saveOpt do
t[i+2]=saveOpt[i].."="..toS(setting[saveOpt[i]])
--not always i+2!
t[#t+1]=saveOpt[i].."="..toS(setting[saveOpt[i]])
end
t=concat(t,"\r\n")
t=love.data.compress("string","zlib",t)
userSetting:open("w")
userSetting:write(t)
userSetting:close()

View File

@@ -1,25 +1,63 @@
local S=[=[
Patron(rmb10+):
gggf/T080/Ykzl/zxc
[D*a]?
Future outlook:
GUI:
Normal Things:
powerinfo switch
splashing block
ajustable next count
bag line in all mode
highscore of most modes
custom block color/direction
custom sequence
virtual key switch(all keys)
Normal Things:
new cooler attack FX
custom block sequence
combo mode
demo play at main menu
any screen size
auto GUI in any screen size
CC smarter(think of gaebage buffer)
fineese/bigbang mode & easier CTWC
new AI:task-Z
game recording
TTT mode
Hard Things:
Encrypt source code(JIT to byte code)
Technical things:
Encrypt source code(compile to byte code)
infinite 1v1
square mode
more FXs & 3d features & animations
0.7.32:
Blind-GM now show section directly
easier&more standard classic mode
can switch Virtualkey's auto dodging
in-game setting
code optimized
bug fixed
0.7.31:
stereo system
fixed a problem in finesse calculating
0.7.30:
auto-tracking virtual key,adjustable parameters!
can switch on/off virtuakeys
add 7 more key
better finesse rate calculating
block generating position on Y-axis changed
new icon for android
can use preset in custom mode with keyboard
adjusted GUI
many bug fixed
0.7.28:
add fineese check(almost useful)
code optimized
0.7.27:
super O transform system
optimized light system(no used)
bug fixed
0.7.26:
new skin
import light lib
many bug fixed
0.7.25:
demo play at main menu
ALMOST reconstructed WHOLE PLAYER SYSTEM,NEED TEST
many bug fixed
0.7.24(0.7.23):
REMAKE ALL BGM!
more settings with brand new GUI!