Compare commits

..

4 Commits

Author SHA1 Message Date
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
MrZ_26
e8f0f4cf38 0.7.24α 2020-02-04 19:36:20 +08:00
43 changed files with 4658 additions and 3627 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

162
class.lua
View File

@@ -1,20 +1,9 @@
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,
@@ -42,21 +31,136 @@ function clearTask(opt)
end
end
function newButton(x,y,w,h,color,font,code,hide,up,down,left,right)
return{
type="button",
x=x-w*.5,y=y-h*.5,w=w,h=h,
color=color,font=font,
code=code,hide=hide,
up=up,down=down,left=left,right=right,
}
local button={type="button"}
function newButton(x,y,w,h,color,font,code,hide,N)
local _={
x=x-w*.5,y=y-h*.5,
w=w,h=h,
color=color,
font=font,
code=code,
hide=hide,
next=N,
}for k,v in next,button do _[k]=v end return _
end
function newSlider(x,y,w,unit,color,font,code,hide,up,down,left,right)
return{
type="slider",
x=x,y=y,w=w,unit=unit,
color=color,font=font,
code=code,hide=hide,
up=up,down=down,left=left,right=right,
}
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()
sysFX[#sysFX+1]={0,0,10,self.x,self.y,self.w,self.h}
--[0=ripple],timer,duration,x,y,w,h
end
function button:draw()
local C=self.color
gc.setColor(C)
gc.setLineWidth(3)gc.rectangle("line",self.x,self.y,self.w,self.h,4)
gc.setColor(C[1],C[2],C[3],.4)
gc.setLineWidth(5)gc.rectangle("line",self.x,self.y,self.w,self.h,4)
if self==widget_sel then
gc.rectangle("fill",self.x,self.y,self.w,self.h,4)
end--Highlight when Selected
local t=self.text
if t then
if type(t)=="function"then t=t()end
setFont(self.font)
local y0=self.y+self.h*.5-self.font*.7
gc.printf(t,self.x-2,y0-1,self.w,"center")
gc.setColor(C)
gc.printf(t,self.x,y0,self.w,"center")
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))
end
local switch={type="switch"}
function newSwitch(x,y,font,disp,code,hide,N)
local _={
x=x,y=y,font=font,
disp=disp,
code=code,
hide=hide,
next=N,
}for k,v in next,switch do _[k]=v end return _
end
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()
sysFX[#sysFX+1]=self.disp()and
{1,0,15,1,.4,.4,self.x,self.y-20,50,40,0}--Switched on
or{1,0,15,.4,1,.4,self.x+50,self.y-20,50,40,0}--Switched off
--[1=square fade],timer,duration,r,g,b,x,y,w,h
end
function switch:draw()
local x,y=self.x,self.y-20
if self.disp()then
gc.setColor(.6,1,.6)
gc.rectangle("fill",x+50,y,50,40,3)
--ON
else
gc.setColor(1,.6,.6)
gc.rectangle("fill",x,y,50,40,3)
--OFF
end--switch
gc.setColor(1,1,1,self==widget_sel and 1 or .6)
gc.setLineWidth(3)gc.rectangle("line",x-3,y-3,106,46,5)
--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")
end
end
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,
w=w,unit=unit,
font=font,
change=change,
disp=disp,
code=code,
hide=hide,
next=N,
}for k,v in next,slider do _[k]=v end return _
end
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)
sysFX[#sysFX+1]={1,0,10,1,1,1,self.x+self.w*pos/self.unit-8,self.y-15,17,30}
--[1=square fade],timer,duration,r,g,b,x,y,w,h
end
function slider:draw()
local S=self==widget_sel
gc.setColor(1,1,1,S and 1 or .5)
gc.setLineWidth(2)
local x1,x2=self.x,self.x+self.w
for p=0,self.unit do
local x=x1+(x2-x1)*p/self.unit
gc.line(x,self.y+7,x,self.y-7)
end
--units
gc.setLineWidth(5)
gc.line(x1,self.y,x2,self.y)
--axis
gc.setColor(1,1,1)
gc.rectangle("fill",x1+(x2-x1)*self.disp()/self.unit-8,self.y-15,17,30)
--block
local t=self.text
if t then
gc.setColor(1,1,1)
setFont(self.font)
gc.printf(t,self.x-312,self.y-self.font*.7,300,"right")
end
end
function slider:getInfo()
print(format("x=%d,y=%d,w=%d",self.x,self.y,self.w))
end

View File

@@ -1,4 +1,4 @@
gameVersion="Alpha V0.7.23"
gameVersion="Alpha V0.7.28"
function love.conf(t)
t.identity="Techmino"--Save directory name
t.version="11.1"
@@ -9,7 +9,7 @@ function love.conf(t)
t.audio.mixwithsystem=true--Switch on to keep sysBGM
local W=t.window
W.title="Techmino "..gameVersion
W.title=math.random()>.01 and "Techmino "..gameVersion or"MrZ NB!"
W.icon="/image/icon.png"
W.width,W.height=1280,720
W.minwidth,W.minheight=640,360

File diff suppressed because it is too large Load Diff

31
document.txt Normal file
View File

@@ -0,0 +1,31 @@
攻击系统:
消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……
抵消逻辑:发动攻击时,若缓冲条有攻击则先用额外抵挡再用攻击力抵消受到的攻击,多余的攻击力会发送给对手,没有用上的额外抵挡会被丢弃。
攻击延迟消2/3的攻击生效最快消四其次spin攻击生效较慢高连击生效最慢b2b或者b3b增加攻击力的同时也会减缓一点生效时间mini大幅增加生效时间。
back to back点数说明取值范围0~1200
在40及以上特殊消除时b2b,在1000以上特殊消除时b3b,1200封顶
消四+100
空spin加20不超过1000
spin1~3+50/100/180 (mini*.5)
普通消除-250
1000以上空放一块-40(不减到低于1000)
吃鸡模式:
许多玩家同时进行一局游戏其它的是AI不是真人坚持到最后的玩家胜利。随着玩家数量的减少方块下落/垃圾生效速度/垃圾升起速度都会增加。淘汰其它玩家后可以获得一个徽章和该玩家持有的徽章,增强自己的攻击力。
玩家可选四个攻击模式:
1.随机每次攻击后10%随机锁定一个玩家
2.最多徽章:攻击后或者锁定玩家死亡时锁定徽章最多的玩家
3.最高:攻击后或者锁定玩家死亡时锁定场地最高的玩家(每秒刷新)
4.反击攻击所有锁定自己的玩家AOE若无则伏击随机玩家

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: 36 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 972 B

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,4 +1,3 @@
local SWC={[true]="",[false]=""}
local BK="返回"
return{
atkModeName={"随机","徽章","击杀","反击"},
@@ -26,7 +25,7 @@ return{
lose="失败",
pause="暂停",
finish="结束",
pauseTime="暂停时间",
pauseCount="暂停统计",
custom="自定义游戏",
customOption={
@@ -62,7 +61,10 @@ return{
snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"},
keyboard="键盘",joystick="手柄",
space="空格",enter="回车",
setting2Help="方向键选择/翻页,回车修改,esc返回",
ctrlSetHelp="方向键选择/翻页,回车修改,esc返回",
setting_game="游戏设置",
setting_graphic="画面设置",
setting_sound="声音设置",
musicRoom="音乐室",
nowPlaying="正在播放:",
@@ -101,28 +103,33 @@ return{
load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",},
tips={
"不是动画,真的在加载!",
"整个游戏都是MrZ完成的!",
"大满贯10连击消四全清!",
"<方块研究所>有一个Nspire-CX版本!",
"B2B2B???",
"B2B2B2B存在吗?",
"MEGACMB!",
"ALLSPIN!",
"O型回旋三清?",
"只用一个输入设备就可以游玩了",
"O spin triple!",
"Miya:喵!",
"225238922,哔哩哔哩 干杯~",
"225238922 哔哩哔哩 干杯~",
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
"合群了就会消失,但是消失不代表没有意义",
"学会使用两个旋转键,三个更好",
"更小的DAS和ARR拥有更高的操作上限",
"更小的DAS和ARR拥有更高的操作上限(如果你还能控制得了的话)",
"注意到\"旋转\"到底对方块做了些什么吗?",
"20G是一套全新的游戏规则",
"20G本质是一套全新的游戏规则",
"不要在上课时玩游戏!",
"本游戏难度上限很高,做好心理准备",
"方块可以不是个休闲游戏",
"调到特殊的日期也不会发生什么的",
"3.1415926535897932384",
"2.7182818284590452353",
"Let-The-Bass-Kick!",
"使用love2d引擎制作",
"有疑问?先看设置有没有你想要的",
"有建议的话可以把信息反馈给作者~",
"CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
},
stat={
"游戏运行次数:",
@@ -142,6 +149,7 @@ return{
"B2B数:",
"PC数:",
"效率:",
"多余操作:"
},
help={
"好像也没啥好帮助的吧?就当是关于了",
@@ -152,14 +160,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群",
ButtonText={
warning="禁 止 私 自 传 播",
WidgetText={
main={
lang="中文",
qplay="快速开始",
play="开始",
setting="设置",
@@ -178,7 +196,7 @@ return{
back=BK,
},
music={
bgm=function()return"音乐:"..SWC[setting.bgm]end,
bgm="BGM",
up="",
play="播放",
down="",
@@ -221,39 +239,54 @@ return{
pause="暂停",
},
pause={
resume="继续",
resume= "继续",
restart="重新开始",
quit="退出",
quit= "退出",
},
setting={
ghost=function()return"阴影:"..SWC[setting.ghost]end,
center=function()return"旋转中心:"..SWC[setting.center]end,
grid=function()return"网格:"..SWC[setting.grid]end,
swap=function()return setting.swap and"目标选择:组合键"or"目标选择:循环"end,
fxs=function()return setting.fxs>0 and"特效等级:"..setting.fxs or"特效:关"end,
bg=function()return"背景:"..SWC[setting.bg]end,
setting_game={
graphic="←画面设置",
sound="声音设置→",
dasD="-",dasU="+",
arrD="-",arrU="+",
sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+",
ctrl="控制设置",
touch="触摸设置",
lang=function()return langName[setting.lang]end,
sfx=function()return"音效:"..SWC[setting.sfx]end,
bgm=function()return"音乐:"..SWC[setting.bgm]end,
vib=function()return "震动:"..setting.vib end,
voc=function()return"语音:"..SWC[setting.voc]end,
fullscreen=function()return"全屏:"..SWC[setting.fullscreen]end,
bgblock=function()return"背景动画:"..SWC[setting.bgblock]end,
frame=function()return"绘制帧:"..setting.frameMul.."%"end,
skin="皮肤",
smo=function()return"平滑下落:"..SWC[setting.smo]end,
back="保存&返回",
},
setting2={
quickR="快速重新开始",
swap="组合键切换攻击模式",
fine="极简操作提示音",
ctrl="键位设置",
touch="触屏设置",
back=BK,
},
setting3={
setting_graphic={
sound="←声音设置",
game="游戏设置→",
ghost="阴影",
grid="网格",
center="旋转中心",
skin="皮肤",
bg="背景",
bgblock="背景动画",
smo="平滑下落",
dropFX="下落特效等级",
shakeFX="晃动特效等级",
atkFX="攻击特效等级",
fullscreen="全屏",
frame="绘制帧率",
back=BK,
},
setting_sound={
game="←游戏设置",
graphic="画面设置→",
sfx="音效",
bgm="音乐",
vib="震动",
voc="语音",
back=BK,
},
setting_control={
back=BK,
},
setting_touch={
hide=function()return setting.virtualkeySwitch and"隐藏虚拟按键"or"显示虚拟按键"end,
default="默认组合",
snap=function()return text.snapLevelName[snapLevel]end,
@@ -268,8 +301,8 @@ return{
back=BK,
},
history={
prev="",
next="",
prev="",
next="",
back=BK,
},
stat={

View File

@@ -1,4 +1,3 @@
local SWC={[true]="",[false]=""}
local BK="返回"
return{
atkModeName={"随机","徽章","击杀","反击"},
@@ -26,7 +25,7 @@ return{
lose="失败",
pause="暂停",
finish="结束",
pauseTime="暂停时间",
pauseCount="暂停统计",
custom="自定义游戏",
customOption={
@@ -62,7 +61,10 @@ return{
snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"},
keyboard="键盘",joystick="手柄",
space="空格",enter="回车",
setting2Help="方向键选择/翻页,回车修改,esc返回",
ctrlSetHelp="方向键选择/翻页,回车修改,esc返回",
setting_game="游戏设置",
setting_graphic="画面设置",
setting_sound="声音设置",
musicRoom="音乐室",
nowPlaying="正在播放:",
@@ -101,28 +103,33 @@ return{
load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",},
tips={
"不是动画,真的在加载!",
"整个游戏都是MrZ完成的!",
"大满贯10连击消四全清!",
"<方块研究所>有一个Nspire-CX版本!",
"B2B2B???",
"B2B2B2B存在吗?",
"MEGACMB!",
"ALLSPIN!",
"O型回旋三清?",
"只用一个输入设备就可以游玩了",
"O型回旋三清!",
"Miya:喵!",
"225238922,哔哩哔哩 干杯~",
"225238922 哔哩哔哩 干杯~",
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
"合群了就会消失,但是消失不代表没有意义",
"学会使用两个旋转键,三个更好",
"更小的DAS和ARR拥有更高的操作上限",
"更小的DAS和ARR拥有更高的操作上限(如果你还能控制得了的话)",
"注意到\"旋转\"到底对方块做了些什么吗?",
"20G是一套全新的游戏规则",
"20G本质是一套全新的游戏规则",
"不要在上课时玩游戏!",
"本游戏难度上限很高,做好心理准备",
"方块可以不是个休闲游戏",
"调到特殊的日期也不会发生什么的",
"3.1415926535897932384",
"2.7182818284590452353",
"Let-The-Bass-Kick!",
"使用love2d引擎制作",
"有疑问?先看设置有没有你想要的",
"有建议的话可以把信息反馈给作者~",
"CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
},
stat={
"游戏运行次数:",
@@ -142,6 +149,7 @@ return{
"满贯数:",
"全清数:",
"效率:",
"多余操作:"
},
help={
"好像也没啥好帮助的吧?就当是关于了",
@@ -152,14 +160,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群",
ButtonText={
warning="禁 止 私 自 传 播",
WidgetText={
main={
lang="全中文",
qplay="快速开始",
play="开始",
setting="设置",
@@ -178,7 +196,7 @@ return{
back=BK,
},
music={
bgm=function()return"音乐:"..SWC[setting.bgm]end,
bgm="BGM",
up="",
play="播放",
down="",
@@ -221,39 +239,55 @@ return{
pause="暂停",
},
pause={
resume="继续",
resume= "继续",
restart="重新开始",
quit="退出",
quit= "退出",
},
setting={
ghost=function()return"阴影:"..SWC[setting.ghost]end,
center=function()return"旋转中心:"..SWC[setting.center]end,
grid=function()return"网格:"..SWC[setting.grid]end,
swap=function()return setting.swap and"目标选择:组合键"or"目标选择:循环"end,
fxs=function()return setting.fxs>0 and"特效等级:"..setting.fxs or"特效:关"end,
bg=function()return"背景:"..SWC[setting.bg]end,
setting_game={
graphic="←画面设置",
sound="声音设置→",
dasD="-",dasU="+",
arrD="-",arrU="+",
sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+",
ctrl="控制设置",
touch="触摸设置",
lang=function()return langName[setting.lang]end,
sfx=function()return"音效:"..SWC[setting.sfx]end,
bgm=function()return"音乐:"..SWC[setting.bgm]end,
vib=function()return "震动:"..setting.vib end,
voc=function()return"语音:"..SWC[setting.voc]end,
fullscreen=function()return"全屏:"..SWC[setting.fullscreen]end,
bgblock=function()return"背景动画:"..SWC[setting.bgblock]end,
frame=function()return"绘制帧:"..setting.frameMul.."%"end,
skin="皮肤",
smo=function()return"平滑下落:"..SWC[setting.smo]end,
back="保存&返回",
},
setting2={
quickR="快速重新开始",
swap="组合键切换攻击模式",
fine="极简操作提示音",
ctrl="键位设置",
touch="触屏设置",
back=BK,
},
setting3={
setting_graphic={
sound="←声音设置",
game="游戏设置→",
ghost="阴影",
grid="网格",
center="旋转中心",
skin="皮肤",
bg="背景",
bgblock="背景动画",
smo="平滑下落",
dropFX="下落特效等级",
shakeFX="晃动特效等级",
atkFX="攻击特效等级",
fullscreen="全屏",
frame="绘制帧率",
back=BK,
},
setting_sound={
game="←游戏设置",
graphic="画面设置→",
sfx="音效",
bgm="音乐",
vib="震动",
voc="语音",
back=BK,
},
setting_control={
back=BK,
},
setting_touch={
hide=function()return setting.virtualkeySwitch and"隐藏虚拟按键"or"显示虚拟按键"end,
default="默认组合",
snap=function()return text.snapLevelName[snapLevel]end,
@@ -268,8 +302,8 @@ return{
back=BK,
},
history={
prev="",
next="",
prev="",
next="",
back=BK,
},
stat={

View File

@@ -1,4 +1,3 @@
local SWC={[true]="ON",[false]="OFF"}
local BK="Back"
return{
atkModeName={"Random","Badges","K.O.s","Counters"},
@@ -26,7 +25,7 @@ return{
lose="LOSE",
pause="PAUSE",
finish="FINISH",
pauseTime="Pause time",
pauseCount="Pause Count",
custom="Custom Game",
customOption={
@@ -62,7 +61,10 @@ 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:",
@@ -101,28 +103,34 @@ 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",
"Small DAS&ARR can make you faster,if you can adapt to it",
"Small DAS&ARR can make you faster,if you can control block correctly",
"Have you noticed what does \"rotating\" do to block?",
"20G is a brand new game rule",
"20G actually is a brand new game rule",
"Do not play game in class!",
"This game can be very hard,be mentally perpared",
"This in not a casual game",
"Nothing will happen when some special day come",
"3.1415926535897932384",
"2.7182818284590452353",
"Let-The-Bass-Kick!",
"Powered by love2d",
"Find out what's in the setting!",
"Any suggestions to author!",
"Techmino=Technique+Tetromino",
"CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
},
stat={
"Games run:",
@@ -132,7 +140,7 @@ return{
"Rotate:",
"Hold:",
"Block used:",
"Rows cleared:",
"Lines cleared:",
"Attack:",
"Sent:",
"Receive:",
@@ -142,6 +150,7 @@ return{
"B2B:",
"PC:",
"Efficiency:",
"Fineese:"
},
help={
"I don't think you need \"help\".",
@@ -151,15 +160,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",
ButtonText={
warning="DO NOT DISTRIBUTE",
WidgetText={
main={
lang="English",
qplay="Qplay",
play="Play",
setting="Settings",
@@ -178,7 +197,7 @@ return{
back=BK,
},
music={
bgm=function()return"BGM:"..SWC[setting.bgm]end,
bgm="BGM",
up="",
play="Play",
down="",
@@ -225,35 +244,50 @@ return{
restart="Restart",
quit="Quit",
},
setting={
ghost=function()return"Ghost:"..SWC[setting.ghost]end,
center=function()return"Center:"..SWC[setting.center]end,
grid=function()return"Grid:"..SWC[setting.grid]end,
swap=function()return setting.swap and"Swap:comboKey"or"Swap:loop"end,
fxs=function()return setting.fxs>0 and"FX level:"..setting.fxs or"NO FX"end,
bg=function()return"BG:"..SWC[setting.bg]end,
setting_game={
graphic="←Graphic",
sound="Sound→",
dasD="-",dasU="+",
arrD="-",arrU="+",
sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+",
ctrl="Control settings",
touch="Touch settings",
lang=function()return langName[setting.lang]end,
sfx=function()return"SFX:"..SWC[setting.sfx]end,
bgm=function()return"BGM:"..SWC[setting.bgm]end,
voc=function()return"VOC:"..SWC[setting.voc]end,
vib=function()return "VIB:"..setting.vib end,
fullscreen=function()return"Fullscreen:"..SWC[setting.fullscreen]end,
bgblock=function()return"BG animation:"..SWC[setting.bgblock]end,
frame=function()return"FrameDraw:"..setting.frameMul.."%"end,
skin="Skin",
smo=function()return"SmoothDrop:"..SWC[setting.smo]end,
back="Save&Back",
},
setting2={
quickR="Quick restart",
swap="Combo key to change ATK mode",
fine="Fineese error SFX",
ctrl="Key Setting",
touch="Touch Setting",
back=BK,
},
setting3={
setting_graphic={
sound="←Sound",
game="Game→",
ghost="Ghost",
grid="Grid",
center="Center",
skin="Skin",
bg="Background",
bgblock="BG animation",
smo="Smoooth drop",
dropFX="Drop FX level",
shakeFX="Shake FX level",
atkFX="ATK FX level",
fullscreen="Fullscreen",
frame="draw FPS",
back=BK,
},
setting_sound={
game="←Game",
graphic="Graphic→",
sfx="SFX",
bgm="BGM",
vib="VIB",
voc="VOC",
back=BK,
},
setting_control={
back=BK,
},
setting_touch={
hide=function()return setting.virtualkeySwitch and"Hide Virtual Key"or"Show Virtual Key"end,
default="Defaults",
snap=function()return text.snapLevelName[snapLevel]end,
@@ -268,8 +302,8 @@ return{
back=BK,
},
history={
prev="",
next="",
prev="",
next="",
back=BK,
},
stat={

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));
}

254
list.lua
View File

@@ -1,7 +1,3 @@
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"}
@@ -53,12 +49,13 @@ blockColor={
color.darkGreen,
}
sfx={
"welcome",
"button","swipe",
"ready","start","win","fail","collect",
"move","rotate","rotatekick","hold",
"prerotate","prehold",
"lock","drop","fall",
"reach",
"error","error_long","reach",
"ren_1","ren_2","ren_3","ren_4","ren_5","ren_6","ren_7","ren_8","ren_9","ren_10","ren_11","ren_mega",
"clear_1","clear_2","clear_3","clear_4",
"spin_0","spin_1","spin_2","spin_3",
@@ -82,14 +79,14 @@ bgm={
"shining terminal",
"end",
}
voiceList={
voiceBank={}
voiceName={
"Z","S","L","J","T","O","I",
"single","double","triple","tts",
"spin","spin_","mini","b2b","b3b","pc",
"win","lose","voc_nya","nya",
}
voiceBank={}
voice={
voiceList={
Z={"Z_1","Z_2"},
S={"S_1","S_2"},
J={"J_1","J_2"},
@@ -178,10 +175,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"},
@@ -271,7 +268,7 @@ local customSet={
{18,20,1,1,7,1,1,1,8,3,8,3,3},
{22,22,1,1,7,3,1,1,8,4,1,7,7},
{20,20,1,1,7,1,1,3,8,3,1,7,8},
{23,11,8,11,4,1,2,1,8,3,1,4,9},
{1,11,8,11,4,1,2,1,8,3,1,4,9},
}
local function useDefaultSet(n)
for i=1,#customSet[n]do
@@ -281,65 +278,68 @@ local function useDefaultSet(n)
BGM(customRange.bgm[customSel[13]])
end
Widget={
load={},
intro={},
load={},intro={},quit={},
main={
qplay= newButton(160, 300,150,150,color.lightRed, 40,function()loadGame(modeSel,levelSel)end, nil, nil, "stat", nil, "play" ),
play= newButton(380, 300,240,240,color.red, 70,function()gotoScene("mode")end, nil, nil, "stat", "qplay", "setting" ),
setting=newButton(640, 300,240,240,color.lightBlue,55,function()gotoScene("setting")end, nil, nil, "stat", "play", "music" ),
music= newButton(900, 300,240,240,color.lightCyan,42,function()gotoScene("music")end, nil, nil, "help", "setting", "quit" ),
stat= newButton(640, 560,240,240,color.cyan, 55,function()gotoScene("stat")end, nil, "setting", nil, "play", "help" ),
help= newButton(900, 560,240,240,color.yellow, 55,function()gotoScene("help")end, nil, "music", nil, "stat", "quit" ),
quit= newButton(1180, 620,120,120,color.lightGrey,50,function()gotoScene("quit")end, nil, "music", nil, "help", nil ),
play= newButton(150,280,200,160,color.red, 60,function()gotoScene("mode")end, nil,"setting"),
setting=newButton(370,280,200,160,color.lightBlue, 50,function()gotoScene("setting_game")end, nil,"music"),
music= newButton(590,280,200,160,color.lightPurple,37,function()gotoScene("music")end, nil,"help"),
help= newButton(150,460,200,160,color.yellow, 55,function()gotoScene("help")end, nil,"stat"),
stat= newButton(370,460,200,160,color.cyan, 48,function()gotoScene("stat")end, nil,"qplay"),
qplay= newButton(540,415,100,70,color.lightGreen, 28,function()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()gotoScene("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),
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),
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),
},
music={
bgm= newButton(1100, 80, 160,80, color.white,40,function()BGM()setting.bgm=not setting.bgm end),
up= newButton(1100, 200, 120,120,color.white,60,function()love.keypressed("up")end, function()return not setting.bgm end),
play= newButton(1100, 340, 120,120,color.white,40,function()love.keypressed("space")end, function()return not setting.bgm end),
down= newButton(1100, 480, 120,120,color.white,60,function()love.keypressed("down")end, function()return not setting.bgm end),
back= newButton(640, 630, 230,90, color.white,45,back),
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),
},
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),
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),
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),
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),
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),
},
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),
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),
},
play={
pause= newButton(1235,45,80,80,color.white,30,pauseGame),
@@ -354,74 +354,79 @@ Widget={
end),
quit= newButton(640,600,240,100,color.white,50,back),
},
setting={--Normal setting
ghost= newButton(290, 90, 210,60,color.white,40,function()setting.ghost=not setting.ghost end, nil, nil, "grid", nil, "center" ),
center= newButton(505, 90, 210,60,color.white,40,function()setting.center=not setting.center end, nil, nil, "swap", "ghost", "sfx" ),
grid= newButton(290, 160,210,60,color.white,40,function()setting.grid=not setting.grid end, nil, "ghost", "fxs", nil, "swap" ),
swap= newButton(505, 160,210,60,color.white,28,function()setting.swap=not setting.swap end, nil, "center", "bg", "grid", "vib" ),
fxs= newButton(290, 230,210,60,color.white,40,function()setting.fxs=(setting.fxs+1)%4 end, nil, "grid", "dasU", nil, "bg" ),
bg= newButton(505, 230,210,60,color.white,40,function()setting.bg=not setting.bg end, nil, "swap", "arrD", "fxs", "fullscreen" ),
dasD= newButton(210, 300,50, 50,color.white,40,function()setting.das=(setting.das-1)%31 end, nil, "fxs", "sddasD", nil, "dasU" ),
dasU= newButton(370, 300,50, 50,color.white,40,function()setting.das=(setting.das+1)%31 end, nil, "fxs", "sddasU", "dasD", "arrD" ),
arrD= newButton(425, 300,50, 50,color.white,40,function()
setting_game={
graphic=newButton(200,80,240,80,color.lightGreen,40,function()gotoScene("setting_graphic")end, nil,"sound"),
sound= newButton(1080,80,240,80,color.lightGreen,40,function()gotoScene("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
Widget.setting.dasU.alpha,Widget.setting.dasD.alpha=1,1
Widget.setting_game.dasU:FX()
SFX("blip_1",.4)
end
end,nil,"bg","sdarrD","dasU","arrU"),
arrU= newButton(585, 300,50, 50,color.white,40,function()
end,nil,"arrU"),
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
Widget.setting.dasU.alpha,Widget.setting.dasD.alpha=1,1
Widget.setting_game.dasU:FX()
SFX("blip_1",.4)
end
end,nil,"bg","sdarrU","arrD","bgblock"),
sddasD= newButton(210, 370,50, 50,color.white,40,function()setting.sddas=(setting.sddas-1)%11 end, nil, "dasD", "ctrl", nil, "sddasU" ),
sddasU= newButton(370, 370,50, 50,color.white,40,function()setting.sddas=(setting.sddas+1)%11 end, nil, "dasU", "ctrl", "sddasD", "sdarrD" ),
sdarrD= newButton(425, 370,50, 50,color.white,40,function()setting.sdarr=(setting.sdarr-1)%4 end, nil, "arrD", "ctrl", "sddasU", "sdarrU" ),
sdarrU= newButton(585, 370,50, 50,color.white,40,function()setting.sdarr=(setting.sdarr+1)%4 end, nil, "arrU", "ctrl", "sdarrD", "frame" ),
ctrl= newButton(340,440, 310,60,color.green,40, function()gotoScene("setting2")end, nil, "sddasU", "touch", "lang", "skin" ),
touch= newButton(340,510, 310,60,color.yellow,40, function()gotoScene("setting3")end, nil, "ctrl", "back", nil, "lang" ),
lang= newButton(580,510, 150,60,color.red,40, function()
setting.lang=setting.lang%#langName+1
swapLanguage(setting.lang)
end,nil,"sdarrU","back","touch","skin"),
sfx= newButton(760,90, 160,60,color.white,40, function()setting.sfx=not setting.sfx end, nil, nil, "vib", "center", "bgm" ),
bgm= newButton(940,90, 160,60,color.white,40, function()BGM()setting.bgm=not setting.bgm BGM("blank")end, nil, nil, "voc", "sfx", nil ),
vib= newButton(760,160, 160,60,color.white,40, function()setting.vib=(setting.vib+1)%6 VIB(1)end, nil, "sfx", "fullscreen", "swap", "voc" ),
voc= newButton(940,160, 160,60,color.white,40, function()setting.voc=not setting.voc end, nil, "sfx", "fullscreen", "vib", nil ),
fullscreen= newButton(850,230, 340,60,color.white,40, function()
end,nil,"sddasD"),
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()gotoScene("setting_control")end, nil,"touch"),
touch= newButton(1020,340,320,80,color.white,40,function()gotoScene("setting_touch")end, nil,"back"),
back= newButton(1160,600,160,160,color.white,55,back,nil,"graphic"),
},
setting_graphic={
sound= newButton(200,80,240,80,color.lightGreen,40,function()gotoScene("setting_sound")end, nil,"game"),
game= newButton(1080,80,240,80,color.lightGreen,40,function()gotoScene("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,"vib","bgblock","bg",nil),
bgblock= newButton(850,300, 340,60,color.white,40, function()
setting.bgblock=not setting.bgblock--if not setting.bgblock then for i=1,16 do BGblockList[i].v=3*BGblockList[i].v end end
end,nil,"fullscreen","frame","arrU",nil),
frame= newButton(850,370, 340,60,color.white,40, function()
setting.frameMul=setting.frameMul+(setting.frameMul<50 and 5 or 10)
if setting.frameMul>100 then setting.frameMul=25 end
end,nil,"bgblock","skin","sdarrU",nil),
skin= newButton(740,440, 120,60,color.white,40, function()
setting.skin=setting.skin%6+1
end,nil,"bg"),
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(860,470,120,60,color.white,40,function()
setting.skin=setting.skin%8+1
changeBlockSkin(setting.skin)
end,nil,"frame","back","ctrl","smo"),
smo= newButton(920,440, 200,60,color.white,27, function()
setting.smo=not setting.smo
end,nil,"frame","back","skin",nil),
back= newButton(640,620, 300,70,color.white,40, back,nil,nil,"lang",nil,nil),
end,nil,"back"),
back= newButton(1160,600,160,160,color.white,55,back,nil,"sound"),
},
setting_sound={
game= newButton(200,80,240,80,color.lightGreen,40,function()gotoScene("setting_game")end, nil,"graphic"),
graphic=newButton(1080,80,240,80,color.lightGreen,40,function()gotoScene("setting_graphic")end, nil,"sfx"),
sfx=newSlider(180,250,400,8,40,function()SFX("blip_1")end, function()return setting.sfx end,function(i)setting.sfx=i end,nil,"bgm"),
bgm=newSlider(750,250,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,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,8,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,back,nil,"game"),
},
setting2={--Control setting
setting_control={
back=newButton(840,630,180,60,color.white,40,back),
},
setting3={--Touch setting
setting_touch={
hide= newButton(640,210,500,80,color.white,45,function()
setting.virtualkeySwitch=not setting.virtualkeySwitch
end),
@@ -454,18 +459,25 @@ Widget={
back= newButton(640,410,170,80,color.white,45,back),
},
help={
his= newButton(1050, 520,230,60,color.white,40,function()gotoScene("history")end, nil, nil, "qq", "back", nil),
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", nil, "back", nil),
back= newButton(640, 600,180,60,color.white,40,back, nil, "his", nil, nil, "qq"),
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()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,back,nil,"qq"),
},
history={
prev= newButton(75, 320,100,300,color.white,40,function()love.keypressed("left")end,function()return sel==1 end),
next= newButton(1205, 320,100,300,color.white,40,function()love.keypressed("right")end,function()return sel==#updateLog end),
back= newButton(640, 640,200,70, color.white,40,back),
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),
},
stat={
path= newButton(980,590,250,60,color.white,30,function()sys.openURL(fs.getSaveDirectory())end,function()return mobile end,nil,nil,"back",nil),
back= newButton(640,590,180,60,color.white,40,back,nil,nil,nil,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,back,nil,"path"),
},
sel=nil,--selected widget id
}
}
for S,L in next,Widget do
for N,W in next,L do
if W.next then
W.next,L[W.next].prev=L[W.next],W
end
end
end
widget_sel=nil--selected widget object

646
main.lua

File diff suppressed because it is too large Load Diff

569
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,8 @@ 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.."["..(int(stat.extraRate/stat.piece*10000)*.01).."%]"
end
end
local statOptL={
@@ -88,6 +74,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,16 +90,17 @@ 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
FX={
flash=0,--Black screen(frame)
shake=0,--Screen shake(frame)
attack={},--Attack beam
badge={},--badge thrown
FX_BGblock={tm=150,next=7,ct=0,list={{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},{v=0},}}--Falling tetrominos on background
FX_attack={}--Attack beam
FX_badge={}--Badge thrown
sysFX={}
FX_ripple={}--Ripple&SqrShade
textFX={
appear=function(t,a)
setFont(t.font)
gc.setColor(1,1,1,a)
@@ -179,17 +168,6 @@ FX={
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,7 +176,6 @@ 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
@@ -228,70 +205,77 @@ local function drawVirtualkey()
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(mouseBlock[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 +284,7 @@ matrix=function()
gc.rectangle("fill",80*i,80*j,80,80)
end
end
end,
}
end
function Pnt.load()
gc.setLineWidth(4)
@@ -315,14 +298,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,17 +315,19 @@ function Pnt.intro()
end
function Pnt.main()
gc.setColor(1,1,1)
gc.draw(titleImage,280,30,nil,1.3)
setFont(30)
gc.print(gameVersion,290,125)
gc.print(system,845,95)
gc.draw(coloredTitleImage,60,30,nil,1.3)
gc.draw(drawableText.warning,595-drawableText.warning:getWidth(),128)
setFont(35)
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)
gc.draw(titleImage,810,30)
gc.draw(titleImage,830,30)
setFont(40)
gc.setColor(modeLevelColor[modeLevel[modeID[modeSel]][levelSel]]or color.white)
mStr(modeLevel[modeID[modeSel]][levelSel],270,215)
@@ -368,29 +353,37 @@ function Pnt.music()
gc.draw(drawableText.musicRoom,20,20)
gc.setColor(1,1,1)
gc.draw(drawableText.musicRoom,22,23)
gc.draw(drawableText.nowPlaying,490,110)
gc.draw(drawableText.nowPlaying,490,390)
setFont(35)
for i=1,#musicID do
gc.print(musicID[i],50,90+30*i)
end
setFont(50)
gc.setColor(sin(Timer()*.5)*.2+.8,sin(Timer()*.7)*.2+.8,sin(Timer())*.2+.8)
mStr(bgmPlaying or"",630,180)
gc.draw(titleImage,640,310,nil,1.5,nil,206,35)
if bgmPlaying then
setFont(50)
gc.setColor(sin(Timer()*.5)*.2+.8,sin(Timer()*.7)*.2+.8,sin(Timer())*.2+.8)
mStr(bgmPlaying or"",630,460)
local t=-Timer()%2.3/2
if t<1 then
gc.setColor(1,1,1,t)
gc.draw(coloredTitleImage,640,310,nil,1.5+.1-.1*t,1.5+.3-.3*t,206,35)
end
end
end
function Pnt.custom()
gc.setColor(1,1,1,.3+sin(Timer()*8)*.2)
gc.rectangle("fill",25,95+40*sel,465,40)
gc.rectangle("fill",25,95+40*sel,480,40)
gc.setColor(.8,.8,.8)gc.draw(drawableText.custom,20,20)
gc.setColor(1,1,1)gc.draw(drawableText.custom,22,23)
setFont(40)
for i=1,#customID do
local k=customID[i]
local y=90+40*i
gc.printf(text.customOption[k],30,y,320,"right")
gc.printf(text.customOption[k],15,y,320,"right")
if text.customVal[k]then
gc.print(text.customVal[k][customSel[i]],350,y)
gc.print(text.customVal[k][customSel[i]],335,y)
else
gc.print(customRange[k][customSel[i]],350,y)
gc.print(customRange[k][customSel[i]],335,y)
end
end
end
@@ -407,7 +400,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)
@@ -435,295 +428,35 @@ 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]
for i=1,#FX_attack do
local A=FX_attack[i]
gc.push("transform")
local a=A.a
if A.t<20 then
gc.translate(A.x1,A.y1)
a=a*A.t*.05
elseif A.t<80 then
local t=((A.t-20)*.016667)t=(3-2*t)*t*t
gc.translate(A.x1*(1-t)+A.x2*t,A.y1*(1-t)+A.y2*t)
else
gc.translate(A.x2,A.y2)
a=a*(5-A.t*.05)
end
gc.rotate(A.t*.1)
local a=A.t<10 and A.a*A.t*.05 or A.t>50 and A.a*(6-A.t*.1)or A.a
gc.setColor(A.r,A.g,A.b,a*.5)
gc.circle("line",0,0,A.rad,A.corner)
local L=A.drag
for i=1,#L,2 do
gc.setColor(A.r,A.g,A.b,a*i*.05)
gc.translate(L[i],L[i+1])
gc.rotate(A.t*.1)
gc.circle("fill",0,0,A.rad,A.corner)
gc.rotate(-A.t*.1)
gc.translate(-L[i],-L[i+1])
end
gc.setColor(A.r,A.g,A.b,a)
gc.translate(A.x,A.y)
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 modeEnv.royaleMode then
for i=1,#FX.badge do
local b=FX.badge[i]
for i=1,#FX_badge do
local b=FX_badge[i]
gc.setColor(1,1,1,b.t<10 and b.t*.1 or b.t<50 and 1 or(60-b.t)*.1)
if b.t<10 then
gc.draw(badgeIcon,b[1]-14,b[2]-14)
@@ -734,26 +467,24 @@ 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/17)
gc.setColor(0,0,0,restartCount/20)
gc.rectangle("fill",0,0,1280,720)
end
end
@@ -764,34 +495,44 @@ function Pnt.pause()
gc.setColor(1,1,1,pauseTimer*.02)
setFont(30)
if pauseCount>0 then
gc.print(text.pauseTime..":["..pauseCount.."] "..format("%0.2f",pauseTime).."s",110,150)
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,15 do
gc.print(text.stat[i+3],860,30*i+30)
gc.print(dataOpt(i),1000,30*i+30)
end
setFont(40)
if system~="Android"then
mStr(text.space.."/"..text.enter,640,335)
gc.print("ESC",610,509)
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()
function Pnt.setting_game()
gc.setColor(1,1,1)
setFont(35)
mStr("DAS:"..setting.das,290,278)
mStr("ARR:"..setting.arr,506,278)
setFont(21)
mStr(text.softdropdas..setting.sddas,290,357)
mStr(text.softdroparr..setting.sdarr,506,357)
gc.draw(blockSkin[7-int(Timer()*2)%7],820,480,nil,2)
mDraw(drawableText.setting_game,640,15)
setFont(40)
mStr("DAS:"..setting.das,290,205)
mStr("ARR:"..setting.arr,610,205)
setFont(28)
mStr(text.softdropdas..setting.sddas,290,323)
mStr(text.softdroparr..setting.sdarr,610,323)
end
function Pnt.setting2()
function Pnt.setting_graphic()
gc.setColor(1,1,1)
mDraw(drawableText.setting_graphic,640,15)
gc.draw(blockSkin[7-int(Timer()*2)%7],940,440,nil,2)
end
function Pnt.setting_sound()
gc.setColor(1,1,1)
mDraw(drawableText.setting_sound,640,15)
end
function Pnt.setting_control()
local a=.3+sin(Timer()*15)*.1
if keyboardSetting then
gc.setColor(1,.5,.5,a)
@@ -821,12 +562,12 @@ function Pnt.setting2()
gc.line(40,550,640,550)
mDraw(drawableText.keyboard,340,0)
mDraw(drawableText.joystick,540,0)
gc.draw(drawableText.setting2Help,50,620)
gc.draw(drawableText.ctrlSetHelp,50,620)
setFont(40)
gc.print("P"..int(curBoard*.5+.5).."/P4",420,560)
gc.print(curBoard.."/8",580,560)
end
function Pnt.setting3()
function Pnt.setting_touch()
VirtualkeyPreview()
local d=snapLevelValue[snapLevel]
if d>=10 then
@@ -841,12 +582,14 @@ function Pnt.setting3()
end
end
function Pnt.help()
setFont(32)
setFont(30)
gc.setColor(1,1,1)
for i=1,11 do
gc.printf(text.help[i],140,15+43*i,1000,"center")
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,212,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)
@@ -861,19 +604,21 @@ 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
gc.draw(titleImage,260,600,.2+.07*sin(Timer()*3),nil,nil,212,35)
gc.draw(titleImage,260,600,.2+.07*sin(Timer()*3),nil,nil,206,35)
end
function Pnt.history()
gc.setColor(.2,.2,.2,.7)
gc.rectangle("fill",150,35,980,530)
gc.rectangle("fill",30,45,1000,632)
gc.setColor(1,1,1)
gc.setLineWidth(4)
gc.rectangle("line",150,35,980,530)
gc.rectangle("line",30,45,1000,632)
setFont(25)
gc.print(updateLog[sel],160,40)
for i=0,min(22,#updateLog-sel)do
gc.print(updateLog[sel+i],40,50+27*(i))
end
end
return Pnt

2315
player.lua Normal file

File diff suppressed because it is too large Load Diff

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

@@ -46,6 +46,7 @@ c:release()
gc.setDefaultFilter("linear","linear")
titleImage=N("/image/mess/title.png")
coloredTitleImage=N("/image/mess/title_colored.png")
dialCircle=N("/image/mess/dialCircle.png")
dialNeedle=N("/image/mess/dialNeedle.png")
badgeIcon=N("/image/mess/badge.png")
@@ -65,9 +66,11 @@ drawableText={
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(25),
musicRoom=T(80),
nowPlaying=T(50),
warning=T(30),
}
c=gc.setCanvas()

302
timer.lua
View File

@@ -3,17 +3,17 @@ 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
if loadnum<=#voiceList then
local N=voiceList[loadnum]
for i=1,#voice[N]do
voice[N][i]=love.audio.newSource("VOICE/"..voice[N][i]..".ogg","static")
if loadnum<=#voiceName then
local N=voiceName[loadnum]
for i=1,#voiceList[N]do
voiceBank[voiceList[N][i]]={love.audio.newSource("VOICE/"..voiceList[N][i]..".ogg","static")}
end
loadprogress=loadnum/#voiceList
loadprogress=loadnum/#voiceName
loadnum=loadnum+1
else
loading=2
@@ -41,39 +41,57 @@ 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")
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
local b=FX.attack[i]
for i=#FX_attack,1,-1 do
local b=FX_attack[i]
b.t=b.t+1
local t0=b.t*.025--t in [0,1]
local t=(sin(1.5*(2*t0-1))+1)*.5
if t0==1 then
rem(FX.attack,i)
if b.t>50 then
b.rad=b.rad*1.08+.2
b.x,b.y=b.x2,b.y2
elseif b.t>10 then
local t=((b.t-10)*.025)t=(3-2*t)*t*t
b.x,b.y=b.x1*(1-t)+b.x2*t,b.y1*(1-t)+b.y2*t
end
if b.t<60 then
local L=FX_attack[i].drag
if #L==6*setting.atkFX then
rem(L,1)rem(L,1)
end
ins(L,b.x)ins(L,b.y)
else
for i=1,#FX_attack do
FX_attack[i]=FX_attack[i+1]
end
end
end
for i=#FX.badge,1,-1 do
local b=FX.badge[i]
for i=#FX_badge,1,-1 do
local b=FX_badge[i]
b.t=b.t+1
if b.t==60 then
rem(FX.badge,i)
rem(FX_badge,i)
end
end
for i=1,#virtualkey do
@@ -81,18 +99,6 @@ play=function(dt)
virtualkeyPressTime[i]=virtualkeyPressTime[i]-1
end
end
local E=#FX.attack
for i=E,1,-1 do
local A=FX.attack[i]
A.t=A.t+1
if A.t>=100 then
for j=i,E do
FX.attack[j]=FX.attack[j+1]
end--remove [i]
elseif A.t>80 then
A.rad=A.rad*1.08+.2
end
end
if frame<180 then
if frame==179 then
@@ -101,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
@@ -116,7 +122,7 @@ play=function(dt)
return
elseif players[1].keyPressing[10]then
restartCount=restartCount+1
if restartCount>17 then
if restartCount>20 then
clearTask("play")
updateStat()
resetGameData()
@@ -126,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.fxs*.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 atk=P.atkBuffer[i]
atk.time=atk.time+1
if not atk.sent then
if atk.countdown>0 then
atk.countdown=atk.countdown-garbageSpeed
end
else
if atk.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

@@ -24,22 +24,27 @@ end
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)
@@ -65,26 +70,21 @@ 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",
}
function swapLanguage(l)
text=require("language/"..langID[l])
Widget.sel=nil
for S,L in next,Widget do
for N,W in next,L do
if W.type=="button"then
W.alpha=0
W.text=text.ButtonText[S][N]
end
W.text=text.WidgetText[S][N]
end
end
gc.push("transform")
@@ -109,6 +109,7 @@ function changeBlockSkin(n)
n=n-1
gc.push("transform")
gc.origin()
gc.setColor(1,1,1)
for i=1,13 do
gc.setCanvas(blockSkin[i])
gc.draw(blockImg,30-30*i,-30*n)
@@ -126,31 +127,41 @@ function VIB(t)
end
end
function SFX(s,v)
if setting.sfx then
if setting.sfx>0 then
local n=1
::L::if sfx[s][n]:isPlaying()then
while sfx[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
break
end
goto L
end::quit::
sfx[s][n]:setVolume(v or 1)
end
sfx[s][n]:setVolume((v or 1)*setting.sfx*.125)
sfx[s][n]:play()
end
end
function VOICE(s,n)
if setting.voc then
voicePlaying[#voicePlaying+1]=voice[s][n or rnd(#voice[s])]
if #voicePlaying==1 then
voicePlaying[1]:play()
function getFreeVoiceChannel()
local i=#voiceQueue
for i=1,i do
if #voiceQueue[i]==0 then return i end
end
voiceQueue[i+1]={}
return i+1
end
function VOICE(s,chn)
if setting.voc>0 then
if chn then
voiceQueue[chn][#voiceQueue[chn]+1]=voiceList[s][rnd(#voiceList[s])]
--添加到[chn]
else
voiceQueue[getFreeVoiceChannel()]={voiceList[s][rnd(#voiceList[s])]}
--自动查找/创建空轨
end
end
end
function BGM(s)
if setting.bgm then
if setting.bgm>0 then
if bgmPlaying~=s then
if bgmPlaying then newTask(Event_task.bgmFadeOut,nil,bgmPlaying)end
for i=#Task,1,-1 do
@@ -167,8 +178,19 @@ function BGM(s)
end
bgmPlaying=s
else
if bgmPlaying then bgm[bgmPlaying]:play()end
if bgmPlaying then
local v=setting.bgm*.125
bgm[bgmPlaying]:setVolume(v)
if v>0 then
bgm[bgmPlaying]:play()
else
bgm[bgmPlaying]:pause()
end
end
end
elseif bgmPlaying then
bgm[bgmPlaying]:pause()
bgmPlaying=nil
end
end
@@ -184,7 +206,7 @@ local swapDeck_data={
{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},
none={2,1,d=NULL},
flash={8,1,d=function()gc.clear(1,1,1)end},
fade={30,15,d=function()
local t=1-abs(sceneSwaping.time*.06667-1)
@@ -221,15 +243,16 @@ function gotoScene(s,style)
time=swap[style][1],mid=swap[style][2],
draw=swap[style].d
}
Widget.sel=nil
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
local S=players[1].stat
for k,v in next,S do
stat[k]=stat[k]+S[k]
end
end
local prevMenu={
@@ -239,26 +262,27 @@ local prevMenu={
music="main",
mode="main",
custom="mode",
draw=function()
gotoScene("custom")
end,
draw="custom",
play=function()
kb.setKeyRepeat(true)
updateStat()
saveData()
clearTask("play")
gotoScene(curMode.id~="custom"and"mode"or"custom","deck")
end,
pause=nil,
setting=function()
setting_game=function()
saveSetting()
gotoScene("main")
end,
setting2="setting",
setting3="setting",
setting_control="setting_game",
setting_touch= "setting_game",
help="main",
history="help",
stat="main",
}prevMenu.pause=prevMenu.play
}
prevMenu.pause=prevMenu.play
prevMenu.setting_graphic=prevMenu.setting_game
prevMenu.setting_sound=prevMenu.setting_game
function back()
local t=prevMenu[scene]
if type(t)=="string"then
@@ -267,6 +291,82 @@ function back()
t()
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
end
end
function pauseGame()
pauseTimer=0--Pause timer for animation
if not gamefinished then
@@ -276,7 +376,7 @@ 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
@@ -285,8 +385,97 @@ end
function resumeGame()
gotoScene("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
gotoScene("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
for i=1,#virtualkey do
virtualkey[i].press=false
end
collectgarbage()
end
function resetGameData()
gamefinished=false
frame=0
garbageSpeed=1
pushSpeed=3
pauseTime=0--Time paused
pauseCount=0--Times paused
destroyPlayers()
local E=defaultModeEnv[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
for i=1,#virtualkey do
virtualkey[i].press=false
end
stat.game=stat.game+1
local m,p=#freeRow,40*#players+1
while freeRow[p]do
m,freeRow[m]=m-1
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",
@@ -322,7 +511,6 @@ 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()
@@ -339,13 +527,32 @@ function loadSetting()
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=="bgblock"or t=="voc"then
setting[t]=v=="true"
if t=="sfx"or t=="bgm"or t=="voc"then
setting[t]=toN(v:match("[012345678]"))or setting[t]
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=="virtualkeyAlpha"then
setting.virtualkeyAlpha=min(int(abs(toN(v))),10)
elseif
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=="virtualkeyIcon"or t=="virtualkeySwitch"
then
setting[t]=v=="true"
elseif t=="frameMul"then
setting.frameMul=min(max(toN(v)or 100,0),100)
elseif t=="das"or t=="arr"or t=="sddas"or t=="sdarr"then
v=toN(v)if not v or v<0 then v=0 end
setting[t]=int(v)
elseif t=="dropFX"or t=="shakeFX"or t=="atkFX"then
setting[t]=toN(v:match("[0123]"))or 0
elseif t=="lang"then
setting[t]=toN(v:match("[123]"))or 1
elseif t=="skin"then
setting[t]=toN(v:match("[12345678]"))or 1
elseif t=="keymap"then
v=splitS(v,"/")
for i=1,16 do
@@ -364,44 +571,36 @@ function loadSetting()
end
end
end
elseif t=="virtualkeyAlpha"then
setting.virtualkeyAlpha=min(int(abs(toN(v))),10)
elseif t=="virtualkeyIcon"or t=="virtualkeySwitch"then
setting[t]=v=="true"
elseif t=="frameMul"then
setting.frameMul=min(max(toN(v)or 100,0),100)
elseif t=="das"or t=="arr"or t=="sddas"or t=="sdarr"then
v=toN(v)if not v or v<0 then v=0 end
setting[t]=int(v)
elseif t=="ghost"or t=="center"or t=="grid"or t=="swap"or t=="bg"or t=="smo"then
setting[t]=v=="true"
elseif t=="fxs"then
setting[t]=toN(v:match("[0123]"))or 0
elseif t=="lang"then
setting[t]=toN(v:match("[123]"))or 1
elseif t=="skin"then
setting[t]=toN(v:match("[123456]"))or 1
end
end
end
end
local saveOpt={
"ghost","center",
"grid","swap",
"fxs","bg",
"das","arr",
"sddas","sdarr",
"quickR",
"swap",
"fine",
"ghost","center",
"smo","grid",
"dropFX",
"shakeFX",
"atkFX",
"frameMul",
"fullscreen",
"bg",
"bgblock",
"lang",
"skin",
"sfx","bgm",
"vib","voc",
"fullscreen",
"bgblock",
"skin","smo",
"virtualkeyAlpha",
"virtualkeyIcon",
"virtualkeySwitch",
"frameMul",
}
function saveSetting()
local vk={}
@@ -424,7 +623,6 @@ function saveSetting()
--not always i+2!
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,47 @@
return{
[=[Future outlook:
Brand New GUI:
custom restart method
local S=[=[
Patron(rmb10+):
gggf/T080/Ykzl/zxc
[D*a]?
Future outlook:
Normal Things:
ajustable next count
bag line in all mode
force fineese mode
highscore of most modes
custom block color/direction
custom sequence
virtual key switch(all keys)
Normal Things:
demo play at main menu
combo mode
infinite c4w mode
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.23:
remake all BGM!
more FXs & 3d features & animations
0.7.28:
add fineese check
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!
new mode:Master-Final
new modes:attacker & defender(not survivor!)
add restart button when pause
@@ -27,7 +49,8 @@ return{
change falling animation
new GUI details
louder sound
code optimized & many bugs fixed]=],[=[
code optimized
many bugs fixed
0.7.22:
scoring system
smooth dropping
@@ -46,7 +69,7 @@ return{
0.7.21:
new title image
more GUI details
many bugs fixed]=],[=[
many bugs fixed
0.7.20:
add music room
change block/space apperance in draw mode
@@ -63,7 +86,7 @@ return{
add 2 new block skins
new difficulty in infinite mode
new background/sound effect in master mode
bug fixed]=],[=[
bug fixed
0.7.18:
3 new block skins!(one skin origional by Miya(nya~))
better restarting(to prevent mistakenly touching)
@@ -79,7 +102,7 @@ return{
adjust difficulty of PC train mode
adjust vibrate level for mobile devices
little optimized
bugs fixed]=],[=[
bugs fixed
0.7.16:
bugs fixed
change rules of custom puzzle mode
@@ -92,7 +115,7 @@ return{
can pause game with animation
change icon of "Functional key"
speed optimized
bugs fixed]=],[=[
bugs fixed
0.7.14:
drawing mode in custom game
can adjust virtual keys with mouse
@@ -103,7 +126,7 @@ return{
little game rule change
bugs fixed(AI control error)
0.7.13:
Chniese game name:方块研究所
Chinese game name:方块研究所
SUPER COOL instant moving effect
new b2b bar style & animation
new transition animation
@@ -111,7 +134,7 @@ return{
adjust delay algorithm(probably cause controlfeel changing,please reset your DAS setting)
code reconstructed
bugs fixed(error when seq=his,size of custom oppo)
debug key change to F8]=],[=[
debug key change to F8
0.7.12:
AI learned to switch attack mode
seperate master mode from marathon mode
@@ -124,7 +147,7 @@ return{
grid switch
swap target by combo key/press
some Chinese translaton editted
[reconstruct event system]]=],[=[
[reconstruct event system]
0.7.11:
some Chinese translaton editted
add bone block in 2 hardest marathon(new block-fresh system)
@@ -135,7 +158,7 @@ return{
clearer attacking pointer
fix 6 next in classic mode
add QR code in help page
change some detials]=],[=[
change some detials
0.7.10:
更完全的中文翻译
add Classic mode
@@ -148,7 +171,7 @@ return{
change rotate system
change BGM&BG set
code optimized
fix bugs]=],[=[
fix bugs
0.7.8:
GPU usage decreased much more than before
add virtual key animation
@@ -163,7 +186,7 @@ return{
combine some modes
change some GUI
more SFXs
fix bugs]=],[=[
fix bugs
0.7.6:
new font
add DIFFICULTY selection
@@ -175,7 +198,7 @@ return{
better GUI&change speed&BGM in royale mode
more FXs in royale mode
fix all attacking bug of royale mode
change sequence of TSD-only mode to bag7]=],[=[
change sequence of TSD-only mode to bag7
0.7.5:
reduce difficuly of PC training mode,and add more patterns
reduce difficuly of death mode
@@ -189,7 +212,7 @@ return{
change game icon
adjust GUI of royale mode
change sequence of TSD-only mode
royale mode use LESS GPU]=],[=[
royale mode use LESS GPU
0.7.4:
add a lot of bugs
0.7.3:
@@ -205,5 +228,15 @@ return{
remove non-sense s/z spin double
GUI position editted
grid BG changed
smarter AI]=]
}
smarter AI
]=]
local find,sub=string.find,string.sub
local L,n,p={},1,1
local eof=#S
repeat
p1=find(S,"\n",p)
L[n]=sub(S,p,p1-1)
n=n+1
p=p1+1
until p1==eof
return L