Compare commits

...

3 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
26 changed files with 3894 additions and 3251 deletions

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

View File

@@ -2,21 +2,8 @@ local gc=love.graphics
local rem=table.remove local rem=table.remove
local format=string.format local format=string.format
Task={} 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) function newTask(code,P,data)
Task[#Task+1]={ Task[#Task+1]={
update=Task.update,
code=code, code=code,
P=P, P=P,
data=data, data=data,
@@ -44,12 +31,7 @@ function clearTask(opt)
end end
end end
local a={a=1,b=2} local button={type="button"}
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
function newButton(x,y,w,h,color,font,code,hide,N) function newButton(x,y,w,h,color,font,code,hide,N)
local _={ local _={
x=x-w*.5,y=y-h*.5, 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, next=N,
}for k,v in next,button do _[k]=v end return _ }for k,v in next,button do _[k]=v end return _
end 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 return x>self.x and x<self.x+self.w and y>self.y and y<self.y+self.h
end end
function button:FX() function button:FX()
@@ -91,6 +73,7 @@ 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.y,self.w,self.h,self.font))
end end
local switch={type="switch"}
function newSwitch(x,y,font,disp,code,hide,N) function newSwitch(x,y,font,disp,code,hide,N)
local _={ local _={
x=x,y=y,font=font, x=x,y=y,font=font,
@@ -100,7 +83,7 @@ function newSwitch(x,y,font,disp,code,hide,N)
next=N, next=N,
}for k,v in next,switch do _[k]=v end return _ }for k,v in next,switch do _[k]=v end return _
end 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 return x>self.x and x<self.x+100 and y>self.y-20 and y<self.y+20
end end
function switch:FX() function switch:FX()
@@ -135,6 +118,7 @@ function switch:getInfo()
print(format("x=%d,y=%d,font=%d",self.x,self.y,self.font)) print(format("x=%d,y=%d,font=%d",self.x,self.y,self.font))
end end
local slider={type="slider"}
function newSlider(x,y,w,unit,font,change,disp,code,hide,N) function newSlider(x,y,w,unit,font,change,disp,code,hide,N)
local _={ local _={
x=x,y=y, x=x,y=y,
@@ -147,7 +131,7 @@ function newSlider(x,y,w,unit,font,change,disp,code,hide,N)
next=N, next=N,
}for k,v in next,slider do _[k]=v end return _ }for k,v in next,slider do _[k]=v end return _
end 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 return x>self.x-10 and x<self.x+self.w+10 and y>self.y-20 and y<self.y+20
end end
function slider:FX(pos) function slider:FX(pos)

View File

