commit 6a80cdc4b996c19e697f2c4a4ef07991e556cacc Author: MrZ_26 Date: Tue Feb 4 19:22:39 2020 +0800 0.190718α diff --git a/BGM/32000Hz 86kbps b/BGM/32000Hz 86kbps new file mode 100644 index 00000000..e69de29b diff --git a/BGM/blank.ogg b/BGM/blank.ogg new file mode 100644 index 00000000..4679cc90 Binary files /dev/null and b/BGM/blank.ogg differ diff --git a/BGM/push.ogg b/BGM/push.ogg new file mode 100644 index 00000000..498429ce Binary files /dev/null and b/BGM/push.ogg differ diff --git a/BGM/race.ogg b/BGM/race.ogg new file mode 100644 index 00000000..e046c763 Binary files /dev/null and b/BGM/race.ogg differ diff --git a/BGM/reason.ogg b/BGM/reason.ogg new file mode 100644 index 00000000..3abac919 Binary files /dev/null and b/BGM/reason.ogg differ diff --git a/BGM/way.ogg b/BGM/way.ogg new file mode 100644 index 00000000..439928d0 Binary files /dev/null and b/BGM/way.ogg differ diff --git a/SFX/button.ogg b/SFX/button.ogg new file mode 100644 index 00000000..443b5c7c Binary files /dev/null and b/SFX/button.ogg differ diff --git a/SFX/clear_1.ogg b/SFX/clear_1.ogg new file mode 100644 index 00000000..6de90963 Binary files /dev/null and b/SFX/clear_1.ogg differ diff --git a/SFX/clear_2.ogg b/SFX/clear_2.ogg new file mode 100644 index 00000000..a9f6c24e Binary files /dev/null and b/SFX/clear_2.ogg differ diff --git a/SFX/clear_3.ogg b/SFX/clear_3.ogg new file mode 100644 index 00000000..4b5a9ff6 Binary files /dev/null and b/SFX/clear_3.ogg differ diff --git a/SFX/clear_4.ogg b/SFX/clear_4.ogg new file mode 100644 index 00000000..0ccda139 Binary files /dev/null and b/SFX/clear_4.ogg differ diff --git a/SFX/drop.ogg b/SFX/drop.ogg new file mode 100644 index 00000000..a6fea30b Binary files /dev/null and b/SFX/drop.ogg differ diff --git a/SFX/fall.ogg b/SFX/fall.ogg new file mode 100644 index 00000000..b050d74c Binary files /dev/null and b/SFX/fall.ogg differ diff --git a/SFX/hold.ogg b/SFX/hold.ogg new file mode 100644 index 00000000..8b90739a Binary files /dev/null and b/SFX/hold.ogg differ diff --git a/SFX/move.ogg b/SFX/move.ogg new file mode 100644 index 00000000..ba5d57cc Binary files /dev/null and b/SFX/move.ogg differ diff --git a/SFX/perfectclear.ogg b/SFX/perfectclear.ogg new file mode 100644 index 00000000..feaf53a0 Binary files /dev/null and b/SFX/perfectclear.ogg differ diff --git a/SFX/prehold.ogg b/SFX/prehold.ogg new file mode 100644 index 00000000..079aacff Binary files /dev/null and b/SFX/prehold.ogg differ diff --git a/SFX/prerotate.ogg b/SFX/prerotate.ogg new file mode 100644 index 00000000..26a85d1e Binary files /dev/null and b/SFX/prerotate.ogg differ diff --git a/SFX/reach.ogg b/SFX/reach.ogg new file mode 100644 index 00000000..9cdd270d Binary files /dev/null and b/SFX/reach.ogg differ diff --git a/SFX/ready.ogg b/SFX/ready.ogg new file mode 100644 index 00000000..f5674df7 Binary files /dev/null and b/SFX/ready.ogg differ diff --git a/SFX/ren_1.ogg b/SFX/ren_1.ogg new file mode 100644 index 00000000..56d3b840 Binary files /dev/null and b/SFX/ren_1.ogg differ diff --git a/SFX/ren_10.ogg b/SFX/ren_10.ogg new file mode 100644 index 00000000..87a77a99 Binary files /dev/null and b/SFX/ren_10.ogg differ diff --git a/SFX/ren_11.ogg b/SFX/ren_11.ogg new file mode 100644 index 00000000..6a23013a Binary files /dev/null and b/SFX/ren_11.ogg differ diff --git a/SFX/ren_2.ogg b/SFX/ren_2.ogg new file mode 100644 index 00000000..622b49c2 Binary files /dev/null and b/SFX/ren_2.ogg differ diff --git a/SFX/ren_3.ogg b/SFX/ren_3.ogg new file mode 100644 index 00000000..bfe8260b Binary files /dev/null and b/SFX/ren_3.ogg differ diff --git a/SFX/ren_4.ogg b/SFX/ren_4.ogg new file mode 100644 index 00000000..22201954 Binary files /dev/null and b/SFX/ren_4.ogg differ diff --git a/SFX/ren_5.ogg b/SFX/ren_5.ogg new file mode 100644 index 00000000..76c8235d Binary files /dev/null and b/SFX/ren_5.ogg differ diff --git a/SFX/ren_6.ogg b/SFX/ren_6.ogg new file mode 100644 index 00000000..4b1b6dfb Binary files /dev/null and b/SFX/ren_6.ogg differ diff --git a/SFX/ren_7.ogg b/SFX/ren_7.ogg new file mode 100644 index 00000000..789cc3cb Binary files /dev/null and b/SFX/ren_7.ogg differ diff --git a/SFX/ren_8.ogg b/SFX/ren_8.ogg new file mode 100644 index 00000000..6bd290bd Binary files /dev/null and b/SFX/ren_8.ogg differ diff --git a/SFX/ren_9.ogg b/SFX/ren_9.ogg new file mode 100644 index 00000000..0cc721c8 Binary files /dev/null and b/SFX/ren_9.ogg differ diff --git a/SFX/rotate.ogg b/SFX/rotate.ogg new file mode 100644 index 00000000..cdd1fc63 Binary files /dev/null and b/SFX/rotate.ogg differ diff --git a/SFX/rotatekick.ogg b/SFX/rotatekick.ogg new file mode 100644 index 00000000..7a69f010 Binary files /dev/null and b/SFX/rotatekick.ogg differ diff --git a/SFX/spin.ogg b/SFX/spin.ogg new file mode 100644 index 00000000..dce9ced5 Binary files /dev/null and b/SFX/spin.ogg differ diff --git a/SFX/spin_0.ogg b/SFX/spin_0.ogg new file mode 100644 index 00000000..23da7cdd Binary files /dev/null and b/SFX/spin_0.ogg differ diff --git a/SFX/spin_1.ogg b/SFX/spin_1.ogg new file mode 100644 index 00000000..a1aa8bb2 Binary files /dev/null and b/SFX/spin_1.ogg differ diff --git a/SFX/spin_2.ogg b/SFX/spin_2.ogg new file mode 100644 index 00000000..e0c3188c Binary files /dev/null and b/SFX/spin_2.ogg differ diff --git a/SFX/spin_3.ogg b/SFX/spin_3.ogg new file mode 100644 index 00000000..8007bdde Binary files /dev/null and b/SFX/spin_3.ogg differ diff --git a/SFX/start.ogg b/SFX/start.ogg new file mode 100644 index 00000000..cd774145 Binary files /dev/null and b/SFX/start.ogg differ diff --git a/SRS.lua b/SRS.lua new file mode 100644 index 00000000..abb9741d --- /dev/null +++ b/SRS.lua @@ -0,0 +1,75 @@ +blocks={ + {[0]={{0,1,1},{1,1,0}},{{1,0},{1,1},{0,1}},{{0,1,1},{1,1,0}},{{1,0},{1,1},{0,1}}},--Z + {[0]={{1,1,0},{0,1,1}},{{0,1},{1,1},{1,0}},{{1,1,0},{0,1,1}},{{0,1},{1,1},{1,0}}},--S + {[0]={{1,1,1},{0,0,1}},{{1,1},{1,0},{1,0}},{{1,0,0},{1,1,1}},{{0,1},{0,1},{1,1}}},--L + {[0]={{1,1,1},{1,0,0}},{{1,0},{1,0},{1,1}},{{0,0,1},{1,1,1}},{{1,1},{0,1},{0,1}}},--J + {[0]={{1,1,1},{0,1,0}},{{1,0},{1,1},{1,0}},{{0,1,0},{1,1,1}},{{0,1},{1,1},{0,1}}},--T + {[0]={{1,1},{1,1}},{{1,1},{1,1}},{{1,1},{1,1}},{{1,1},{1,1}}},--O + {[0]={{1,1,1,1}},{{1},{1},{1},{1}},{{1,1,1,1}},{{1},{1},{1},{1}}},--I +} +do--SRS data + local K={0,0} + local D,E,L,S,R,Q,J,C={0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1} + local B,I,P,F,M,T={-2,1},{-2,0},{-2,-1},{2,1},{2,0},{2,-1} + local X,Y,Z={-1,-2},{0,-2},{1,-2} + local F,G,N={-1,2},{0,2},{1,2} + scs={N,N,N,N,N,{1.5,1.5},{.5,2.5}} + SRS={ + [1]={ + [01]={K,J,C,Y,X,D}, + [10]={K,L,S,G,N,R}, + [12]={K,L,S,G,N}, + [21]={K,J,C,Y,X}, + [23]={K,L,E,Y,Z}, + [32]={K,J,Q,G,F}, + [30]={K,J,Q,G,F}, + [03]={K,L,E,Y,Z}, + [02]={K,L,J,R,D}, + [20]={K,J,L,D,R}, + [13]={K,D,R,J,L,G}, + [31]={K,R,D,L,J,G}, + }, + [2]={ + [01]={K,J,C,Y,X}, + [10]={K,L,S,G,N}, + [12]={K,L,S,G,N}, + [21]={K,J,C,Y,X}, + [23]={K,L,E,Y,Z}, + [32]={K,J,Q,G,F}, + [30]={K,J,Q,G,F,R}, + [03]={K,L,E,Y,Z,D}, + [02]={K,J,L,R,D}, + [20]={K,L,J,D,R}, + [13]={K,R,D,L,J,G}, + [31]={K,D,R,J,L,G}, + }, + [5]={ + [01]={K,J,C,Y,X}, + [10]={K,L,S,G,N}, + [12]={K,L,S,G,N}, + [21]={K,J,C,Y,X}, + [23]={K,L,E,Y,Z}, + [32]={K,J,Q,G,F}, + [30]={K,J,Q,G,F,R}, + [03]={K,L,E,Y,Z,D}, + [02]={K,J,L,R,D}, + [20]={K,L,J,D,R}, + [13]={K,R,D,L,J,G}, + [31]={K,R,D,J,L,G}, + }, + [7]={ + [01]={K,I,L,P,N}, + [10]={K,M,J,F,X}, + [12]={K,J,M,F,T}, + [21]={K,L,I,Z,B}, + [23]={K,M,J,F,X}, + [32]={K,I,L,P,N}, + [30]={K,L,I,Z,B}, + [03]={K,J,M,F,T}, + [02]={K,J,L,D}, + [20]={K,L,J,R}, + [13]={K,L}, + [31]={K,J}, + } +}SRS[3],SRS[4],SRS[6]=SRS[2],SRS[1],SRS[1] +end \ No newline at end of file diff --git a/ai.lua b/ai.lua new file mode 100644 index 00000000..b5186bc0 --- /dev/null +++ b/ai.lua @@ -0,0 +1,137 @@ +--[[ +HighestBlock +HorizontalTransitions +VerticalTransitions +BlockedCells +Wells +FilledLines +TetrisShape +BlockedWells; +]] +spinNeed={2,2,4,4,4,1,2} +spinOffset={ + {1,0,0},--S + {1,0,0},--Z + {1,0,0},--L + {1,0,0},--J + {1,0,0},--T + {0,0,0},--O + {2,0,1},--I +}for i=1,7 do spinOffset[i][0]=0 end +function ifoverlapAI(field,bk,x,y) + if x<1 or x+#bk[1]>11 or y<1 then return true end + if y>#field then return nil end + for i=1,#bk do for j=1,#bk[1]do + if field[y+i-1]and bk[i][j]>0 and field[y+i-1][x+j-1]>0 then return true end + end end +end +function resetField(f0,start) + while field[start]do + rem(field,start) + end + for i=start,#f0 do + field[i]={} + for j=1,10 do + field[i][j]=f0[i][j] + end + end +end +function getScore(field,cb,cx,cy) + local highest=0 + local height={} + local rough=0 + local clear=0 + local hole=0 + + for i=cy+#cb-1,cy,-1 do + local f=true + for j=1,10 do + if field[i][j]==0 then f=false;break end + end + if f then + rem(field,i) + clear=clear+1 + end + end + if #field==0 then return 9e99 end--PC best + for x=1,10 do + local h=#field + while field[h][x]==0 and h>1 do + h=h-1 + end + height[x]=h + if x>3 and x<8 and h>highest then highest=h end + if h>1 then + for h=h-1,1,-1 do + if field[h][x]==0 then hole=hole+1 end + end + end + end + for x=1,9 do + local dh=abs(height[x]-height[x]) + if dh>1 then + rough=rough+dh^1.5 + end + end + return + -highest*10 + -rough*10 + -cy*15 + +clear^1.5*15 + -hole*20 +end +--controlname:mL,mR,rR,rL,rF,hD,sD,H,LL,RR +function AI_getControls(ctrl) + local field_org,cb,cx,cy={} + for i=1,#field do + field_org[i]={} + for j=1,10 do + field_org[i][j]=field[i][j] + end + end + local best={x=1,dir=0,hold=false,score=-9e99} + for ifhold=0,1 do + local bn=ifhold==0 and bn or hn>0 and hn or nxt[1] + for dir=0,spinNeed[bn]-1 do--for each direction + cb=blocks[bn][dir] + for cx=1,11-#cb[1]do--for each positioon + cy=#field+1 + while not ifoverlapAI(field,cb,cx,cy-1)do + cy=cy-1 + end--move to bottom + for i=1,#cb do + local y=cy+i-1 + if not field[y]then field[y]={0,0,0,0,0,0,0,0,0,0}end + for j=1,#cb[1]do + if cb[i][j]~=0 then + field[y][cx+j-1]=1 + end + end + end--simulate lock + local score=getScore(field,cb,cx,cy) + if score>best.score then + best={bn=bn,x=cx,dir=dir,hold=ifhold==1,score=score} + end + resetField(field_org,cy) + end + end + end--ifHold + + cb,cx,cy=cb_org,cx_org,cy_org + if best.hold then + ins(ctrl,8) + end + if best.dir==1 then + ins(ctrl,3) + elseif best.dir==2 then + ins(ctrl,5) + elseif best.dir==3 then + ins(ctrl,4) + end--rotate + best.x=best.x-spinOffset[best.bn][best.dir] + local n=blockPos[best.bn]b.time +end + +ww,wh=gc.getWidth(),gc.getHeight() + +Timer=tm.getTime +mx,my,mouseShow=-10,-10,true +pause=0--pause countdown +focus=true +scene="" +gamemode="" +bgmPlaying=nil +curBG="none" + +languages={"eng"} +prevMenu={ + load=love.event.quit, + ready="mode", + play="mode", + mode="main", + help="main", + stat="main", + setting="main", + setting2="setting", + intro="quit", + main="quit", +} +swap={ +none={2,1,d=function()end}, +flash={8,1,d=function()gc.clear(1,1,1)end}, +deck={60,20,d=function() + local t=sceneSwaping.time + t=(t>40 and 60-t or t>20 and 20 or t)/255 + gc.setColor(.6,.6,.6,t*13) + gc.rectangle("fill",0,0,1000,t*15) + gc.rectangle("fill",0,600-t*15,1000,t*15) + gc.setColor(.5,0,0,t*13) + gc.line(0,t*15,1000,t*15) + gc.line(0,600-t*15,1000,600-t*15) +end +}, +} +kb.setKeyRepeat(false) +kb.setTextInput(false) + +Texts={ + eng={ + load={"Loading textures","Loading BGM","Loading SFX","Finished",}, + stat={"Games played:","Game time:","Total block used:","Total rows cleared:","Total lines sent:",}, + }, +} +numFonts={} +function numFont(s) + if numFonts[s]then + gc.setFont(numFonts[s]) + else + local t=gc.setNewFont("cb.ttf",s) + numFonts[s]=t + gc.setFont(t) + end + currentFont=-1 +end +Fonts={}for i=1,#languages do Fonts[languages[i]]={}end +fontLib={ +eng=function(s) + if s~=currentFont then + if Fonts[s]then + gc.setFont(Fonts[s]) + else + local t=gc.setNewFont("cb.ttf",s) + Fonts[s]=t + gc.setFont(t) + end + currentFont=s + end +end, +chi=function(s) + if s~=currentFont then + if Fonts[setting.lang][s]then + gc.setFont(Fonts[setting.lang][s]) + else + local t=gc.newFont("hei.ttf",s-5,"normal") + Fonts[setting.lang][s]=t + gc.setFont(t) + end + currentFont=s + end +end, +} + +require("button") + +sfx={ + "button", + "ready","start", + "move","rotate","rotatekick","hold", + "prerotate","prehold", + "drop","fall", + "reach", + "ren_1","ren_2","ren_3","ren_4","ren_5","ren_6","ren_7","ren_8","ren_9","ren_10","ren_11", + "clear_1","clear_2","clear_3","clear_4", + "spin_0","spin_1","spin_2","spin_3", + "perfectclear", +} +bgm={ + "blank", + "way", + "race", + "push", + "reason", +} +img={ + title={ + eng=gc.newImage("/image/title/eng.png"), + chi=gc.newImage("/image/title/chi.png"), + } +} +FX={ + flash=0,--Black screen(frame) + shake=0,--Screen shake(frame) + beam={},--Attack beam + appear=function(t) + setFont(t.font) + gc.setColor(1,1,1,min((30-abs(t.t-30))*.05,1)*(#field>9 and .7 or 1)) + mStr(t.text,150,250-t.font*.5+t.dy) + end, + stretch=function(t) + gc.push("transform") + setFont(t.font) + gc.translate(150,250) + gc.setColor(1,1,1,min((30-abs(t.t-30))*.1,1)*(#field>9 and .7 or 1)) + if t.t<20 then gc.scale((20-t.t)*.015+1,1)end + mStr(t.text,0,-t.font*.5+t.dy) + gc.pop() + end, + drive=function(t) + gc.push("transform") + setFont(t.font) + gc.translate(150,290) + gc.setColor(1,1,1,min((30-abs(t.t-30))*.1,1)*(#field>9 and .7 or 1)) + if t.t<20 then gc.shear((20-t.t)*.03,0)end + mStr(t.text,0,-t.font*.5+t.dy) + gc.pop() + end, + spin=function(t) + gc.push("transform") + setFont(t.font) + gc.translate(150,250) + gc.setColor(1,1,1,min((30-abs(t.t-30))*.1,1)*(#field>9 and .7 or 1)) + if t.t<20 then + gc.scale((20-t.t)*.01+1,(20-t.t)*.015+1) + end + mStr(t.text,0,-t.font*.5+t.dy) + gc.pop() + end, + flicker=function(t) + setFont(t.font) + gc.setColor(1,1,1,min((30-abs(t.t-30))*.05,1)*(#field>9 and .7 or 1)*(rnd()+.5)) + mStr(t.text,150,250-t.font*.5+t.dy) + end, +} +function stencil_field() + gc.rectangle("fill",0,0,300,600) +end +--System data +list={ + clearname={"Single","Double","Triple"}, + reason={[0]="Escape","Block out","Lock out","Finished","Top out"}, + method={"Bag7","His4","Rnd"}, +} +actName={"moveLeft","moveRight","rotRight","rotLeft","rotFlip","hardDrop","softDrop","hold","toLeft","toRight"} +actName_={"move left","move right","rotate right","rotate left","rotate flip","hard drop","soft drop","hold","toLeft","toRight"} +name={"Z","S","L","J","T","O","I"} +blockPos={4,4,4,4,4,5,4} +renATK={[0]=0,0,0,1,1,1,2,2,2,3,3,3} +require"SRS" +gameEnv0={ + das=6,arr=1, + ghost=true,center=true, + drop=30,lock=45, + wait=0,fall=20, + next=6,hold=true, + sequence=1,visible=1, + _20G=false,target=9e99, + color={1,5,2,8,10,3,7,13}, + key={"left","right","x","z","c","up","down","space","LEFT","RIGHT"}, + reach=function()end +} +randomMethod={ + function() + P.bn,P.cb=rem(nxt,1),rem(nb,1) + if #nxt<6 then + local bag={1,2,3,4,5,6,7} + for i=1,7 do + ins(nxt,rem(bag,rnd(8-i))) + end + end + for i=6,#nxt do + nb[i]=blocks[nxt[i]][0] + end + end, + function() + P.bn,P.cb=rem(nxt,1),rem(nb,1) + for j=1,4 do + local i,f=rnd(7) + for k=1,4 do + if i==his[k]then f=true end + end + if not f then break end + end + P.nxt[6],P.nb[6]=i,blocks[i][0] + rem(his,1)ins(his,i) + end, + function() + P.bn,P.cb=rem(nxt,1),rem(nb,1) + repeat i=rnd(7)until i~=nxt[5] + P.nxt[6],P.nb[6]=i,blocks[i][0] + end, +} +loadmode={ + marathon=function() + modeEnv={ + drop=60, + wait=1, + fall=20, + target=10, + reach=Event.marathon_reach, + } + createPlayer(1,190,20,.8) + curBG="game1" + BGM("way") + end, + sprint=function() + modeEnv={ + wait=1, + fall=1, + target=40, + reach=Event.gameover.win, + } + createPlayer(1,190,20,.8) + curBG="game1" + BGM("race") + end, + zen=function() + modeEnv={ + drop=1e99, + lock=1e99, + wait=1, + fall=1, + target=200, + reach=Event.gameover.win, + } + createPlayer(1,190,20,.8) + curBG="game1" + BGM("reason") + end, + gm=function() + modeEnv={ + drop=60, + wait=10, + fall=5, + target=100, + reach=Event.gm_reach, + } + createPlayer(1,190,20,.8) + curBG="game2" + BGM("push") + end, + battle=function() + modeEnv={ + wait=1, + fall=1, + } + createPlayer(1,240,30,.8)--Player + + -- createPlayer(2,580,25,.38,true) + -- createPlayer(3,580,315,.38,true) + --Triple + + -- createPlayer(2,580,140,.6,true) + --Solo + + local n=2 + for i=1,3 do + for j=1,7 do + createPlayer(n,75*i-65,80*j-55,.1,true) + n=n+1 + end + end + for i=11,13 do + for j=1,7 do + createPlayer(n,75*i-65,80*j-55,.1,true) + n=n+1 + end + end + + curBG="game2" + BGM("race") + end, +} +Event={ + task={ + win=function() + gameover=gameover+1 + if gameover%3==0 then + local j=gameover/3 + if j<=#field then + for i=1,10 do + if field[j][i]>0 then field[j][i]=13 end + end + if j==#field then gameover=50 end + end + end + if gameover>80 then + return true + end + end, + lose=function() + gameover=gameover+1 + if gameover%3==0 then + local j=gameover/3 + if j<=#field then + for i=1,10 do + if field[j][i]>0 then field[j][i]=13 end + end + end + end + if gameover>80 then + return true + end + end, + }, + gameover={ + win=function() + P.control=false + P.waiting=1e99 + gameover=0 + for i=1,#visTime do for j=1,10 do + P.visTime[i][j]=1e99 + end end--Make all visible + P.control=false + ins(task,Event.task.win) + end, + lose=function() + P.control=false + P.waiting=1e99 + gameover=0 + for i=1,#visTime do for j=1,10 do + P.visTime[i][j]=1e99 + end end--Make all visible + P.control=false + for i=1,#players.alive do + if players.alive[i]==P.id then + rem(players.alive,i) + break + end + end + for i=1,#P.atkBuffer do + P.atkBuffer[i].sent=true + P.atkBuffer[i].time=0 + end + ins(task,Event.task.lose) + end, + }, + marathon_reach=function() + local s=int(P.cstat.row*.1) + if s>=20 then + Event.gameover.win() + else + gameEnv.drop=Data.marathon_drop[s] + gameEnv.target=s*10+10 + end + end, + gm_reach=function() + + end +} +Data={ + marathon_drop={[0]=60,50,40,30,25,20,18,16,14,12,10,8,7,6,5,4,3,2,1,1}, + shirase_drop={[0]=0}, + shirase_lock={[0]=0}, + shirase_are={[0]=0}, + shirase_lare={[0]=0}, +} +mesDisp={ + marathon=function() + gc.setColor(1,1,1) + setFont(40) + gc.print(format("%0.2f",time),-130,530) + mStr(P.cstat.row.."/"..gameEnv.target,-80,250) + end, + sprint=function() + gc.setColor(1,1,1) + setFont(40) + gc.print(format("%0.2f",time),-130,530) + setFont(75) + mStr(max(40-P.cstat.row,0),-80,280) + end, + zen=function() + gc.setColor(1,1,1) + setFont(40) + gc.print(format("%0.2f",time),-130,530) + setFont(75) + mStr(max(200-P.cstat.row,0),-80,280) + end, + gm=function()end, + battle=function()end, +} +--Game system Data + +setting={ + sfx=true,bgm=true, + fullscreen=false, + lang="eng", + das=5,arr=0, + ghost=true,center=true, + key={"left","right","x","z","c","up","down","space","LEFT","RIGHT"}, + color={1,5,2,8,10,3,7,13}, +} +stat={ + run=0, + game=0, + gametime=0, + piece=0, + row=0, + atk=0, + key=0, + hold=0, + rotate=0, + spin=0, +} +--Userdata tables + +function string.splitS(s,sep) + sep=sep or"/" + local t={} + repeat + local i=find(s,sep) + ins(t,sub(s,1,i-1)) + s=sub(s,i+#sep) + until #s==0 + return t +end +function string.concat(t,sep) + sep=sep or"/" + local s="" + for i=1,#t do + s=s..t[i]..sep + end + return s +end +function sgn(i)return i>0 and 1 or i<0 and -1 or 0 end +function stringPack(s,v)return s..toS(v).."\r\n"end +function without(t,v) + for i=1,#t do + if t[i]==v then return nil end + end + return true +end +function nextLanguage() + for i=1,#languages do + if setting.lang==languages[i]then return languages[i+1]or"eng"end + end +end +function mStr(s,x,y)gc.printf(s,x-500,y,1000,"center")end +function mouseConvert(x,y) + if wh/ww<=.6 then + return 500+(x-ww*.5)*600/wh,y*600/wh + else + return x*1000/ww,300+(y-wh*.5)*1000/ww + end +end +function drawButton() + for i=1,#Buttons[scene]do + local B=Buttons[scene][i] + if not(B.hide and B.hide())then + local t=B==Buttons.sel and .3 or 0 + B.alpha=abs(B.alpha-t)>.02 and(B.alpha+(B.alphat then B.alpha=B.alpha-.02 elseif B.alpha#field+1 and #field+1 or P.cy + while not ifoverlap(cb,cx,y_img-1)do + P.y_img=P.y_img-1 + end + else + while not ifoverlap(cb,cx,cy-1)do + P.cy=P.cy-1 + end + P.y_img=P.cy + end +end +function ifoverlap(bk,x,y) + if x<1 or x+#bk[1]>11 or y<1 then return true end + if y>#field then return nil end + for i=1,#bk do for j=1,#bk[1]do + if field[y+i-1]and bk[i][j]>0 and field[y+i-1][x+j-1]>0 then return true end + end end +end +function resetblock() + P.holded=false + P.freshNext() + P.sc={scs[bn][1],scs[bn][2]}P.dir=0 + P.r,P.c=#cb,#cb[1] + P.cx,P.cy=blockPos[bn],21+ceil(fieldBeneath/30) + freshgho() + P.dropDelay,P.lockDelay=gameEnv.drop,gameEnv.lock + if keyPressing[8]then hold(true)end + if keyPressing[3]then spin(1,true)end + if keyPressing[4]then spin(-1,true)end + if keyPressing[5]then spin(2,true)end + if ifoverlap(cb,cx,cy)then Event.gameover.lose()end + if keyPressing[6]then act.hardDrop()P.keyPressing[6]=false end +end +function pressKey(i,player) + P=player or players[1] + setmetatable(_G,P.index) + if control then + P.keyPressing[i]=true + if waiting<=0 then + act[actName[i]]() + if i>2 and i<6 then keyPressing[i]=false end + elseif i==1 then + P.moving=-1 + elseif i==2 then + P.moving=1 + end + P.cstat.key=stat.key+1;ins(keyTime,1,frame)rem(keyTime,11) + -- if playmode=="recording"then ins(rec,{i,frame})end + stat.key=stat.key+1 + end +end +function releaseKey(i,player) + P=player or players[1] + setmetatable(_G,P.index) + P.keyPressing[i]=false + -- if playmode=="recording"then ins(rec,{-i,frame})end +end +function spin(d,ifpre) + if bn==6 then return nil end + local icb=blocks[bn][(dir+d)%4] + local isc=d==1 and{c-sc[2]+1,sc[1]}or d==-1 and{sc[2],r-sc[1]+1}or{r-sc[1]+1,c-sc[2]+1} + local ir,ic=#icb,#icb[1] + local ix,iy=cx+sc[2]-isc[2],cy+sc[1]-isc[1] + local t=false + local iki=SRS[bn][dir*10+(dir+d)%4] + for i=1,#iki do + if not ifoverlap(icb,ix+iki[i][1],iy+iki[i][2])then + ix,iy=ix+iki[i][1],iy+iki[i][2] + t=true + break + end + end + if t then + P.cx,P.cy=ix,iy + P.sc,P.cb=isc,icb + P.r,P.c=ir,ic + P.dir=(dir+d)%4 + freshgho() + P.lockDelay=gameEnv.lock + SFX(ifpre and"prerotate"or ifoverlap(cb,cx,cy+1)and ifoverlap(cb,cx-1,cy)and ifoverlap(cb,cx+1,cy)and"rotatekick"or"rotate") + stat.rotate=stat.rotate+1 + end +end +function hold(ifpre) + if not holded and waiting<=0 and gameEnv.hold then + P.hn,P.bn=bn,hn + P.hb,P.cb=blocks[hn][0],hb + + if bn==0 then freshNext()end + P.sc={scs[bn][1],scs[bn][2]}P.dir=0 + P.r,P.c=#cb,#cb[1] + P.cx,P.cy=blockPos[bn],21 + freshgho() + P.dropDelay,P.lockDelay=gameEnv.drop,gameEnv.lock + if ifoverlap(cb,cx,cy) then Event.gameover.lose()end + P.holded=true + SFX(ifpre and"prehold"or"hold") + stat.hold=stat.hold+1 + end +end +function drop() + if cy==y_img then + P.waiting=gameEnv.wait + local dospin=ifoverlap(cb,cx,cy+1)and ifoverlap(cb,cx-1,cy)and ifoverlap(cb,cx+1,cy) + ins(dropTime,1,frame)rem(dropTime,11) + lock() + local cc,csend=checkrow(cy,r),0--Currect clear&send + + P.combo=P.combo+1--combo=0 is under + if cc==4 then + if b2b then + showText("Tetris B2B","drive",70) + csend=5 + else + showText("Tetris","stretch",80) + csend=4 + P.b2b=true + end + elseif cc>0 then + if dospin then + if b2b then + showText(name[bn].." spin "..list.clearname[cc].." B2B","spin",40) + csend=2*cc+1 + else + showText(name[bn].." spin "..list.clearname[cc],"spin",50) + csend=2*cc + P.b2b=true + end + SFX("spin_"..cc) + stat.spin=stat.spin+1 + else + P.b2b=false + showText(list.clearname[cc],"appear",50) + csend=cc-1 + end + else + P.combo=0 + if dospin then + showText(name[bn].." spin","appear",50) + SFX("spin_0") + end + end + if cc>0 and #clearing==#field then + showText("Perfect Clear","flicker",70,-60) + csend=csend+5 + SFX("perfectclear") + end + csend=csend+(renATK[combo]or 4) + if cc>0 then + SFX("clear_"..cc) + SFX("ren_"..min(combo,11)) + end + if csend>0 then + while csend>0 and P.atkBuffer[1]do + csend=csend-1 + P.atkBuffer[1].amount=P.atkBuffer[1].amount-1 + if P.atkBuffer[1].amount==0 then + rem(P.atkBuffer,1) + end + end + if csend>0 and #players.alive>1 then garbageSend(P.id,csend,120)end + elseif cc==0 then + garbageRelease() + end--Send attack + stat.piece,stat.row,stat.atk=stat.piece+1,stat.row+cc,stat.atk+csend + P.cstat.piece,P.cstat.row,P.cstat.atk=P.cstat.piece+1,P.cstat.row+cc,P.cstat.atk+csend + if P.cstat.row>=gameEnv.target then + gameEnv.reach() + if control then SFX("reach")end + end + else + if cy>y_img then P.cy=cy-1 end + end +end +function lock() + for i=1,r do + local y=cy+i-1 + if not P.field[y]then P.field[y],P.visTime[y]={0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0}end + for j=1,c do + if cb[i][j]~=0 then + P.field[y][cx+j-1]=P.gameEnv.color[bn] + P.visTime[y][cx+j-1]=P.showTime + end + end + end +end +function ckfull(i) + for j=1,10 do if field[i][j]==0 then return nil end end + return true +end +function checkrow(s,num)--(cy,r) + local c=0--rows cleared + for i=s,s+num-1 do if ckfull(i)then + ins(clearing,1,i) + P.falling=gameEnv.fall + c=c+1--row cleared+1 + for k=1,1000 do + PTC.dust[P.id]:setPosition(rnd(0,300),600-30*i+rnd(30)) + PTC.dust[P.id]:emit(1) + end + end end + return c +end +function garbageSend(sender,send,time) + local pos,r=rnd(10) + repeat + r=players.alive[rnd(#players.alive)] + until r~=P.id + createBeam(sender,r) + ins(players[r].atkBuffer,{pos,amount=send,countdown=time,cd0=time,time=0,sent=false}) + sort(players[r].atkBuffer,sortByTime) +end +function garbageRelease() + local t=P.showTime*2 + for i=1,#P.atkBuffer do + local atk=P.atkBuffer[i] + if not atk.sent and atk.countdown==0 then + for j=1,atk.amount do + ins(P.field,1,{13,13,13,13,13,13,13,13,13,13}) + ins(P.visTime,1,{t,t,t,t,t,t,t,t,t,t}) + for k=1,#atk do + P.field[1][atk[k]]=0 + end + end + atk.sent=true + atk.time=0 + P.fieldBeneath=P.fieldBeneath+atk.amount*30 + end + end +end +function drawPixel(y,x,id,alpha) + gc.setColor(1,1,1,alpha) + gc.draw(blockSkin[id],30*x-30,600-30*y) +end +--------------------------------Warning!_G is __indexed to players[n]! + +require("user_actions")--Game control functions + +mouseDown={} +keyDown={} +function keyDown.play(key) + local k=players[1].gameEnv.key + for i=1,10 do + if key==k[i]then + pressKey(i,players[1]) + break + end + end + if key=="escape"then back()end +end +function keyDown.setting2(key) + if key=="escape"then + back() + elseif keysetting then + setting.key[keysetting]=key + keysetting=nil + end +end +keyUp={} +function keyUp.play(key) + local k=players[1].gameEnv.key + for i=1,10 do + if key==k[i]then + releaseKey(i,players[1]) + break + end + end +end +wheelmoved={} + +require("ai")--AI module +require("timer")--Timer +require("paint")--Paint +require("game_scene")--Game scenes +require("control")--User control + +function love.update(dt) + if players then + for i=1,#players do + for k,v in pairs(players[i])do + if rawget(_G,k)then print(i,k)end + end + end + end + if Buttons.pressing>0 then + Buttons.pressing=Buttons.pressing+1 + if Buttons.pressing>35 and Buttons.pressing%6==0 then love.mousepressed(ms.getX(),ms.getY(),1)end + end + if sceneSwaping then + sceneSwaping.time=sceneSwaping.time-1 + if sceneSwaping.time==sceneSwaping.mid then + for i=1,#Buttons[scene]do + Buttons[scene][i].alpha=0 + end + game[sceneSwaping.tar]() + Buttons.sel=nil + love.mousemoved(ms.getX(),ms.getY()) + elseif sceneSwaping.time==0 then + sceneSwaping=nil + end + elseif Tmr[scene]then + Tmr[scene](dt) + end +end +function love.draw() + Pnt.BG[curBG]() + if Pnt[scene]then Pnt[scene]()end + setFont(35) + drawButton() + if mouseShow then + gc.setColor(1,0,0,.6) + gc.circle("fill",mx,my,4) + end + if sceneSwaping then sceneSwaping.draw()end + + gc.setColor(0,0,0) + if wh/ww>=.6 then + gc.rectangle("fill",0,0,1000,-(wh*1000/ww-600)*.5) + gc.rectangle("fill",0,600,1000,(wh*1000/ww-600)*.5) + else + gc.rectangle("fill",0,0,-(ww*600/wh-1000)*.5,600) + gc.rectangle("fill",1000,0,(ww*600/wh-1000)*.5,600) + end--Draw black side + + --numFont(10)gc.setColor(1,1,1) + --gc.print(tm.getFPS(),0,590) + --if gcinfo()>500 then collectgarbage()end +end +function love.resize(x,y) + ww,wh=x,y + gc.origin() + gc.translate(ww*.5,wh*.5) + if wh/ww>=.6 then + gc.scale(ww/1000) + else + gc.scale(wh/600) + end + gc.translate(-500,-300) +end +function love.focus(f) + if f then + focus=true + ms.setVisible(false) + if bgmPlaying then bgm[bgmPlaying]:play()end + else + if scene=="play"then pause=20 end + focus=false + ms.setVisible(true) + if bgmPlaying then bgm[bgmPlaying]:pause()end + end +end +function love.run() + tm.step() + love.resize(1000,600) + game.load()--Launch + return function() + love.event.pump() + for name,a,b,c,d,e,f in love.event.poll()do + if name=="quit"then + savedata() + return 0 + end + love.handlers[name](a,b,c,d,e,f) + end + if focus or pause==20 then + tm.step() + love.update(tm.getDelta()) + if gc.isActive()then + gc.clear(1,1,1) + love.draw()--Draw all things + gc.present() + end + end + end +end +--System callbacks + +do--Texture/Image + local p=gc.newImage("/image/block.png") + local l={} + gc.setColor(1,1,1) + for i=1,13 do + l[i]=gc.newCanvas(30,30) + gc.setCanvas(l[i]) + gc.draw(p,30-30*i) + end + blockSkin=l + l={} + for i=1,1 do + local p=gc.newImage("/image/BG/"..i..".png") + l[i]=gc.newCanvas(1200,1200) + gc.setCanvas(l[i]) + gc.draw(p,nil,nil,nil,10,10) + p:release() + end + background=l + gc.setCanvas() +end +do--Particle + PTC={dust={}}--Particle systems + c=gc.newCanvas(6,6)gc.setCanvas(c) + gc.clear(1,1,1) + PTC.dust[0]=gc.newParticleSystem(c,10000) + PTC.dust[0]:setParticleLifetime(.2,.3) + PTC.dust[0]:setEmissionRate(0) + PTC.dust[0]:setLinearAcceleration(-1500,-200,1500,200) + PTC.dust[0]:setColors(1,1,1,.4,1,1,1,0) + --Dust particles + gc.setCanvas() +end +c=nil + +userdata=fs.newFile("userdata") +if fs.getInfo("userdata")then + loaddata() +end + +stat.run=stat.run+1 +setFont=fontLib[setting.lang] +Text=Texts[setting.lang] \ No newline at end of file diff --git a/paint.lua b/paint.lua new file mode 100644 index 00000000..f9a313c5 --- /dev/null +++ b/paint.lua @@ -0,0 +1,253 @@ +Pnt={BG={}} +function Pnt.BG.none() + gc.clear(.2,.2,.2) +end +function Pnt.BG.menu() + gc.setLineWidth(40) + gc.setColor(1,.9,.9) + local t=(Timer()%1)*100 + for i=-6,9 do + gc.line(t+100*i,-50,t+100*i+600,650) + end + gc.setLineWidth(2) +end +function Pnt.BG.game1() + gc.setColor(1,1,1) + gc.draw(background[1],500,300,Timer()*.15,nil,nil,600,600) +end +function Pnt.BG.game2() + gc.setColor(1,.5,.5) + gc.draw(background[1],500,300,Timer()*.15,nil,nil,600,600) +end +function Pnt.BG.game3() + gc.push("transform") + gc.translate(500,300) + gc.scale(1,.6) + gc.setColor(1,.9,.9) + gc.setLineWidth(30) + local t=(Timer()%1)*60 + for x=0,8 do + local d=60*x+t + gc.rectangle("line",-d,-d,2*d,2*d) + end + gc.setLineWidth(2) + gc.pop() +end +function Pnt.BG.game4() + local t=215+sin(Timer()*6)*40 + gc.setColor(255,t,t) + gc.rectangle("fill",0,0,1000,600) +end +function Pnt.BG.game5() + gc.setColor(1,.9,.9) + local t=(Timer()%1)*50 + for x=0,20 do + for y=0,12 do + if(x+y)%2==0 then + gc.rectangle("fill",50*x-t,50*y-t,50,50) + end + end + end +end + +function Pnt.load() + if loadprogress then + gc.setLineWidth(3) + gc.setColor(.8,.8,.8) + gc.rectangle("fill",200,280,loadprogress*600,40) + gc.setColor(1,1,1) + gc.rectangle("line",200,280,600,40) + setFont(30) + mStr("Loading...",500,285) + end +end +function Pnt.intro() + gc.setColor(1,1,1) + gc.draw(img.title[setting.lang],500,300,nil,nil,nil,250,100) +end +function Pnt.main() + gc.setColor(1,1,1) + gc.draw(img.title[setting.lang],500,120,nil,nil,nil,250,60) +end +function Pnt.play() + for p=1,#players do + P=players[p] + setmetatable(_G,P.index) + gc.push("transform") + gc.translate(x,y)gc.scale(size)--Scale + gc.setColor(0,0,0,.7)gc.rectangle("fill",0,0,620,690)--Back + gc.setLineWidth(3) + gc.setColor(1,1,1)gc.rectangle("line",0,0,620,690)--Big frame + gc.translate(160,70) + gc.stencil(stencil_field, "replace", 1) + gc.translate(0,fieldBeneath) + love.graphics.setStencilTest("equal",1) + for j=1,#field do + if falling<=0 or without(clearing,j)then + for i=1,10 do + if field[j][i]>0 then + drawPixel(j,i,field[j][i],min(visTime[j][i],20)*.05) + end + end + else + gc.setColor(1,1,1,falling/gameEnv.fall) + gc.rectangle("fill",0,600-30*j,300,30) + end + end--Field + if waiting<=0 then + if gameEnv.ghost then + for i=1,r do for j=1,c do + if cb[i][j]>0 then + drawPixel(i+y_img-1,j+cx-1,gameEnv.color[bn],.4) + end + end end + end--Ghost + for i=1,r do for j=1,c do + if cb[i][j]>0 then + drawPixel(i+cy-1,j+cx-1,gameEnv.color[bn],1) + end + end end--Block + end + gc.draw(PTC.dust[p])--Draw game field + love.graphics.setStencilTest()--In-field mask + gc.translate(0,-fieldBeneath) + gc.setColor(1,1,1)gc.rectangle("line",-1,-1,300,600)--Draw boarder + + local h=0 + for i=1,#atkBuffer do + local a=atkBuffer[i] + local bar=a.amount*30 + 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(1,0,0) + gc.rectangle("fill",302,600-h,8,-bar+5) + gc.setColor(1,1,0) + gc.rectangle("fill",302,600-h+(-bar+5),8,-(-bar+5)*(1-a.countdown/a.cd0)) + --Time count + else + gc.setColor(1,(sin((Timer()-i)*20)+1)*.5,0) + gc.rectangle("fill",302,600-h,8,-bar+5) + --warning + end + else + gc.setColor(1,0,0) + bar=bar*(20-a.time)*.05 + gc.rectangle("fill",302,600-h,8,-bar+5) + --Disappear + end + h=h+bar + if h>600 then break end + end--Buffer line + + setFont(40) + if gameEnv.hold then + gc.setColor(1,1,1) + gc.print("Hold",-113,0) + for i=1,#hb do + for j=1,#hb[1] do + if hb[i][j]>0 then + drawPixel(i+17.5-#hb*.5,j-2.5-#hb[1]*.5,holded and 13 or gameEnv.color[hn],1) + end + end + end + end--Hold + for N=1,gameEnv.next do + gc.setColor(1,1,1) + gc.print("Next",336,0) + local b=nb[N] + for i=1,#b do + for j=1,#b[1] do + if b[i][j]>0 then + drawPixel(i+20-2.4*N-#b*.5,j+12.5-#b[1]*.5,gameEnv.color[nxt[N]],1) + end + end + end + end--Next + if count then + gc.push("transform") + gc.translate(155,220) + gc.setColor(1,1,1) + 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,#bonus do + bonus[i]:draw() + end--Effects + mesDisp[gamemode]()--Draw message + setFont(45) + gc.translate(380,550) + gc.setColor(1,1,1) + mStr(int(dropSpeed),0,-21) + gc.setColor(.6,.6,.6)gc.setLineWidth(5) + gc.circle("line",0,0,50) + gc.setColor(1,1,1)gc.setLineWidth(2) + gc.circle("line",0,0,50) + gc.rotate(2.0944+(dropSpeed<=175 and .020944*dropSpeed or 4.712389-52.35988/(dropSpeed-125))) + gc.setColor(.4,.4,.4,.5)gc.setLineWidth(5) + gc.line(0,0,40,0) + gc.setColor(.6,.6,.6,.5)gc.setLineWidth(3) + gc.line(0,0,40,0) + --Speed dial + + gc.pop() + end--Draw players + gc.setLineWidth(3) + for i=1,#FX.beam do + local b=FX.beam[i] + local t=b.t/45 + if t<.25 then + t=t*4 + gc.setColor(1,1,1,4*t) + gc.line(b[1],b[2],b[1]+t*(b[3]-b[1]),b[2]+t*(b[4]-b[2])) + elseif t<.75 then + gc.setColor(1,1,1) + gc.line(b[1],b[2],b[3],b[4]) + else + t=4*t-3 + gc.setColor(1,1,1,4-4*t) + gc.line(b[1]+t*(b[3]-b[1]),b[2]+t*(b[4]-b[2]),b[3],b[4]) + end + end + setmetatable(_G,nil) +end +function Pnt.setting() + setFont(30) + gc.setColor(1,1,1) + mStr("DAS:"..setting.das,200,65) + mStr("ARR:"..setting.arr,400,65) +end +function Pnt.setting2() + setFont(30) + gc.setColor(1,1,1) + for i=1,8 do + gc.printf(actName_[i]..":",80,5+50*i,150,"right") + end + if keysetting then + setFont(35) + gc.print("<<",470,50*keysetting) + end +end +function Pnt.help() + gc.setColor(1,1,1) + gc.draw(img.title[setting.lang],60,420,.2,.5+.05*sin(Timer()*2)) +end +function Pnt.stat() + setFont(30) + gc.setColor(1,1,1) + gc.print(Text.stat[1],250,60) + gc.print(Text.stat[2],250,100) + gc.print(Text.stat[3],250,140) + gc.print(Text.stat[4],250,180) + + gc.print(stat.game,600,60) + gc.print(format("%0.2f",stat.gametime).."s",600,100) + gc.print(stat.piece,600,140) + gc.print(stat.row,600,180) + gc.draw(img.title[setting.lang],60,420,.2,.5+.05*sin(Timer()*2)) +end \ No newline at end of file diff --git a/question note.txt b/question note.txt new file mode 100644 index 00000000..8c7e9559 --- /dev/null +++ b/question note.txt @@ -0,0 +1,2 @@ +1.缓冲条位置 +2. \ No newline at end of file diff --git a/timer.lua b/timer.lua new file mode 100644 index 00000000..3f3f8b0f --- /dev/null +++ b/timer.lua @@ -0,0 +1,169 @@ +Tmr={} +function Tmr.load() + if loading==1 then + loadnum=loadnum+1 + loadprogress=loadnum/10 + if loadnum==5 then + --require("load_texture") + elseif loadnum==10 then + loadnum=1 + loading=2 + end + elseif loading==2 then + if loadnum<=#bgm then + bgm[bgm[loadnum]]=love.audio.newSource("/BGM/"..bgm[loadnum]..".ogg","stream") + bgm[bgm[loadnum]]:setLooping(true) + loadprogress=loadnum/#bgm + loadnum=loadnum+1 + else + for i=1,#bgm do bgm[i]=nil end + loading=3 + loadnum=1 + end + elseif loading==3 then + if loadnum<=#sfx then + sfx[sfx[loadnum]]=love.audio.newSource("/SFX/"..sfx[loadnum]..".ogg","static") + loadprogress=loadnum/#sfx + loadnum=loadnum+1 + else + for i=1,#sfx do sfx[i]=nil end + loading=4 + loadnum=1 + end + elseif loading==4 then + loadnum=loadnum+1 + if loadnum==20 then + gotoScene("main") + end + end +end +function Tmr.play(dt) + frame=frame+1 + if count then + count=count-1 + if count==0 then + count=nil + SFX("start") + for P=1,#players do + P=players[P] + _G.P=P + setmetatable(_G,P.index) + P.control=true + resetblock() + end + setmetatable(_G,nil) + elseif count%60==0 then + SFX("ready") + end + return nil + end + for p=1,#players do + P=players[p] + setmetatable(_G,P.index) + if control then P.time=time+dt end + + local v=0 + for i=2,10 do v=v+i*(i-1)*7.2/(frame-keyTime[i])end P.keySpeed=keySpeed*.99+v*.1 + v=0 for i=2,10 do v=v+i*(i-1)*7.2/(frame-dropTime[i])end P.dropSpeed=dropSpeed*.99+v*.1 + --Update speeds + + if P.ai then + P.ai.controlDelay=P.ai.controlDelay-1 + if P.ai.controlDelay==0 then + if #P.ai.controls>0 then + pressKey(P.ai.controls[1],P) + releaseKey(P.ai.controls[1],P) + rem(P.ai.controls,1) + P.ai.controlDelay=P.ai.controlDelay0 + else + AI_getControls(P.ai.controls) + P.ai.controlDelay=2*P.ai.controlDelay0 + end + end + end + + for j=1,#field do for i=1,10 do + if visTime[j][i]>0 then P.visTime[j][i]=visTime[j][i]-1 end + end end + --Fresh visible time + if keyPressing[1]or keyPressing[2]then + P.moving=moving+sgn(moving) + local d=abs(moving)-gameEnv.das + if d>1 then + if gameEnv.arr>0 then + if d%gameEnv.arr==0 then + act[moving>0 and"moveRight"or"moveLeft"](true) + end + else + act[moving>0 and"toRight"or"toLeft"]() + end + end + else + P.moving=0 + end + if keyPressing[7]then + act.softDrop() + P.downing=downing+1 + else + P.downing=0 + end + if falling>0 then + P.falling=falling-1 + if falling<=0 then + if #field>clearing[1]then SFX("fall")end + for i=1,#clearing do + rem(field,clearing[i]) + rem(visTime,clearing[i]) + end + P.clearing={} + end + elseif waiting>0 then + P.waiting=waiting-1 + if waiting<=0 then + resetblock() + end + else + if cy~=y_img then + if dropDelay>1 then + P.dropDelay=dropDelay-1 + else + drop() + P.dropDelay,P.lockDelay=gameEnv.drop,gameEnv.lock + end + else + if lockDelay>0 then P.lockDelay=lockDelay-1 + else drop() + end + end + end + for i=#bonus,1,-1 do + bonus[i].t=bonus[i].t+1 + if bonus[i].t>60 then rem(bonus,i)end + end + for i=#task,1,-1 do + if task[i]()then rem(task,i)end + end + for i=#atkBuffer,1,-1 do + local atk=atkBuffer[i] + atk.time=atk.time+1 + if not atk.sent then + if atk.countdown>0 then + atk.countdown=atk.countdown-1 + end + else + if atk.time>20 then + rem(atkBuffer,i) + end + end + end + if fieldBeneath>0 then P.fieldBeneath=fieldBeneath-1 end + PTC.dust[p]:update(dt) + end + for i=#FX.beam,1,-1 do + FX.beam[i].t=FX.beam[i].t+1 + if FX.beam[i].t>45 then + rem(FX.beam,i) + end + end + setmetatable(_G,nil) +end \ No newline at end of file diff --git a/user_actions.lua b/user_actions.lua new file mode 100644 index 00000000..b4863ef9 --- /dev/null +++ b/user_actions.lua @@ -0,0 +1,47 @@ +act={ + moveLeft=function(auto) + if not auto then P.moving=-1 end + if not ifoverlap(cb,cx-1,cy)then + P.cx=cx-1 + freshgho() + P.lockDelay=gameEnv.lock + if cy==y_img then SFX("move")end + end + end, + moveRight=function(auto) + if not auto then P.moving=1 end + if not ifoverlap(cb,cx+1,cy)then + P.cx=cx+1 + freshgho() + P.lockDelay=gameEnv.lock + if cy==y_img then SFX("move")end + end + end, + hardDrop=function() + if P.waiting<=0 then + if cy~=y_img then + P.cy=y_img + SFX("drop") + end + drop() + P.keyPressing[6]=false + end + end, + softDrop=function() + act.toDown() + P.downing=1 + end, + rotRight=function()spin(1)end, + rotLeft=function()spin(-1)end, + rotFlip=function()spin(2)end, + hold=hold, + --Player movements + + down1=function()drop()end, + down4=function()for i=1,4 do if cy~=y_img then drop()else break end end end, + toDown=function()P.cy,P.lockDelay=y_img,gameEnv.lock end, + toLeft=function()while not ifoverlap(cb,cx-1,cy)do P.cx,P.lockDelay=cx-1,gameEnv.lock;freshgho()end end, + toRight=function()while not ifoverlap(cb,cx+1,cy)do P.cx,P.lockDelay=cx+1,gameEnv.lock;freshgho()end end, + quit=function()Event.gameover.lose()end, + --System movements +} \ No newline at end of file