@@ -1,4 +1,4 @@
gameVersion="Alpha V0.7.24" gameVersion="Alpha V0.7.28"
function love.conf(t) function love.conf(t)
t.identity="Techmino"--Save directory name t.identity="Techmino"--Save directory name
t.version="11.1" t.version="11.1"
@@ -9,7 +9,7 @@ function love.conf(t)
t.audio.mixwithsystem=true--Switch on to keep sysBGM t.audio.mixwithsystem=true--Switch on to keep sysBGM
local W=t.window 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.icon="/image/icon.png"
W.width,W.height=1280,720 W.width,W.height=1280,720
W.minwidth,W.minheight=640,360 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: 17 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -61,7 +61,10 @@ return{
snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"}, snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"},
keyboard="键盘",joystick="手柄", keyboard="键盘",joystick="手柄",
space="空格",enter="回车", space="空格",enter="回车",
setting2Help="方向键选择/翻页,回车修改,esc返回", ctrlSetHelp="方向键选择/翻页,回车修改,esc返回",
setting_game="游戏设置",
setting_graphic="画面设置",
setting_sound="声音设置",
musicRoom="音乐室", musicRoom="音乐室",
nowPlaying="正在播放:", nowPlaying="正在播放:",
@@ -100,17 +103,15 @@ return{
load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",}, load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",},
tips={ tips={
"不是动画,真的在加载!", "不是动画,真的在加载!",
"整个游戏都是MrZ完成的!",
"大满贯10连击消四全清!", "大满贯10连击消四全清!",
"<方块研究所>有一个Nspire-CX版本!", "<方块研究所>有一个Nspire-CX版本!",
"B2B2B???", "B2B2B???",
"B2B2B2B存在吗?", "B2B2B2B存在吗?",
"MEGACMB!", "MEGACMB!",
"ALLSPIN!", "ALLSPIN!",
"O型回旋三清?", "O spin triple!",
"只用一个输入设备就可以游玩了",
"Miya:喵!", "Miya:喵!",
"225238922,哔哩哔哩 干杯~", "225238922 哔哩哔哩 干杯~",
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活", "适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
"合群了就会消失,但是消失不代表没有意义", "合群了就会消失,但是消失不代表没有意义",
"学会使用两个旋转键,三个更好", "学会使用两个旋转键,三个更好",
@@ -125,9 +126,10 @@ return{
"2.7182818284590452353", "2.7182818284590452353",
"Let-The-Bass-Kick!", "Let-The-Bass-Kick!",
"使用love2d引擎制作", "使用love2d引擎制作",
"哪里不舒服的话先看看设置有没有你想要", "有疑问?先看设置有没有你想要的",
"有建议的话可以把信息反馈给作者~", "有建议的话可以把信息反馈给作者~",
"本游戏不叫铁壳米诺", "CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
}, },
stat={ stat={
"游戏运行次数:", "游戏运行次数:",
@@ -147,6 +149,7 @@ return{
"B2B数:", "B2B数:",
"PC数:", "PC数:",
"效率:", "效率:",
"多余操作:"
}, },
help={ help={
"好像也没啥好帮助的吧?就当是关于了", "好像也没啥好帮助的吧?就当是关于了",
@@ -157,15 +160,24 @@ return{
"使用LOVE2D引擎", "使用LOVE2D引擎",
"作者:MrZ 邮箱:1046101471@qq.com", "作者:MrZ 邮箱:1046101471@qq.com",
"程序:MrZ 美术:MrZ 音乐:MrZ 音效:MrZ 语音:Miya", "程序:MrZ 美术:MrZ 音乐:MrZ 音效:MrZ 语音:Miya",
"使用工具:VScode,GFIE,Beepbox,Goldwave,Cold_Clear",
"特别感谢:Farter,Flyz,196,Teatube,T830,[所有测试人员]和 你!", "特别感谢:Farter,Flyz,196,Teatube,T830,[所有测试人员]和 你!",
"错误或者建议请附带相关信息发送到作者邮箱~", "错误或者建议请附带相关信息发送到作者邮箱~",
}, },
used=[[
使用工具:
Beepbox
GFIE
Goldwave
使用库:
Cold_Clear[MinusKelvin]
simple-love-lights[dylhunn]
]],
support="支持作者", support="支持作者",
group="官方QQ群", group="官方QQ群",
warning="禁 止 私 自 传 播", warning="禁 止 私 自 传 播",
WidgetText={ WidgetText={
main={ main={
lang="中文",
qplay="快速开始", qplay="快速开始",
play="开始", play="开始",
setting="设置", setting="设置",
@@ -231,25 +243,23 @@ return{
restart="重新开始", restart="重新开始",
quit= "退出", quit= "退出",
}, },
setting={
game= "游戏设置",
graphic="画面设置",
sound= "声音设置",
ctrl= "控制设置",
touch= "触屏设置",
lang= function()return langName[setting.lang]end,
back= "保存&返回",
},
setting_game={ setting_game={
graphic="←画面设置",
sound="声音设置→",
dasD="-",dasU="+", dasD="-",dasU="+",
arrD="-",arrU="+", arrD="-",arrU="+",
sddasD="-",sddasU="+", sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+", sdarrD="-",sdarrU="+",
holdR="长按重新开始", quickR="快速重新开始",
swap="组合键切换攻击模式", swap="组合键切换攻击模式",
fine="极简操作提示音",
ctrl="键位设置",
touch="触屏设置",
back=BK, back=BK,
}, },
setting_graphic={ setting_graphic={
sound="←声音设置",
game="游戏设置→",
ghost="阴影", ghost="阴影",
grid="网格", grid="网格",
center="旋转中心", center="旋转中心",
@@ -265,6 +275,8 @@ return{
back=BK, back=BK,
}, },
setting_sound={ setting_sound={
game="←游戏设置",
graphic="画面设置→",
sfx="音效", sfx="音效",
bgm="音乐", bgm="音乐",
vib="震动", vib="震动",

View File

@@ -61,7 +61,10 @@ return{
snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"}, snapLevelName={"任意摆放","10px吸附","20px吸附","40px吸附","60px吸附","80px吸附"},
keyboard="键盘",joystick="手柄", keyboard="键盘",joystick="手柄",
space="空格",enter="回车", space="空格",enter="回车",
setting2Help="方向键选择/翻页,回车修改,esc返回", ctrlSetHelp="方向键选择/翻页,回车修改,esc返回",
setting_game="游戏设置",
setting_graphic="画面设置",
setting_sound="声音设置",
musicRoom="音乐室", musicRoom="音乐室",
nowPlaying="正在播放:", nowPlaying="正在播放:",
@@ -100,17 +103,15 @@ return{
load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",}, load={"加载语音ing","加载音乐ing","加载音效ing","加载完成",},
tips={ tips={
"不是动画,真的在加载!", "不是动画,真的在加载!",
"整个游戏都是MrZ完成的!",
"大满贯10连击消四全清!", "大满贯10连击消四全清!",
"<方块研究所>有一个Nspire-CX版本!", "<方块研究所>有一个Nspire-CX版本!",
"B2B2B???", "B2B2B???",
"B2B2B2B存在吗?", "B2B2B2B存在吗?",
"MEGACMB!", "MEGACMB!",
"ALLSPIN!", "ALLSPIN!",
"O型回旋三清?", "O型回旋三清!",
"只用一个输入设备就可以游玩了",
"Miya:喵!", "Miya:喵!",
"225238922,哔哩哔哩 干杯~", "225238922 哔哩哔哩 干杯~",
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活", "适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
"合群了就会消失,但是消失不代表没有意义", "合群了就会消失,但是消失不代表没有意义",
"学会使用两个旋转键,三个更好", "学会使用两个旋转键,三个更好",
@@ -125,9 +126,10 @@ return{
"2.7182818284590452353", "2.7182818284590452353",
"Let-The-Bass-Kick!", "Let-The-Bass-Kick!",
"使用love2d引擎制作", "使用love2d引擎制作",
"哪里不舒服的话先看看设置有没有你想要", "有疑问?先看设置有没有你想要的",
"有建议的话可以把信息反馈给作者~", "有建议的话可以把信息反馈给作者~",
"郑重声明本游戏不叫[铁壳米诺]", "CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
}, },
stat={ stat={
"游戏运行次数:", "游戏运行次数:",
@@ -147,6 +149,7 @@ return{
"满贯数:", "满贯数:",
"全清数:", "全清数:",
"效率:", "效率:",
"多余操作:"
}, },
help={ help={
"好像也没啥好帮助的吧?就当是关于了", "好像也没啥好帮助的吧?就当是关于了",
@@ -157,15 +160,24 @@ return{
"使用LOVE2D引擎", "使用LOVE2D引擎",
"作者:MrZ 邮箱:1046101471@qq.com", "作者:MrZ 邮箱:1046101471@qq.com",
"程序:MrZ 美术:MrZ 音乐:MrZ 音效:MrZ 语音:Miya", "程序:MrZ 美术:MrZ 音乐:MrZ 音效:MrZ 语音:Miya",
"使用工具:VScode,GFIE,Beepbox,Goldwave,Cold_Clear",
"特别感谢:Farter,Flyz,196,Teatube,T830,[所有测试人员]和 你!", "特别感谢:Farter,Flyz,196,Teatube,T830,[所有测试人员]和 你!",
"错误或者建议请附带相关信息发送到作者邮箱~", "错误或者建议请附带相关信息发送到作者邮箱~",
}, },
used=[[
使用工具:
Beepbox
GFIE
Goldwave
使用库:
Cold_Clear[MinusKelvin]
simple-love-lights[dylhunn]
]],
support="支持作者", support="支持作者",
group="官方QQ群", group="官方QQ群",
warning="禁 止 私 自 传 播", warning="禁 止 私 自 传 播",
WidgetText={ WidgetText={
main={ main={
lang="全中文",
qplay="快速开始", qplay="快速开始",
play="开始", play="开始",
setting="设置", setting="设置",
@@ -231,25 +243,24 @@ return{
restart="重新开始", restart="重新开始",
quit= "退出", quit= "退出",
}, },
setting={
game= "游戏设置",
graphic="画面设置",
sound= "声音设置",
ctrl= "控制设置",
touch= "触屏设置",
lang= function()return langName[setting.lang]end,
back= "保存&返回",
},
setting_game={ setting_game={
graphic="←画面设置",
sound="声音设置→",
dasD="-",dasU="+", dasD="-",dasU="+",
arrD="-",arrU="+", arrD="-",arrU="+",
sddasD="-",sddasU="+", sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+", sdarrD="-",sdarrU="+",
holdR="长按重新开始", quickR="快速重新开始",
swap="组合键切换攻击模式", swap="组合键切换攻击模式",
fine="极简操作提示音",
ctrl="键位设置",
touch="触屏设置",
back=BK, back=BK,
}, },
setting_graphic={ setting_graphic={
sound="←声音设置",
game="游戏设置→",
ghost="阴影", ghost="阴影",
grid="网格", grid="网格",
center="旋转中心", center="旋转中心",
@@ -265,6 +276,8 @@ return{
back=BK, back=BK,
}, },
setting_sound={ setting_sound={
game="←游戏设置",
graphic="画面设置→",
sfx="音效", sfx="音效",
bgm="音乐", bgm="音乐",
vib="震动", vib="震动",

View File

@@ -61,7 +61,10 @@ return{
snapLevelName={"Free pos","Snap-10","Snap-20","Snap-40","Snap-60","Snap-80"}, snapLevelName={"Free pos","Snap-10","Snap-20","Snap-40","Snap-60","Snap-80"},
keyboard="Keyboard",joystick="Joystick", keyboard="Keyboard",joystick="Joystick",
space="Space",enter="Enter", 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", musicRoom="Music Room",
nowPlaying="Now Playing:", nowPlaying="Now Playing:",
@@ -100,17 +103,15 @@ return{
load={"Loading VOICE","Loading BGM","Loading SFX","Finished",}, load={"Loading VOICE","Loading BGM","Loading SFX","Finished",},
tips={ tips={
"Not animation,real loading!", "Not animation,real loading!",
"The WHOLE game is made by MrZ!",
"Back to Back 10 combo Techrash PC!", "Back to Back 10 combo Techrash PC!",
"Techmino has a Nspire-CX edition!", "Techmino has a Nspire-CX edition!",
"B2B2B???", "B2B2B???",
"Is B2B2B2B possible?", "Is B2B2B2B possible?",
"MEGACMB!", "MEGACMB!",
"ALLSPIN!", "ALLSPIN!",
"O spin triple?", "O spin triple!",
"You can play with any input device!",
"Miya:Nya!", "Miya:Nya!",
"225238922,Bilibili cheers!", "225238922 Bilibili cheers!",
"Playing too much = taking drugs", "Playing too much = taking drugs",
"Disappearing doesn't mean useless", "Disappearing doesn't mean useless",
"Try to use two rotate button,three better", "Try to use two rotate button,three better",
@@ -126,8 +127,10 @@ return{
"Let-The-Bass-Kick!", "Let-The-Bass-Kick!",
"Powered by love2d", "Powered by love2d",
"Find out what's in the setting!", "Find out what's in the setting!",
"Any suggestions to author!~", "Any suggestions to author!",
"Techmino=Technique+tetromino", "Techmino=Technique+Tetromino",
"CLASSIC SEXY RUSSIAN BLOCKS",
"LrL,RlR LLr,RRl RRR/LLL F!!",--ZSLJTTI
}, },
stat={ stat={
"Games run:", "Games run:",
@@ -137,7 +140,7 @@ return{
"Rotate:", "Rotate:",
"Hold:", "Hold:",
"Block used:", "Block used:",
"Rows cleared:", "Lines cleared:",
"Attack:", "Attack:",
"Sent:", "Sent:",
"Receive:", "Receive:",
@@ -147,6 +150,7 @@ return{
"B2B:", "B2B:",
"PC:", "PC:",
"Efficiency:", "Efficiency:",
"Fineese:"
}, },
help={ help={
"I don't think you need \"help\".", "I don't think you need \"help\".",
@@ -156,16 +160,25 @@ return{
"", "",
"Powered by LOVE2D", "Powered by LOVE2D",
"Author:MrZ E-mail:1046101471@qq.com", "Author:MrZ E-mail:1046101471@qq.com",
"Programe:MrZ Art:MrZ Music:MrZ SFX:MrZ VOICE:Miya", "Program:MrZ Art:MrZ Music:MrZ SFX:MrZ VOICE:Miya",
"Tool used:VScode,GFIE,Beepbox,Goldwave,Cold_Clear",
"Special thanks:Farter,Flyz,196,Teatube,T830,[all test staff] and YOU!", "Special thanks:Farter,Flyz,196,Teatube,T830,[all test staff] and YOU!",
"Any bugs/suggestions to my E-mail.", "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", support="Support Author",
group="Official QQ Group", group="Official QQ Group",
warning="DO NOT DISTRIBUTE", warning="DO NOT DISTRIBUTE",
WidgetText={ WidgetText={
main={ main={
lang="English",
qplay="Qplay", qplay="Qplay",
play="Play", play="Play",
setting="Settings", setting="Settings",
@@ -231,25 +244,23 @@ return{
restart="Restart", restart="Restart",
quit="Quit", 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={ setting_game={
graphic="←Graphic",
sound="Sound→",
dasD="-",dasU="+", dasD="-",dasU="+",
arrD="-",arrU="+", arrD="-",arrU="+",
sddasD="-",sddasU="+", sddasD="-",sddasU="+",
sdarrD="-",sdarrU="+", sdarrD="-",sdarrU="+",
holdR="Hold R to restart", quickR="Quick restart",
swap="Combo key to change ATK mode", swap="Combo key to change ATK mode",
fine="Fineese error SFX",
ctrl="Key Setting",
touch="Touch Setting",
back=BK, back=BK,
}, },
setting_graphic={ setting_graphic={
sound="←Sound",
game="Game→",
ghost="Ghost", ghost="Ghost",
grid="Grid", grid="Grid",
center="Center", center="Center",
@@ -261,10 +272,12 @@ return{
shakeFX="Shake FX level", shakeFX="Shake FX level",
atkFX="ATK FX level", atkFX="ATK FX level",
fullscreen="Fullscreen", fullscreen="Fullscreen",
frame="drawFPS", frame="draw FPS",
back=BK, back=BK,
}, },
setting_sound={ setting_sound={
game="←Game",
graphic="Graphic→",
sfx="SFX", sfx="SFX",
bgm="BGM", bgm="BGM",
vib="VIB", vib="VIB",

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

141
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" 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"}
@@ -53,12 +49,13 @@ blockColor={
color.darkGreen, color.darkGreen,
} }
sfx={ sfx={
"welcome",
"button","swipe", "button","swipe",
"ready","start","win","fail","collect", "ready","start","win","fail","collect",
"move","rotate","rotatekick","hold", "move","rotate","rotatekick","hold",
"prerotate","prehold", "prerotate","prehold",
"lock","drop","fall", "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", "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", "clear_1","clear_2","clear_3","clear_4",
"spin_0","spin_1","spin_2","spin_3", "spin_0","spin_1","spin_2","spin_3",
@@ -178,10 +175,10 @@ modeLevel={
tsd={"NORMAL","HARD"}, tsd={"NORMAL","HARD"},
blind={"EASY","HARD","HARD+","LUNATIC","ULTIMATE","GM"}, blind={"EASY","HARD","HARD+","LUNATIC","ULTIMATE","GM"},
dig={"NORMAL","LUNATIC"}, dig={"NORMAL","LUNATIC"},
survivor={"EASY","NORMAL","HARD","LUNATIC","ULTIMATE","EXTRA"}, survivor={"EASY","NORMAL","HARD","LUNATIC","ULTIMATE"},
defender={"NORMAL","LUNATIC"}, defender={"NORMAL","LUNATIC"},
attacker={"HARD","ULTIMATE"}, attacker={"HARD","ULTIMATE"},
tech={"NORMAL","NORMAL+","HARD","HARD+","LUNATIC","LUNATIC+",}, tech={"NORMAL","NORMAL+","HARD","HARD+","LUNATIC","LUNATIC+","ULTIMATE","ULTIMATE+",},
c4wtrain={"NORMAL","LUNATIC"}, c4wtrain={"NORMAL","LUNATIC"},
pctrain={"NORMAL","EXTRA"}, pctrain={"NORMAL","EXTRA"},
pcchallenge={"NORMAL","HARD","LUNATIC"}, pcchallenge={"NORMAL","HARD","LUNATIC"},
@@ -281,25 +278,28 @@ local function useDefaultSet(n)
BGM(customRange.bgm[customSel[13]]) BGM(customRange.bgm[customSel[13]])
end end
Widget={ Widget={
load={}, load={},intro={},quit={},
intro={},
main={ main={
qplay= newButton(160, 300,150,150,color.lightRed, 40,function()loadGame(modeSel,levelSel)end, nil,"play"), play= newButton(150,280,200,160,color.red, 60,function()gotoScene("mode")end, nil,"setting"),
play= newButton(380, 300,240,240,color.red, 70,function()gotoScene("mode")end, nil,"setting"), setting=newButton(370,280,200,160,color.lightBlue, 50,function()gotoScene("setting_game")end, nil,"music"),
setting=newButton(640, 300,240,240,color.lightBlue,55,function()gotoScene("setting")end, nil,"music"), music= newButton(590,280,200,160,color.lightPurple,37,function()gotoScene("music")end, nil,"help"),
music= newButton(900, 300,240,240,color.lightCyan,42,function()gotoScene("music")end, nil,"stat"), help= newButton(150,460,200,160,color.yellow, 55,function()gotoScene("help")end, nil,"stat"),
stat= newButton(640, 560,240,240,color.cyan, 55,function()gotoScene("stat")end, nil,"help"), stat= newButton(370,460,200,160,color.cyan, 48,function()gotoScene("stat")end, nil,"qplay"),
help= newButton(900, 560,240,240,color.yellow, 55,function()gotoScene("help")end, nil,"quit"), qplay= newButton(540,415,100,70,color.lightGreen, 28,function()loadGame(modeSel,levelSel)end, nil,"lang"),
quit= newButton(1180,620,120,120,color.lightGrey,50,function()gotoScene("quit")end, nil,"qplay"), 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={ mode={
up= newButton(1000,210,200,140,color.white, 80,function()love.keypressed("up")end,function()return modeSel==1 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), 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), 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), 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), 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), custom= newButton(275, 420,200,90, color.yellow,40,function()gotoScene("custom")end),
back= newButton(640, 630,230,90, color.white, 45,back), back= newButton(640, 630,230,90, color.white,45,back),
}, },
music={ music={
bgm= newSlider(760,80,400,8,40,nil,function()return setting.bgm end,function(i)setting.bgm=i;BGM(bgmPlaying)end), bgm= newSlider(760,80,400,8,40,nil,function()return setting.bgm end,function(i)setting.bgm=i;BGM(bgmPlaying)end),
@@ -309,10 +309,10 @@ Widget={
back= newButton(640, 630,230,90, color.white,45,back), back= newButton(640, 630,230,90, color.white,45,back),
}, },
custom={ custom={
up= newButton(1000,220,100,100,color.white, 50,function()sel=(sel-2)%#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), 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), 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), 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), 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), 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), draw= newButton(1000,90, 190,85, color.cyan, 40,function()gotoScene("draw")end),
@@ -336,9 +336,9 @@ Widget={
gb2= newButton(1120,360,120,120,color.grey, 65,function()pen=10 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), 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), 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), 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), 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), clear= newButton(1120,640,120,120,color.white, 45,function()love.keypressed("delete")end),
back= newButton(1235,45, 80, 80, color.white, 35,back), back= newButton(1235,45, 80, 80, color.white, 35,back),
}, },
play={ play={
@@ -354,22 +354,12 @@ Widget={
end), end),
quit= newButton(640,600,240,100,color.white,50,back), 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_game={ setting_game={
dasD= newButton(150,120,50,50,color.white,40,function()setting.das=(setting.das-1)%31 end, nil,"dasU"), graphic=newButton(200,80,240,80,color.lightGreen,40,function()gotoScene("setting_graphic")end, nil,"sound"),
dasU= newButton(370,120,50,50,color.white,40,function()setting.das=(setting.das+1)%31 end, nil,"arrD"), sound= newButton(1080,80,240,80,color.lightGreen,40,function()gotoScene("setting_sound")end, nil,"dasD"),
arrD= newButton(450,120,50,50,color.white,40,function() 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 setting.arr=(setting.arr-1)%16
if setting.arr>setting.das then if setting.arr>setting.das then
setting.das=setting.arr setting.das=setting.arr
@@ -377,7 +367,7 @@ Widget={
SFX("blip_1",.4) SFX("blip_1",.4)
end end
end,nil,"arrU"), 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 setting.arr=(setting.arr+1)%16
if setting.arr>setting.das then if setting.arr>setting.das then
setting.das=setting.arr setting.das=setting.arr
@@ -385,46 +375,53 @@ Widget={
SFX("blip_1",.4) SFX("blip_1",.4)
end end
end,nil,"sddasD"), end,nil,"sddasD"),
sddasD= newButton(150,230,50,50,color.white,40,function()setting.sddas=(setting.sddas-1)%11 end, nil,"sddasU"), sddasD= newButton(180,340,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"), sddasU= newButton(400,340,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"), sdarrD= newButton(500,340,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"), sdarrU= newButton(720,340,50,50,color.white,40,function()setting.sdarr=(setting.sdarr+1)%4 end, nil,"quickR"),
holdR= newSwitch(510,330,40,function()return setting.holdR end,function()setting.holdR=not setting.holdR end, nil,"swap"), quickR= newSwitch(560,430,40,function()return setting.quickR end,function()setting.quickR=not setting.quickR end, nil,"swap"),
swap= newSwitch(510,420,25,function()return setting.swap end,function()setting.swap=not setting.swap end, nil,"back"), swap= newSwitch(560,510,25,function()return setting.swap end,function()setting.swap=not setting.swap end, nil,"fine"),
back= newButton(640,620,300,70,color.white,40,back,nil,"dasD"), 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={ setting_graphic={
ghost= newSwitch(310,90,40, function()return setting.ghost end, function()setting.ghost= not setting.ghost end, nil,"center"), sound= newButton(200,80,240,80,color.lightGreen,40,function()gotoScene("setting_sound")end, nil,"game"),
center= newSwitch(580,90,40, function()return setting.center end, function()setting.center= not setting.center end, nil,"smo"), game= newButton(1080,80,240,80,color.lightGreen,40,function()gotoScene("setting_game")end, nil,"ghost"),
smo= newSwitch(310,170,25, function()return setting.smo end, function()setting.smo= not setting.smo end, nil,"grid"), ghost= newSwitch(310,180,40,function()return setting.ghost end, function()setting.ghost= not setting.ghost end, nil,"center"),
grid= newSwitch(580,170,40, function()return setting.grid end, function()setting.grid= not setting.grid end, nil,"dropFX"), center= newSwitch(580,180,40,function()return setting.center end, function()setting.center= not setting.center end, nil,"smo"),
dropFX= newSlider(310,260,373,3,40,nil,function()return setting.dropFX end, function(i)setting.dropFX=i end, nil,"shakeFX"), smo= newSwitch(310,260,25,function()return setting.smo end, function()setting.smo= not setting.smo end, nil,"grid"),
shakeFX=newSlider(310,340,373,3,40,nil,function()return setting.shakeFX end, function(i)setting.shakeFX=i end, nil,"atkFX"), grid= newSwitch(580,260,40,function()return setting.grid end, function()setting.grid= not setting.grid end, nil,"dropFX"),
atkFX= newSlider(310,420,373,3,40,nil,function()return setting.atkFX end, function(i)setting.atkFX=i end, nil,"frame"), dropFX= newSlider(310,350,373,3,40,nil,function()return setting.dropFX end, function(i)setting.dropFX=i end, nil,"shakeFX"),
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"), shakeFX=newSlider(310,430,373,3,40,nil,function()return setting.shakeFX end, function(i)setting.shakeFX=i end, nil,"atkFX"),
fullscreen=newSwitch(990,90,40,function()return setting.fullscreen end,function() 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 setting.fullscreen=not setting.fullscreen
love.window.setFullscreen(setting.fullscreen) love.window.setFullscreen(setting.fullscreen)
if not setting.fullscreen then if not setting.fullscreen then
love.resize(gc.getWidth(),gc.getHeight()) love.resize(love.graphics.getWidth(),love.graphics.getHeight())
end end
end,nil,"bg"), end,nil,"bg"),
bg= newSwitch(990,170,40,function()return setting.bg end,function()setting.bg=not setting.bg end, nil,"bgblock"), bg= newSwitch(990,250,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() 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 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"), end,nil,"skin"),
skin= newButton(950,450,120,60,color.white,40,function() skin= newButton(860,470,120,60,color.white,40,function()
setting.skin=setting.skin%6+1 setting.skin=setting.skin%8+1
changeBlockSkin(setting.skin) changeBlockSkin(setting.skin)
end,nil,"back"), end,nil,"back"),
back= newButton(600,620,300,70,color.white,40,back,nil,"ghost"), back= newButton(1160,600,160,160,color.white,55,back,nil,"sound"),
}, },
setting_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"), game= newButton(200,80,240,80,color.lightGreen,40,function()gotoScene("setting_game")end, nil,"graphic"),
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"), graphic=newButton(1080,80,240,80,color.lightGreen,40,function()gotoScene("setting_graphic")end, nil,"sfx"),
vib=newSlider(180,340,400,5,40,function()VIB(1)end, function()return setting.vib end,function(i)setting.vib=i end,nil,"voc"), 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"),
voc=newSlider(750,340,400,8,40,function()VOICE("nya")end, function()return setting.voc end,function(i)setting.voc=i end,nil,"back"), 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"),
back=newButton(640,620,300,70,color.white,40,back,nil,"sfx"), 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"),
}, },
setting_control={ setting_control={
back=newButton(840,630,180,60,color.white,40,back), back=newButton(840,630,180,60,color.white,40,back),
@@ -463,7 +460,7 @@ Widget={
}, },
help={ help={
his= newButton(1050,520,230,60,color.white,40,function()gotoScene("history")end,nil,"back"), 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"), 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"), back= newButton(640, 600,180,60,color.white,40,back,nil,"qq"),
}, },
history={ history={
@@ -472,8 +469,8 @@ Widget={
back= newButton(1155,600,180,90,color.white,40,back), back= newButton(1155,600,180,90,color.white,40,back),
}, },
stat={ stat={
path= newButton(980,590,250,60,color.white,30,function()sys.openURL(fs.getSaveDirectory())end,function()return mobile end,"back"), 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,590,180,60,color.white,40,back,nil,"path"), back= newButton(640,620,180,60,color.white,40,back,nil,"path"),
}, },
} }
for S,L in next,Widget do for S,L in next,Widget do

197
main.lua
View File

@@ -1,25 +1,23 @@
--[[ --[[
第一次搞这么大的工程~参考价值不是很大 第一次搞这么大的工程~参考价值不是很大
如果你有时间并且也热爱俄罗斯方块的话,来看代码或者帮助优化的话当然欢迎! 如果你有时间并且也热爱俄罗斯方块的话,来看代码或者帮助优化的话当然欢迎!
顺便,不经允许直接盗代码的先死个妈 (顺便,无授权直接盗代码的先死个妈)
]] ]]
local love=love local love=love
local gc,tm=love.graphics,love.timer
local ms,kb,tc=love.mouse,love.keyboard,love.touch local ms,kb,tc=love.mouse,love.keyboard,love.touch
local fs,sys,wd=love.filesystem,love.system,love.window local gc,sys=love.graphics,love.system
local int,abs,rnd,max,min=math.floor,math.abs,math.random,math.max,math.min local Timer=love.timer.getTime
local find,format=string.find,string.format local int,rnd,max,min=math.floor,math.random,math.max,math.min
local ins,rem=table.insert,table.remove local rem=table.remove
local Timer=tm.getTime NULL=function()end
local F=false
null=function()end
------------------------------------------------------------- -------------------------------------------------------------
system=sys.getOS() system=sys.getOS()
local mobile=system=="Android"or system=="iOS"
local xOy=love.math.newTransform() local xOy=love.math.newTransform()
local mx,my,mouseShow=-20,-20,false local mx,my,mouseShow=-20,-20,false
local touching--1st touching ID local touching--1st touching ID
modeSel,levelSel=1,3--Initialize mode selection
players={alive={},human=0}
scr={x=0,y=0,w=gc.getWidth(),h=gc.getHeight(),k=1} scr={x=0,y=0,w=gc.getWidth(),h=gc.getHeight(),k=1}
local scr=scr local scr=scr
scene="" scene=""
@@ -55,25 +53,28 @@ freeRow={L=40}for i=1,40 do freeRow[i]={0,0,0,0,0,0,0,0,0,0}end
setting={ setting={
das=10,arr=2, das=10,arr=2,
sddas=0,sdarr=2, sddas=0,sdarr=2,
holdR=true, quickR=true,swap=true,
swap=true, fine=false,
--game --game
ghost=true,center=true, ghost=true,center=true,
smo=true,grid=false, smo=true,grid=false,
dropFX=3, dropFX=3,
shakeFX=3, shakeFX=3,
atkFX=3, atkFX=3,
frameMul=100, frameMul=100,
--
fullscreen=false, fullscreen=false,
bg=true, bg=true,
bgblock=true, bgblock=true,
lang=1, lang=1,
skin=1, skin=1,
--graphic --graphic
sfx=8,bgm=6, sfx=8,bgm=6,
vib=3,voc=0, vib=3,voc=0,
--sound --sound
keyMap={ keyMap={
{"left","right","x","z","c","up","down","space","tab","r","","",""}, {"left","right","x","z","c","up","down","space","tab","r","","",""},
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},
@@ -82,7 +83,7 @@ setting={
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},--keyboard
{"dpleft","dpright","a","b","y","dpup","dpdown","rightshoulder","x","leftshoulder","","",""}, {"dpleft","dpright","a","b","y","dpup","dpdown","rightshoulder","x","leftshoulder","","",""},
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},
@@ -90,18 +91,18 @@ setting={
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},
{"","","","","","","","","","","","",""}, {"","","","","","","","","","","","",""},--joystick
},--keyboard & joystick },
virtualkey={ virtualkey={
{80,720-80,6400,80},--moveLeft {80,720-80,6400,80}, --moveLeft
{240,720-80,6400,80},--moveRight {240,720-80,6400,80}, --moveRight
{1280-240,720-80,6400,80},--rotRight {1280-240,720-80,6400,80}, --rotRight
{1280-400,720-80,6400,80},--rotLeft {1280-400,720-80,6400,80}, --rotLeft
{1280-240,720-240,6400,80},--rotFlip {1280-240,720-240,6400,80}, --rotFlip
{1280-80,720-80,6400,80},--hardDrop {1280-80,720-80,6400,80}, --hardDrop
{1280-80,720-240,6400,80},--softDrop {1280-80,720-240,6400,80}, --softDrop
{1280-80,720-400,6400,80},--hold {1280-80,720-400,6400,80}, --hold
{80,80,6400,80},--restart {80,80,6400,80}, --restart
}, },
virtualkeyAlpha=3, virtualkeyAlpha=3,
virtualkeyIcon=true, virtualkeyIcon=true,
@@ -110,6 +111,7 @@ setting={
} }
stat={ stat={
run=0,game=0,time=0, run=0,game=0,time=0,
extraPiece=0,extraRate=0,
key=0,rotate=0,hold=0,piece=0,row=0, key=0,rotate=0,hold=0,piece=0,row=0,
atk=0,send=0,recv=0,pend=0, atk=0,send=0,recv=0,pend=0,
clear_1=0,clear_2=0,clear_3=0,clear_4=0, clear_1=0,clear_2=0,clear_3=0,clear_4=0,
@@ -134,19 +136,20 @@ virtualkey={
]] ]]
} }
virtualkeyDown={F,F,F,F,F,F,F,F,F,F,F,F,F} virtualkeyDown={X,X,X,X,X,X,X,X,X,X}
virtualkeyPressTime={0,0,0,0,0,0,0,0,0,0,0,0,0} virtualkeyPressTime={0,0,0,0,0,0,0,0,0,0,0,0,0}
--User datas&settings --User datas&settings
------------------------------------------------------------- -------------------------------------------------------------
require("class") require("class")
require("toolfunc")
require("ai") require("ai")
require("gamefunc") require("toolfunc")
require("list") require("list")
require("dataList") require("dataList")
require("texture") require("texture")
require("light")
local Tmr=require("timer") local Tmr=require("timer")
local Pnt=require("paint") local Pnt=require("paint")
require("player")
--Modules --Modules
------------------------------------------------------------- -------------------------------------------------------------
local powerInfoCanvas,updatePowerInfo local powerInfoCanvas,updatePowerInfo
@@ -167,7 +170,6 @@ if sys.getPowerInfo()~="unknown"then
gc.line(61.5,.5,83.5,22.5) gc.line(61.5,.5,83.5,22.5)
elseif state=="charging"or state=="charged"then elseif state=="charging"or state=="charged"then
gc.draw(chargeImage,84,3) gc.draw(chargeImage,84,3)
F=true
end end
end end
if pow then if pow then
@@ -213,7 +215,10 @@ local sceneInit={
updatePowerInfo() updatePowerInfo()
end, end,
main=function() main=function()
modeSel,levelSel=modeSel or 1,levelSel or 3 modeEnv={}
if not players[1]then
newDemoPlayer(1,900,35,1.1)
end--create demo player
collectgarbage() collectgarbage()
end, end,
music=function() music=function()
@@ -230,7 +235,6 @@ local sceneInit={
end, end,
mode=function() mode=function()
curBG="none" curBG="none"
saveData()
destroyPlayers() destroyPlayers()
BGM("blank") BGM("blank")
end, end,
@@ -255,36 +259,32 @@ local sceneInit={
end, end,
pause=function() pause=function()
end, end,
setting=function() setting_game=function()
curBG="none" curBG="none"
end, end,
setting_game=null,
setting_graphic=null,
setting_sound=null,
setting_control=function() setting_control=function()
curBoard=1 curBoard=1
keyboardSet=1 keyboardSet=1
joystickSet=1 joystickSet=1
keyboardSetting=false keyboardSetting=false
joystickSetting=false joystickSetting=false
end,--Control settings end,
setting_touch=function() setting_touch=function()
curBG="game1" curBG="game1"
defaultSel=1 defaultSel=1
sel=nil sel=nil
snapLevel=1 snapLevel=1
end,--Touch setting end,
help=function() help=function()
curBG="none" curBG="none"
end, end,
stat=function()
end,
history=function() history=function()
updateLog=require"updateLog" updateLog=require"updateLog"
curBG="lightGrey" curBG="lightGrey"
sel=1 sel=1
end, end,
quit=function() quit=function()
love.timer.sleep(.3)
love.event.quit() love.event.quit()
end, end,
} }
@@ -490,7 +490,7 @@ function keyDown.draw(key)
elseif key=="escape"then elseif key=="escape"then
back() back()
else else
pen=find("123qwea#sdzxc",key)or pen pen=string.find("123qwea#sdzxc",key)or pen
end end
end end
@@ -605,24 +605,19 @@ function keyDown.pause(key)
back() back()
elseif key=="return"or key=="space"then elseif key=="return"or key=="space"then
resumeGame() resumeGame()
else elseif key=="r"and kb.isDown("lctrl","rctrl")then
local m=setting.keyMap clearTask("play")
for p=1,human do updateStat()
if key==m[2*p-1][10]or key==m[2*p][10]then resetGameData()
clearTask("play") gotoScene("play","none")
updateStat() end--Restart with ctrl+R
resetGameData()
gotoScene("play","none")
end
end--Restart
end
end end
function touchDown.play(id,x,y) function touchDown.play(id,x,y)
if setting.virtualkeySwitch then if setting.virtualkeySwitch then
local t=onVirtualkey(x,y) local t=onVirtualkey(x,y)
if t then if t then
pressKey(t,players[1]) players[1]:pressKey(t)
VIB(0) VIB(0)
end end
end end
@@ -631,7 +626,7 @@ function touchUp.play(id,x,y)
if setting.virtualkeySwitch then if setting.virtualkeySwitch then
local t=onVirtualkey(x,y) local t=onVirtualkey(x,y)
if t then if t then
releaseKey(t,players[1]) players[1]:releaseKey(t)
end end
end end
end end
@@ -644,7 +639,7 @@ function touchMove.play(id,x,y,dx,dy)
local x,y=xOy:inverseTransformPoint(tc.getPosition(l[i])) local x,y=xOy:inverseTransformPoint(tc.getPosition(l[i]))
if(x-b[1])^2+(y-b[2])^2<=b[3]then goto L end if(x-b[1])^2+(y-b[2])^2<=b[3]then goto L end
end end
releaseKey(n,players[1]) players[1]:releaseKey(n)
::L:: ::L::
end end
end end
@@ -654,10 +649,10 @@ function keyDown.play(key)
return(frame<180 and back or pauseGame)() return(frame<180 and back or pauseGame)()
end end
local m=setting.keyMap local m=setting.keyMap
for p=1,human do for p=1,players.human do
for k=1,12 do for k=1,12 do
if key==m[2*p-1][k]or key==m[2*p][k]then if key==m[2*p-1][k]or key==m[2*p][k]then
pressKey(k,players[p]) players[p]:pressKey(k)
return return
end end
end end
@@ -665,10 +660,10 @@ function keyDown.play(key)
end end
function keyUp.play(key) function keyUp.play(key)
local m=setting.keyMap local m=setting.keyMap
for p=1,human do for p=1,players.human do
for k=1,12 do for k=1,12 do
if key==m[2*p-1][k]or key==m[2*p][k]then if key==m[2*p-1][k]or key==m[2*p][k]then
releaseKey(k,players[p]) players[p]:releaseKey(k)
return return
end end
end end
@@ -677,10 +672,10 @@ end
function gamepadDown.play(key) function gamepadDown.play(key)
if key=="back"then back()return end if key=="back"then back()return end
local m=setting.keyMap local m=setting.keyMap
for p=1,human do for p=1,players.human do
for k=1,12 do for k=1,12 do
if key==m[2*p+7][k]or key==m[2*p+8][k]then if key==m[2*p+7][k]or key==m[2*p+8][k]then
pressKey(k,players[p]) players[p]:pressKey(k)
return return
end end
end end
@@ -688,10 +683,10 @@ function gamepadDown.play(key)
end end
function gamepadUp.play(key) function gamepadUp.play(key)
local m=setting.keyMap local m=setting.keyMap
for p=1,human do for p=1,players.human do
for k=1,12 do for k=1,12 do
if key==m[2*p+7][k]or key==m[2*p+8][k]then if key==m[2*p+7][k]or key==m[2*p+8][k]then
releaseKey(k,players[p]) players[p]:releaseKey(k)
return return
end end
end end
@@ -712,7 +707,6 @@ function keyDown.history(key)
end end
------------------------------------------------------------- -------------------------------------------------------------
local function widgetPress(W,x,y) local function widgetPress(W,x,y)
if W.hide and W.hide()then widget_sel=nil end
if W.type=="button"then if W.type=="button"then
W.code() W.code()
W:FX() W:FX()
@@ -730,6 +724,7 @@ local function widgetPress(W,x,y)
W:FX(p) W:FX(p)
if W.change then W.change()end if W.change then W.change()end
end end
if W.hide and W.hide()then widget_sel=nil end
end end
local function widgetDrag(W,x,y,dx,dy) local function widgetDrag(W,x,y,dx,dy)
if W.type=="slider"then if W.type=="slider"then
@@ -738,7 +733,7 @@ local function widgetDrag(W,x,y,dx,dy)
if p==W.disp()then return end if p==W.disp()then return end
W:FX(p) W:FX(p)
if W.change then W.change()end if W.change then W.change()end
elseif not W:ifAbove(x,y)then elseif not W:isAbove(x,y)then
widget_sel=nil widget_sel=nil
end end
end end
@@ -757,11 +752,15 @@ local function widgetControl_key(i)
if widget_sel then if widget_sel then
local W=widget_sel local W=widget_sel
if W.type=="slider"then if W.type=="slider"then
local p=W.disp()
if i=="left"then if i=="left"then
if W.disp()>0 then W.code(W.disp()-1)end if W.disp()>0 then W.code(W.disp()-1)end
elseif i=="right"then elseif i=="right"then
if W.disp()<W.unit then W.code(W.disp()+1)end if W.disp()<W.unit then W.code(W.disp()+1)end
end end
if p==W.disp()then return end
W:FX(p)
if W.change then W.change()end
end end
end end
end end
@@ -793,7 +792,6 @@ local function widgetControl_gamepad(i)
end end
function love.mousepressed(x,y,k,t,num) function love.mousepressed(x,y,k,t,num)
if t then return end if t then return end
mouseShow=true
mx,my=xOy:inverseTransformPoint(x,y) mx,my=xOy:inverseTransformPoint(x,y)
if mouseDown[scene]then if mouseDown[scene]then
mouseDown[scene](mx,my,k) mouseDown[scene](mx,my,k)
@@ -805,10 +803,10 @@ function love.mousepressed(x,y,k,t,num)
widgetPress(widget_sel,mx,my) widgetPress(widget_sel,mx,my)
end end
end end
mouseShow=true
end end
function love.mousemoved(x,y,dx,dy,t) function love.mousemoved(x,y,dx,dy,t)
if t then return end if t then return end
mouseShow=true
mx,my=xOy:inverseTransformPoint(x,y) mx,my=xOy:inverseTransformPoint(x,y)
dx,dy=dx/scr.k,dy/scr.k dx,dy=dx/scr.k,dy/scr.k
if mouseMove[scene]then if mouseMove[scene]then
@@ -819,12 +817,13 @@ function love.mousemoved(x,y,dx,dy,t)
else else
widget_sel=nil widget_sel=nil
for _,W in next,Widget[scene]do for _,W in next,Widget[scene]do
if not(W.hide and W.hide())and W:ifAbove(mx,my)then if not(W.hide and W.hide())and W:isAbove(mx,my)then
widget_sel=W widget_sel=W
return return
end end
end end
end end
mouseShow=true
end end
function love.mousereleased(x,y,k,t,num) function love.mousereleased(x,y,k,t,num)
if t then return end if t then return end
@@ -857,7 +856,7 @@ function love.touchmoved(id,x,y,dx,dy)
else else
widget_sel=nil widget_sel=nil
for _,W in next,Widget[scene]do for _,W in next,Widget[scene]do
if not(W.hide and W.hide())and W:ifAbove(x,y)then if not(W.hide and W.hide())and W:isAbove(x,y)then
widget_sel=W widget_sel=W
return return
end end
@@ -882,9 +881,16 @@ function love.touchreleased(id,x,y)
end end
function love.keypressed(i) function love.keypressed(i)
mouseShow=false mouseShow=false
if i=="f8"then devMode=(devMode+1)%3 end if i=="f8"then devMode=0
if devMode==2 then elseif i=="f9"then devMode=1
elseif i=="f10"then devMode=2
elseif devMode==2 then
if i=="k"then if i=="k"then
for i=1,8 do
local P=players.alive[rnd(#players.alive)]
P.lastRecv=players[1]
Event.lose(P)
end
--Test code here --Test code here
elseif i=="q"then elseif i=="q"then
local W=widget_sel local W=widget_sel
@@ -956,7 +962,6 @@ function love.resize(w,h)
gc.origin() gc.origin()
xOy=xOy:setTransformation(w*.5,h*.5,nil,scr.k,nil,640,360) xOy=xOy:setTransformation(w*.5,h*.5,nil,scr.k,nil,640,360)
gc.replaceTransform(xOy) gc.replaceTransform(xOy)
collectgarbage()
end end
function love.focus(f) function love.focus(f)
if system~="Android" and not f and scene=="play"then pauseGame()end if system~="Android" and not f and scene=="play"then pauseGame()end
@@ -995,7 +1000,7 @@ function love.update(dt)
end end
widget_sel=nil widget_sel=nil
scene=sceneSwaping.tar scene=sceneSwaping.tar
sceneInit[scene]() if sceneInit[scene] then sceneInit[scene]()end
--scene swapped! --scene swapped!
elseif sceneSwaping.time==0 then elseif sceneSwaping.time==0 then
sceneSwaping=nil sceneSwaping=nil
@@ -1005,7 +1010,10 @@ function love.update(dt)
Tmr[scene](dt) Tmr[scene](dt)
end end
for i=#Task,1,-1 do for i=#Task,1,-1 do
Task[i]:update() local T=Task[i]
if(not T.P or T.P and scene=="play")and T.code(T.P,T.data)then
rem(Task,i)
end
end end
for i=1,#voiceQueue do for i=1,#voiceQueue do
local Q=voiceQueue[i] local Q=voiceQueue[i]
@@ -1015,19 +1023,18 @@ function love.update(dt)
for i=1,#Q do for i=1,#Q do
Q[i]=Q[i+1] Q[i]=Q[i+1]
end end
end--play next when stop end--放完后放下一个
else else
local n=1 local n=1
local L=voiceBank[Q[1]] local L=voiceBank[Q[1]]
::L::if L[n]:isPlaying()then while L[n]:isPlaying()do
n=n+1 n=n+1
if not L[n]then if not L[n]then
L[n]=L[n-1]:clone() L[n]=L[n-1]:clone()
L[n]:seek(0) L[n]:seek(0)
goto quit break
end end
goto L end
end::quit::
Q[1]=L[n] Q[1]=L[n]
Q[1]:setVolume(setting.voc*.125) Q[1]:setVolume(setting.voc*.125)
Q[1]:play() Q[1]:play()
@@ -1039,6 +1046,7 @@ function love.update(dt)
-- end--update Widgets -- end--update Widgets
end end
local scs={1,2,1,2,1,2,1,2,1,2,1.5,1.5,.5,2.5} local scs={1,2,1,2,1,2,1,2,1,2,1.5,1.5,.5,2.5}
local FPS=love.timer.getFPS
function love.draw() function love.draw()
gc.discard()--SPEED UPUPUP! gc.discard()--SPEED UPUPUP!
Pnt.BG[setting.bg and curBG or"grey"]() Pnt.BG[setting.bg and curBG or"grey"]()
@@ -1060,14 +1068,14 @@ function love.draw()
end--Draw widgets end--Draw widgets
if mouseShow and not touching then if mouseShow and not touching then
local r=Timer()*.5 local r=Timer()*.5
gc.setColor(1,1,1,min(1-abs(1-r%1*2),.3)) gc.setColor(1,1,1,min(1-math.abs(1-r%1*2),.3))
r=int(r)%7+1 r=int(r)%7+1
gc.draw(mouseBlock[r],mx,my,Timer()%3.1416*4,20,20,scs[2*r]-.5,#blocks[r][0]-scs[2*r-1]+.5) gc.draw(mouseBlock[r],mx,my,Timer()%3.1416*4,20,20,scs[2*r]-.5,#blocks[r][0]-scs[2*r-1]+.5)
gc.setColor(1,1,1,.5)gc.circle("fill",mx,my,5) gc.setColor(1,1,1,.5)gc.circle("fill",mx,my,5)
gc.setColor(1,1,1)gc.circle("fill",mx,my,3) gc.setColor(1,1,1)gc.circle("fill",mx,my,3)
end--Awesome mouse! end--Awesome mouse!
gc.setColor(1,1,1) gc.setColor(1,1,1)
if powerInfoCanvas and scene~="draw"then if powerInfoCanvas then
gc.draw(powerInfoCanvas) gc.draw(powerInfoCanvas)
end--Power Info end--Power Info
gc.setLineWidth(6) gc.setLineWidth(6)
@@ -1100,9 +1108,10 @@ function love.draw()
end--wide end--wide
end--Black side end--Black side
setFont(20) setFont(20)
gc.print(tm.getFPS(),5,700) gc.setColor(1,1,1)
gc.print(FPS(),5,700)
if devMode>0 then if devMode>0 then
gc.setColor(1,1,devMode==2 and 0 or 1) gc.setColor(1,devMode==2 and .5 or 1,1)
gc.print("Tasks:"..#Task,5,600) gc.print("Tasks:"..#Task,5,600)
gc.print("Voices:"..#voiceQueue,5,620) gc.print("Voices:"..#voiceQueue,5,620)
gc.print("Mouse:"..mx.." "..my,5,640) gc.print("Mouse:"..mx.." "..my,5,640)
@@ -1111,21 +1120,28 @@ function love.draw()
end end
end end
function love.run() function love.run()
local lastFrame,lastUpdatePowerInfo=Timer(),Timer()
local readyDrawFrame=0
local T=love.timer local T=love.timer
local lastFrame,lastUpdatePowerInfo=T.getTime(),T.getTime()
local readyDrawFrame=0
local mini=love.window.isMinimized
local PUMP,POLL=love.event.pump,love.event.poll local PUMP,POLL=love.event.pump,love.event.poll
love.resize(gc.getWidth(),gc.getHeight()) love.resize(gc.getWidth(),gc.getHeight())
scene="load"sceneInit.load()--System Launch scene="load"sceneInit.load()--System Launch
return function() return function()
PUMP() PUMP()
for N,a,b,c,d,e in POLL()do for N,a,b,c,d,e in POLL()do
if N=="quit"then destroyPlayers()return 0 if N=="quit"then
elseif love[N]then love[N](a,b,c,d,e)end destroyPlayers()
saveData()
saveSetting()
return 0
elseif love[N]then
love[N](a,b,c,d,e)
end
end end
T.step() T.step()
love.update(T.getDelta()) love.update(T.getDelta())
if not wd.isMinimized()then if not mini()then
readyDrawFrame=readyDrawFrame+setting.frameMul readyDrawFrame=readyDrawFrame+setting.frameMul
if readyDrawFrame>=100 then if readyDrawFrame>=100 then
readyDrawFrame=readyDrawFrame-100 readyDrawFrame=readyDrawFrame-100
@@ -1138,19 +1154,20 @@ function love.run()
updatePowerInfo() updatePowerInfo()
lastUpdatePowerInfo=Timer() lastUpdatePowerInfo=Timer()
end end
until Timer()-lastFrame>.0133 until Timer()-lastFrame>.013
T.sleep(.003) T.sleep(.002)
lastFrame=Timer() lastFrame=Timer()
end end
end end
local fs=love.filesystem
userData,userSetting=fs.newFile("userdata"),fs.newFile("usersetting") userData,userSetting=fs.newFile("userdata"),fs.newFile("usersetting")
if fs.getInfo("userdata")then if fs.getInfo("userdata")then
loadData() loadData()
end end
if fs.getInfo("usersetting")then if fs.getInfo("usersetting")then
loadSetting() loadSetting()
elseif mobile then elseif system=="Android"or system=="iOS" then
setting.virtualkeySwitch=true setting.virtualkeySwitch=true
setting.swap=false setting.swap=false
end end

470
paint.lua
View File

@@ -1,26 +1,10 @@
local gc=love.graphics local gc=love.graphics
local mt=love.math
local gmatch=string.gmatch
local setFont=setFont local setFont=setFont
local int,abs,rnd,max,min,sin=math.floor,math.abs,math.random,math.max,math.min,math.sin local int,abs,rnd,max,min,sin=math.floor,math.abs,math.random,math.max,math.min,math.sin
local format=string.format local format=string.format
local Timer=love.timer.getTime local Timer=love.timer.getTime
local scr=scr 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={ local modeLevelColor={
EASY=color.cyan, EASY=color.cyan,
NORMAL=color.green, NORMAL=color.green,
@@ -66,6 +50,8 @@ local function dataOpt(i)
return stat.pc return stat.pc
elseif i==14 then elseif i==14 then
return format("%0.2f",stat.atk/stat.row) return format("%0.2f",stat.atk/stat.row)
elseif i==15 then
return stat.extraPiece.."["..(int(stat.extraRate/stat.piece*10000)*.01).."%]"
end end
end end
local statOptL={ local statOptL={
@@ -88,6 +74,8 @@ local function statOpt(i)
return stat.pc return stat.pc
elseif i==17 then elseif i==17 then
return format("%0.2f",stat.atk/stat.row) return format("%0.2f",stat.atk/stat.row)
elseif i==18 then
return stat.extraPiece.."["..(int(stat.extraRate/stat.piece*10000)*.01).."%]"
end end
end end
local miniTitle_rect={ local miniTitle_rect={
@@ -102,7 +90,8 @@ local miniTitle_rect={
} }
local function stencil_miniTitle() local function stencil_miniTitle()
for i=1,#miniTitle_rect do 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
end end
@@ -179,17 +168,6 @@ textFX={
gc.pop() gc.pop()
end, 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 function drawAtkPointer(x,y)
local t=sin(Timer()*20) local t=sin(Timer()*20)
gc.setColor(.2,.7+t*.2,1,.6+t*.4) 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.setColor(0,.6,1,.8-a)
gc.circle("line",x,y,30*(1+a),6) gc.circle("line",x,y,30*(1+a),6)
end end
local function VirtualkeyPreview() local function VirtualkeyPreview()
for i=1,#virtualkey do for i=1,#virtualkey do
local c=sel==i and .8 or 1 local c=sel==i and .8 or 1
@@ -228,70 +205,77 @@ local function drawVirtualkey()
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 Pnt={BG={}}
local matrixT={}for i=0,15 do matrixT[i]={}for j=0,8 do matrixT[i][j]=mt.noise(i,j)+2 end end function Pnt.BG.none()
local Pnt={}
Pnt.BG={
none=function()
gc.clear(.15,.15,.15) gc.clear(.15,.15,.15)
end, end
grey=function() function Pnt.BG.grey()
gc.clear(.3,.3,.3) gc.clear(.3,.3,.3)
end, end
lightGrey=function() function Pnt.BG.lightGrey()
gc.clear(.5,.5,.5) gc.clear(.5,.5,.5)
end, end
glow=function() 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 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) gc.clear(t,t,t)
end, end
game1=function() 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.setColor(1,1,1)
gc.draw(background1,640,360,Timer()*.15,12,nil,64,64) gc.draw(background1,640,360,Timer()*.15,12,nil,64,64)
end,--Rainbow end--Rainbow
game2=function() function Pnt.BG.game2()
gc.setColor(1,.5,.5) gc.setColor(1,.5,.5)
gc.draw(background1,640,360,Timer()*.2,12,nil,64,64) gc.draw(background1,640,360,Timer()*.2,12,nil,64,64)
end,--Red rainbow end--Red rainbow
game3=function() function Pnt.BG.game3()
gc.setColor(.6,.6,1) gc.setColor(.6,.6,1)
gc.draw(background1,640,360,Timer()*.25,12,nil,64,64) gc.draw(background1,640,360,Timer()*.25,12,nil,64,64)
end,--Blue rainbow end--Blue rainbow
game4=function() function Pnt.BG.game4()
gc.setColor(.1,.5,.5) gc.setColor(.1,.5,.5)
local x=Timer()%4*320 local x=Timer()%4*320
gc.draw(background2,x,0,nil,10) gc.draw(background2,x,0,nil,10)
gc.draw(background2,x-1280,0,nil,10) gc.draw(background2,x-1280,0,nil,10)
end,--Fast strap end--Fast strap
game5=function() function Pnt.BG.game5()
local t=2.5-Timer()%20%6%2.5 local t=2.5-Timer()%20%6%2.5
if t<.5 then gc.clear(t,t,t) if t<.5 then gc.clear(t,t,t)
else gc.clear(0,0,0) else gc.clear(0,0,0)
end end
end,--Lightning end--Lightning
game6=function() 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 local t=1.2-Timer()%10%3%1.2
if t<.5 then gc.clear(t,t,t) if t<.5 then gc.clear(t,t,t)
else gc.clear(0,0,0) else gc.clear(0,0,0)
end end
gc.setColor(.3,.3,.3) gc.setColor(.3,.3,.3)
local r=7-int(Timer()*.5)%7 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) 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 end--Fast lightning&spining tetromino
rgb=function() 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
gc.clear( function Pnt.BG.matrix()
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.clear(.15,.15,.15) gc.clear(.15,.15,.15)
for i=0,15 do for i=0,15 do
for j=0,8 do for j=0,8 do
@@ -300,8 +284,7 @@ matrix=function()
gc.rectangle("fill",80*i,80*j,80,80) gc.rectangle("fill",80*i,80*j,80,80)
end end
end end
end, end
}
function Pnt.load() function Pnt.load()
gc.setLineWidth(4) gc.setLineWidth(4)
@@ -315,14 +298,14 @@ function Pnt.load()
mStr(loadTip,640,400) mStr(loadTip,640,400)
end end
function Pnt.intro() function Pnt.intro()
gc.push() gc.stencil(stencil_miniTitle,"replace",1)
gc.translate(250,150)
gc.scale(30)
gc.stencil(stencil_miniTitle,"replace",1)
gc.setStencilTest("equal",1) gc.setStencilTest("equal",1)
gc.setColor(1,1,1,min(count,80)*.005) gc.setColor(1,1,1,min(count,80)*.005)
gc.rectangle("fill",0,0,26,14) gc.push("transform")
gc.pop() gc.translate(250,150)
gc.scale(30)
gc.rectangle("fill",0,0,26,14)
gc.pop()
gc.setColor(1,1,1,.06) gc.setColor(1,1,1,.06)
for i=41,5,-2 do for i=41,5,-2 do
gc.setLineWidth(i) gc.setLineWidth(i)
@@ -332,13 +315,15 @@ function Pnt.intro()
end end
function Pnt.main() function Pnt.main()
gc.setColor(1,1,1) gc.setColor(1,1,1)
gc.draw(coloredTitleImage,280,30,nil,1.3) gc.draw(coloredTitleImage,60,30,nil,1.3)
gc.draw(drawableText.warning,570,128) gc.draw(drawableText.warning,595-drawableText.warning:getWidth(),128)
setFont(35) setFont(35)
gc.print(gameVersion,290,125) gc.print(gameVersion,70,125)
gc.print(system,840,95) gc.print(system,610,100)
mStr(modeLevel[modeID[modeSel]][levelSel],160,180) gc.print(modeLevel[modeID[modeSel]][levelSel],600,373)
mStr(text.modeName[modeSel],160,380) setFont(30)
gc.print(text.modeName[modeSel],600,414)
players[1]:demoDraw()
end end
function Pnt.mode() function Pnt.mode()
gc.setColor(1,1,1) gc.setColor(1,1,1)
@@ -415,7 +400,7 @@ function Pnt.draw()
for y=1,20 do for x=1,10 do for y=1,20 do for x=1,10 do
local B=preField[y][x] local B=preField[y][x]
if B>0 then if B>0 then
drawPixel(y,x,B) gc.draw(blockSkin[B],30*x-30,600-30*y)
elseif B==-1 then elseif B==-1 then
gc.line(30*x-25,605-30*y,30*x-5,625-30*y) 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) gc.line(30*x-25,625-30*y,30*x-5,605-30*y)
@@ -443,268 +428,8 @@ function Pnt.draw()
end end
function Pnt.play() function Pnt.play()
for p=1,#players do for p=1,#players do
P=players[p] players[p]:draw()
if P.small then end
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
gc.setLineWidth(5) gc.setLineWidth(5)
for i=1,#FX_attack do for i=1,#FX_attack do
local A=FX_attack[i] local A=FX_attack[i]
@@ -726,7 +451,7 @@ function Pnt.play()
gc.rotate(A.t*.1) gc.rotate(A.t*.1)
gc.circle("fill",0,0,A.rad,A.corner) gc.circle("fill",0,0,A.rad,A.corner)
gc.pop() gc.pop()
end end--FX animation
gc.setColor(1,1,1) gc.setColor(1,1,1)
if setting.virtualkeySwitch then drawVirtualkey()end if setting.virtualkeySwitch then drawVirtualkey()end
if modeEnv.royaleMode then if modeEnv.royaleMode then
@@ -742,25 +467,23 @@ function Pnt.play()
gc.draw(badgeIcon,b[3]-14,b[4]-14) gc.draw(badgeIcon,b[3]-14,b[4]-14)
end end
end end
P=players[1] local P=players[1]
gc.setLineWidth(5) gc.setLineWidth(5)
gc.setColor(.8,1,0,.2) gc.setColor(.8,1,0,.2)
for i=1,#players[1].atker do for i=1,#P.atker do
local p=players[1].atker[i] local p=P.atker[i]
gc.line(p.centerX,p.centerY,P.centerX,P.centerY) gc.line(p.centerX,p.centerY,P.centerX,P.centerY)
end end
if P.atkMode~=4 then if P.atkMode~=4 then
if P.atking then drawAtkPointer(P.atking.centerX,P.atking.centerY)end if P.atking then drawAtkPointer(P.atking.centerX,P.atking.centerY)end
else else
for i=1,#players[1].atker do for i=1,#P.atker do
local p=players[1].atker[i] local p=P.atker[i]
drawAtkPointer(p.centerX,p.centerY) drawAtkPointer(p.centerX,p.centerY)
end end
end end
end end
if restartCount>0 then 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.setColor(0,0,0,restartCount/20)
gc.rectangle("fill",0,0,1280,720) gc.rectangle("fill",0,0,1280,720)
end end
@@ -774,33 +497,40 @@ function Pnt.pause()
if pauseCount>0 then if pauseCount>0 then
gc.print(text.pauseCount..":["..pauseCount.."] "..format("%0.2f",pauseTime).."s",110,150) gc.print(text.pauseCount..":["..pauseCount.."] "..format("%0.2f",pauseTime).."s",110,150)
end end
for i=1,7 do for i=1,8 do
gc.print(text.stat[i+3],110,30*i+270) gc.print(text.stat[i+3],110,30*i+270)
gc.print(dataOpt(i),305,30*i+270) gc.print(dataOpt(i),305,30*i+270)
end end
for i=8,14 do for i=9,15 do
gc.print(text.stat[i+3],860,30*i+60) gc.print(text.stat[i+3],860,30*i+30)
gc.print(dataOpt(i),1000,30*i+60) gc.print(dataOpt(i),1000,30*i+30)
end end
setFont(40) setFont(40)
if system~="Android"then 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) gc.print("ESC",610,506)
end end
mDraw(gamefinished and drawableText.finish or drawableText.pause,640,60-10*(5-pauseTimer*.1)^1.5) mDraw(gamefinished and drawableText.finish or drawableText.pause,640,60-10*(5-pauseTimer*.1)^1.5)
end end
function Pnt.setting_game() function Pnt.setting_game()
gc.setColor(1,1,1) gc.setColor(1,1,1)
mDraw(drawableText.setting_game,640,15)
setFont(40) setFont(40)
mStr("DAS:"..setting.das,260,95) mStr("DAS:"..setting.das,290,205)
mStr("ARR:"..setting.arr,560,95) mStr("ARR:"..setting.arr,610,205)
setFont(28) setFont(28)
mStr(text.softdropdas..setting.sddas,260,213) mStr(text.softdropdas..setting.sddas,290,323)
mStr(text.softdroparr..setting.sdarr,560,213) mStr(text.softdroparr..setting.sdarr,610,323)
end end
function Pnt.setting_graphic() function Pnt.setting_graphic()
gc.setColor(1,1,1) 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_sound()
gc.setColor(1,1,1)
mDraw(drawableText.setting_sound,640,15)
end end
function Pnt.setting_control() function Pnt.setting_control()
local a=.3+sin(Timer()*15)*.1 local a=.3+sin(Timer()*15)*.1
@@ -832,7 +562,7 @@ function Pnt.setting_control()
gc.line(40,550,640,550) gc.line(40,550,640,550)
mDraw(drawableText.keyboard,340,0) mDraw(drawableText.keyboard,340,0)
mDraw(drawableText.joystick,540,0) mDraw(drawableText.joystick,540,0)
gc.draw(drawableText.setting2Help,50,620) gc.draw(drawableText.ctrlSetHelp,50,620)
setFont(40) setFont(40)
gc.print("P"..int(curBoard*.5+.5).."/P4",420,560) gc.print("P"..int(curBoard*.5+.5).."/P4",420,560)
gc.print(curBoard.."/8",580,560) gc.print(curBoard.."/8",580,560)
@@ -852,12 +582,14 @@ function Pnt.setting_touch()
end end
end end
function Pnt.help() function Pnt.help()
setFont(32) setFont(30)
gc.setColor(1,1,1) gc.setColor(1,1,1)
for i=1,11 do for i=1,#text.help do
gc.printf(text.help[i],140,15+43*i,1000,"center") gc.printf(text.help[i],140,10+40*i,1000,"center")
end 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.setLineWidth(5)
gc.rectangle("line",17,17,260,260) gc.rectangle("line",17,17,260,260)
gc.rectangle("line",1077,17,186,186) gc.rectangle("line",1077,17,186,186)
@@ -872,7 +604,7 @@ end
function Pnt.stat() function Pnt.stat()
setFont(28) setFont(28)
gc.setColor(1,1,1) 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(text.stat[i],400,30*i-5)
gc.print(statOpt(i),720,30*i-5) gc.print(statOpt(i),720,30*i-5)
end end

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

@@ -66,8 +66,9 @@ drawableText={
next=T(40),hold=T(40), next=T(40),hold=T(40),
pause=T(120),finish=T(120), pause=T(120),finish=T(120),
custom=T(80), custom=T(80),
setting_game=T(80),setting_graphic=T(80),setting_sound=T(80),
keyboard=T(25),joystick=T(25), keyboard=T(25),joystick=T(25),
setting2Help=T(25), ctrlSetHelp=T(25),
musicRoom=T(80), musicRoom=T(80),
nowPlaying=T(50), nowPlaying=T(50),
warning=T(30), warning=T(30),

248
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 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 local ins,rem=table.insert,table.remove
return{ local Tmr={}
load=function() function Tmr.load()
local t=Timer() local t=Timer()
::R:: ::R::
if loading==1 then if loading==1 then
@@ -41,23 +41,27 @@ load=function()
for i=1,#sfx do sfx[i]=nil end for i=1,#sfx do sfx[i]=nil end
loading=4 loading=4
loadnum=1 loadnum=1
SFX("welcome",.2)
end end
elseif loading==4 then elseif loading==4 then
loadnum=loadnum+1 loadnum=loadnum+1
if loadnum==15 then if loadnum==48 then
stat.run=stat.run+1 stat.run=stat.run+1
gotoScene("intro","none") gotoScene("intro","none")
end end
end end
end, end
intro=function() function Tmr.intro()
count=count+1 count=count+1
if count==200 then count=80 end if count==200 then count=80 end
end, end
draw=function() function Tmr.main(dt)
players[1]:update(dt)
end
function Tmr.draw()
if clearSureTime>0 then clearSureTime=clearSureTime-1 end if clearSureTime>0 then clearSureTime=clearSureTime-1 end
end, end
play=function(dt) function Tmr.play(dt)
frame=frame+1 frame=frame+1
stat.time=stat.time+dt stat.time=stat.time+dt
for i=#FX_attack,1,-1 do for i=#FX_attack,1,-1 do
@@ -72,7 +76,7 @@ play=function(dt)
end end
if b.t<60 then if b.t<60 then
local L=FX_attack[i].drag local L=FX_attack[i].drag
if #L==10 then if #L==6*setting.atkFX then
rem(L,1)rem(L,1) rem(L,1)rem(L,1)
end end
ins(L,b.x)ins(L,b.y) ins(L,b.x)ins(L,b.y)
@@ -103,7 +107,7 @@ play=function(dt)
SFX("ready") SFX("ready")
end end
for p=1,#players do for p=1,#players do
P=players[p] local P=players[p]
if P.keyPressing[1]then if P.keyPressing[1]then
if P.moving>0 then P.moving=0 end if P.moving>0 then P.moving=0 end
P.moving=P.moving-1 P.moving=P.moving-1
@@ -128,227 +132,17 @@ play=function(dt)
restartCount=max(restartCount-2,0) restartCount=max(restartCount-2,0)
end--Counting,include pre-das,directy RETURN,or restart counting end--Counting,include pre-das,directy RETURN,or restart counting
for p=1,#players do for p=1,#players do
P=players[p] local P=players[p]
if P.timing then P.stat.time=P.stat.time+dt end P:update(dt)
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
end end
if modeEnv.royaleMode and frame%120==0 then freshMostDangerous()end if modeEnv.royaleMode and frame%120==0 then freshMostDangerous()end
end, end
pause=function(dt) function Tmr.pause(dt)
if not gamefinished then if not gamefinished then
pauseTime=pauseTime+dt pauseTime=pauseTime+dt
end end
if pauseTimer<50 and not wd.isMinimized()then if pauseTimer<50 and not wd.isMinimized()then
pauseTimer=pauseTimer+1 pauseTimer=pauseTimer+1
end end
end, end
} return Tmr

View File

@@ -25,20 +25,26 @@ function mDraw(s,x,y)
gc.draw(s,x-s:getWidth()*.5,y) gc.draw(s,x-s:getWidth()*.5,y)
end end
function destroyPlayers() function destroyPlayers()
if players then for i=#players,1,-1 do
for _,P in next,players do if P.id then local P=players[i]
while P.field[1]do if P.canvas then P.canvas:release()end
removeRow(P.field) while P.field[1]do
removeRow(P.visTime) removeRow(P.field)
end removeRow(P.visTime)
if P.AI_mode=="CC"then end
BOT.free(P.bot_opt) if P.AI_mode=="CC"then
BOT.free(P.bot_wei) BOT.free(P.bot_opt)
BOT.destroy(P.AI_bot) BOT.free(P.bot_wei)
P.AI_mode=nil BOT.destroy(P.AI_bot)
end P.AI_mode=nil
end end end
players[i]=nil
end end
for i=#players.alive,1,-1 do
players.alive[i]=nil
end
players.human=0
collectgarbage()
end end
function getNewRow(val) function getNewRow(val)
local t=rem(freeRow) local t=rem(freeRow)
@@ -64,14 +70,12 @@ end
langName={"中文","全中文","English"} langName={"中文","全中文","English"}
local langID={"chi","chi_full","eng"} local langID={"chi","chi_full","eng"}
local drawableTextLoad={ local drawableTextLoad={
"next", "next","hold",
"hold", "pause","finish",
"pause",
"finish",
"custom", "custom",
"keyboard", "setting_game","setting_graphic","setting_sound",
"joystick", "keyboard","joystick",
"setting2Help", "ctrlSetHelp",
"musicRoom", "musicRoom",
"nowPlaying", "nowPlaying",
"warning", "warning",
@@ -125,15 +129,14 @@ end
function SFX(s,v) function SFX(s,v)
if setting.sfx>0 then if setting.sfx>0 then
local n=1 local n=1
::L::if sfx[s][n]:isPlaying()then while sfx[s][n]:isPlaying()do
n=n+1 n=n+1
if not sfx[s][n]then if not sfx[s][n]then
sfx[s][n]=sfx[s][n-1]:clone() sfx[s][n]=sfx[s][n-1]:clone()
sfx[s][n]:seek(0) sfx[s][n]:seek(0)
goto quit break
end end
goto L end
end::quit::
sfx[s][n]:setVolume((v or 1)*setting.sfx*.125) sfx[s][n]:setVolume((v or 1)*setting.sfx*.125)
sfx[s][n]:play() sfx[s][n]:play()
end end
@@ -152,9 +155,8 @@ function VOICE(s,chn)
voiceQueue[chn][#voiceQueue[chn]+1]=voiceList[s][rnd(#voiceList[s])] voiceQueue[chn][#voiceQueue[chn]+1]=voiceList[s][rnd(#voiceList[s])]
--添加到[chn] --添加到[chn]
else else
local P=#voiceQueue voiceQueue[getFreeVoiceChannel()]={voiceList[s][rnd(#voiceList[s])]}
voiceQueue[P+1]={voiceList[s][rnd(#voiceList[s])]} --自动查找/创建空轨
--新建[chn]
end end
end end
end end
@@ -204,7 +206,7 @@ local swapDeck_data={
{7,0,8,9},{1,0,2,8},{5,2,4,8},{6,0,15,8}, {7,0,8,9},{1,0,2,8},{5,2,4,8},{6,0,15,8},
}--Block id [ZSLJTOI] ,dir,x,y }--Block id [ZSLJTOI] ,dir,x,y
local swap={ local swap={
none={2,1,d=function()end}, none={2,1,d=NULL},
flash={8,1,d=function()gc.clear(1,1,1)end}, flash={8,1,d=function()gc.clear(1,1,1)end},
fade={30,15,d=function() fade={30,15,d=function()
local t=1-abs(sceneSwaping.time*.06667-1) local t=1-abs(sceneSwaping.time*.06667-1)
@@ -248,8 +250,9 @@ function gotoScene(s,style)
end end
end end
function updateStat() function updateStat()
for k,v in next,players[1].stat do local S=players[1].stat
stat[k]=stat[k]+v for k,v in next,S do
stat[k]=stat[k]+S[k]
end end
end end
local prevMenu={ local prevMenu={
@@ -259,29 +262,27 @@ local prevMenu={
music="main", music="main",
mode="main", mode="main",
custom="mode", custom="mode",
draw=function() draw="custom",
gotoScene("custom")
end,
play=function() play=function()
kb.setKeyRepeat(true) kb.setKeyRepeat(true)
updateStat() updateStat()
saveData()
clearTask("play") clearTask("play")
gotoScene(curMode.id~="custom"and"mode"or"custom","deck") gotoScene(curMode.id~="custom"and"mode"or"custom","deck")
end, end,
pause=nil, setting_game=function()
setting=function()
saveSetting() saveSetting()
gotoScene("main") gotoScene("main")
end, end,
setting_game= "setting", setting_control="setting_game",
setting_graphic="setting", setting_touch= "setting_game",
setting_sound= "setting",
setting_control="setting",
setting_touch= "setting",
help="main", help="main",
history="help", history="help",
stat="main", stat="main",
}prevMenu.pause=prevMenu.play }
prevMenu.pause=prevMenu.play
prevMenu.setting_graphic=prevMenu.setting_game
prevMenu.setting_sound=prevMenu.setting_game
function back() function back()
local t=prevMenu[scene] local t=prevMenu[scene]
if type(t)=="string"then if type(t)=="string"then
@@ -290,6 +291,82 @@ function back()
t() t()
end end
end end
function randomTarget(P)
if #players.alive>1 then
local R
repeat
R=players.alive[rnd(#players.alive)]
until R~=P
return R
end
end--return a random opponent for P
function freshMostDangerous()
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() function pauseGame()
pauseTimer=0--Pause timer for animation pauseTimer=0--Pause timer for animation
if not gamefinished then if not gamefinished then
@@ -299,7 +376,7 @@ function pauseGame()
local l=players.alive[i].keyPressing local l=players.alive[i].keyPressing
for j=1,#l do for j=1,#l do
if l[j]then if l[j]then
releaseKey(j,players.alive[i]) players.alive[i]:releaseKey(j)
end end
end end
end end
@@ -308,8 +385,97 @@ end
function resumeGame() function resumeGame()
gotoScene("play","fade") gotoScene("play","fade")
end 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={ local dataOpt={
"run","game","time", "run","game","time",
"extraPiece","extraRate",
"key","rotate","hold","piece","row", "key","rotate","hold","piece","row",
"atk","send","recv","pend", "atk","send","recv","pend",
"clear_1","clear_2","clear_3","clear_4", "clear_1","clear_2","clear_3","clear_4",
@@ -345,7 +511,6 @@ function saveData()
t[i]=dataOpt[i].."="..toS(stat[dataOpt[i]]) t[i]=dataOpt[i].."="..toS(stat[dataOpt[i]])
end end
t=concat(t,"\r\n") t=concat(t,"\r\n")
t=love.data.compress("string","zlib",t)
userData:open("w") userData:open("w")
userData:write(t) userData:write(t)
userData:close() userData:close()
@@ -369,6 +534,25 @@ function loadSetting()
elseif t=="fullscreen"then elseif t=="fullscreen"then
setting.fullscreen=v=="true" setting.fullscreen=v=="true"
love.window.setFullscreen(setting.fullscreen) 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 elseif t=="keymap"then
v=splitS(v,"/") v=splitS(v,"/")
for i=1,16 do for i=1,16 do
@@ -387,23 +571,6 @@ function loadSetting()
end end
end 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
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("[123456]"))or 1
end end
end end
end end
@@ -411,8 +578,9 @@ end
local saveOpt={ local saveOpt={
"das","arr", "das","arr",
"sddas","sdarr", "sddas","sdarr",
"holdR", "quickR",
"swap", "swap",
"fine",
"ghost","center", "ghost","center",
"smo","grid", "smo","grid",
@@ -455,7 +623,6 @@ function saveSetting()
--not always i+2! --not always i+2!
end end
t=concat(t,"\r\n") t=concat(t,"\r\n")
t=love.data.compress("string","zlib",t)
userSetting:open("w") userSetting:open("w")
userSetting:write(t) userSetting:write(t)
userSetting:close() userSetting:close()

View File

@@ -1,25 +1,44 @@
local S=[=[ local S=[=[
Patron(rmb10+):
gggf/T080/Ykzl/zxc
[D*a]?
Future outlook: Future outlook:
GUI: Normal Things:
ajustable next count
bag line in all mode
force fineese mode
highscore of most modes highscore of most modes
custom block color/direction custom block color/direction
custom sequence custom sequence
virtual key switch(all keys) virtual key switch(all keys)
Normal Things:
new cooler attack FX
combo mode combo mode
demo play at main menu infinite c4w mode
any screen size any screen size
CC smarter(think of gaebage buffer) CC smarter(think of gaebage buffer)
fineese/bigbang mode & easier CTWC fineese/bigbang mode & easier CTWC
new AI:task-Z new AI:task-Z
game recording game recording
TTT mode TTT mode
Hard Things: Technical things:
Encrypt source code(JIT to byte code) Encrypt source code(compile to byte code)
infinite 1v1 infinite 1v1
square mode square mode
more FXs & 3d features & animations 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): 0.7.24(0.7.23):
REMAKE ALL BGM! REMAKE ALL BGM!
more settings with brand new GUI! more settings with brand new GUI!