CocosCreater的俄羅斯方塊遊戲實現
前段時間要做課程設計,發現可以做俄羅斯方塊,就想著用cocoscreater做一個俄羅斯方塊遊戲,順便發上來。
內容就偷個懶,從自己的課程設計拿過來,不再寫了。。自己也記錄一下構思過程。
當然,首先要把連結發上來:
接下來就照著自己的設計論文一一複製上來啦。
要文件的直接拉到最後啊!
資源需求:
1、 七種顏色單個方塊 要求:格式統一。
2、 七種俄羅斯方塊貼圖。
3、 遊戲UI素材
4、 背景音樂選擇
資源需求嘛,網上隨便找找素材,略過。。
(遊戲介面)
需求:協調美觀的遊戲介面,由 ①主遊戲區
②得分割槽 ③下一組方塊預告區 ④暫停區 ⑤調速區 ⑥遊戲結束區 ⑦遊戲背景 ⑧操作提示 組成
①主遊戲區:遊戲的方塊生成、移動、旋轉、消行的顯示去,是最重要的遊戲邏輯圖形化的實現環節,佔據遊戲介面的大部分。
②得分割槽: 每次消行,的分割槽會加上一定的分數,是得分的視覺化介面
③下一組方塊預告區:下一組方塊的預告。讓使用者預知下一個生成的方塊樣式,並作出一定的協調。
④暫停區: 遊戲的暫停和繼續,有助於隨時控制遊戲。
⑤調速區:調整方塊下落的速度,是對遊戲難度的調整。
⑥遊戲結束區:遊戲失敗後的遊戲結束通知介面,告知使用者此回合失敗,可以重新開始下一回合。
⑦遊戲背景:整個遊戲介面的背景,應做到簡介,美觀,不與方塊顏色衝突,且不能影響遊戲體驗。
⑧操作提示:遊戲開始時,向用戶告知啟用的控制方法,和控制按鈕,以及相應介面回饋效果。ui顯示的需求很好理解
控制需求
鍵盤,觸控任選啦~~顯示更新需求
當做出消除介面中某一行的操作後,介面需要獲得運算結果並更新。
幾種演算法需求的考慮,就是要考慮到的一些注意點吧:
1.視覺上碰撞到方塊後停止運動並新建方塊的演算法。
2.視覺上的旋轉操作,不會旋轉到遊戲介面外的演算法。
3.視覺上有限空間內無法旋轉的演算法。
4.視覺上有限空間內無法移動的演算法。
5視覺上同時消除超過一行的演算法。
6.新建方塊的演算法
7.遊戲介面由畫素轉換到方塊網格的演算法。
然後是方塊的定義
定義方塊型別:
在編輯器中預製7種不同顏色的正方形方塊,分別是:藍色,綠色,天藍色,紫色,紅色,黃色,橙色。遊戲開始時由Math.floor(7*Math.random());程式碼驅動隨即選取0~6號方塊中一種顏色的方塊,並例項化對應的目標圖形。
基本圖形的網格化:
例項化出的基本圖形的座標是以畫素為單位,利用2維陣列來網格化,選擇600*1200畫素的主遊戲區,利用20*10的陣列對其進行網格化,剛好200塊塊方塊填滿遊戲區,每個方塊佔有60*60畫素,並有一個唯一對應的行和列資訊,便於以後運算。
流程圖,啟發一下方塊的思路哈。
接下來就是程式碼、、最後我會附上整個專案檔案滴~
模組設計
1.隨機生成數並相應例項化圖形的模組
2.移動和控制模組
3檢查碰撞模組
4移動和旋轉的同時下落重疊檢測
5得分和調整模組
6整體ui關聯控制模組
7遊戲整體狀態檢測判定模組
(1)隨機生成數並相應例項化圖形的模組:
首先建立一個23*10的二維陣列this.box[][]利用兩個for迴圈給陣列每一項賦值為0, 但保留this.box[i] 的每一個項,賦值為一,用來作為地面的判斷。所以i=0是地面層 i=1~21是遊戲層 i>21作為超出介面gameover的判定區。
應用的方法是:在遊戲過程中每次監測到會產生碰撞就會停止下落,並重新建立方塊,判定停止下落的同時,給四個方塊的停留點儲存一個唯一的二維陣列標示,並賦值為1。前文提到,7種方塊的旋轉後共有19種不同圖形。由於數量並不多,在遊戲中選擇採取預儲存19種圖形的四個方塊位置和i的關聯資訊。這些資料共佔據76行程式碼,並有一個基準i,j值作為位置的參考和旋轉操作的轉軸中心。考慮到未來階段的程式碼簡介的,不重複的需求,可以選擇演算法生成。
(2)移動和控制模組
每次更改i的值並呼叫預存程式碼,更新位置,做到視覺上控制效果。方塊的移動實際上是由this.box[i][j]二維陣列的i,j的加減來控制的,加入鍵盤監聽,監聽到鍵盤的輸入,分別由上下左右鍵和W S D A鍵控制i,j加減和圖形旋轉,和螢幕上的點選旋轉,左右滑動控制左右移動來做到人機的互動。
(3)檢查碰撞模組
檢查碰撞模組是俄羅斯方塊的重要點有幾點需要做到
1.邊界碰撞檢測
整個遊戲有三個邊界分別是:左側、右側、底側。
由於遊戲完成時考慮到使用畫素座標點限制左右側邊界,其範圍是0~600而底側的碰撞檢測則是使用到了二維陣列的第一行賦值為1的方法,利用二維陣列i,j和第一行做對比的方法。考慮到統一邊界演算法程式碼修改亮大,現有方法穩定有效就不做統一。
2.已放置方塊和下落方塊的碰撞檢測
在this.box[i][j]陣列中
已放置方塊在停止時會對座標點對應的二維陣列座標點賦值
在下落過程中通過演算法計算當前圖形中j的種類和每種j對應i的最小值所在的點,每個點對應的i值的下一行即this.box[i-1][j]的值如果為1就判定停止,並重新生成。
3.已放置方塊和下落方塊的左右移動的碰撞檢測
在this.box[i][j]陣列中,在移動過程中通過演算法計算圖形中每種i對應的j的最小值,和i的不重複數量,在此需要對陣列做去重運算。最後獲取的點應該同i的種類數量一樣。
做左移操作時,因該獲取到i和對應的j最小值。此時利用this.box[i][j-1]如果為一記sum++對所有種類遍歷過後,只有所有影象左側判定方塊都為空即sum等於i的種類數,才可以判定左移操作為真,此時j的值減一,並且呼叫預存資料,更新位置。
同理,做右移操作時需要獲取到的是i和對應的最大值,並做和左移類似的操作和判定。
4.旋轉操作後錯位回退模組
旋轉時,獲取此時的關鍵資料包括形態、偏移值、ij值為回退提供資料,獲取旋轉後如果旋轉後的圖片位置上已經有相應的this.box[i][j]已經為1則判定無法旋轉,此時將收集到的資料重新賦值給所有屬性,轉變回上一狀態。
(4)得分和調整模組
每次重新例項時呼叫消行檢測模組,對this.box[i][j]做一個遍歷如果某個i上的所有值合為10做消行方法。消行後由於對應i行為空此時需要呼叫到降落演算法,此時遍歷所有i行上為1的box[][]點做i-1操作並更新位置。
(5)整體ui關聯控制模組
消行後每成功一次呼叫加分演算法。每次重新例項化回預先隨機下一次的目標並用全域性變數交給例項化的方法,預告知介面接收到隨機值後載入相應圖片根據進度條的調整控制圖片下落速度。播放暫停按鈕,使用全域性變數在0和1間根據點選切換,0為正常遊戲1為暫停遊戲
(6)遊戲開始時的操作控制預告知顯示版。
每次遊戲開始,播放遊戲的控制文字,告知使用者如何操作整個遊戲,並按透明度漸漸消失。
(7)遊戲整體狀態檢測判定模組
包涵全域性變數值的使用如0、1的交換確定遊戲狀態, 值的加減確定圖片的旋轉狀態。
6.1資料初始化
onLoad: function () {
cc.audioEngine.playEffect(this.audio, true);
this.xingtai=0;
this.prefab;
this.jmix;//j的邊界最小最大值
this.jmax;
this.out=0;
this.speed=0.3;
this.scorenum=0;
this.one=[];
this.two=[];
this.three=[];
this.arry=[];//去重陣列
this.nextgoal=0;
this.gamestate=0;//遊戲的狀態
this.box=[];
for(leti=0;i<25;i++){
this.box[i]=[];
for(letj=0;j<10;j++){
if(i===0){
this.box[i][j]=1;
}else{
this.box[i][j]=0;
}
}
}
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown,this);
this.setcolour();
},
6.2隨機數的生成,和對應圖片的選取和例項化
setcolour(){
this.i=21;
this.j=4;
vargoal=this.nextgoal;
this.gameover();
this.buildbody(goal);
this.drawnext();
},//獲取顏色後例項化7種影象
buildbody(goal){
cc.log('例項化:'+goal)
if(goal===0){this.prefab=this.rect0;}
if(goal===1){this.prefab=this.rect1;}
if(goal===2){this.prefab=this.rect2;}
if(goal===3){this.prefab=this.rect3;}
if(goal===4){this.prefab=this.rect4;}
if(goal===5){this.prefab=this.rect5;}
if(goal===6){this.prefab=this.rect6;}
this.type=goal;
this.rectyi=cc.instantiate(this.prefab).getComponent('rect');
this.recter=cc.instantiate(this.prefab).getComponent('rect');
this.rectsan=cc.instantiate(this.prefab).getComponent('rect');
this.rectsi=cc.instantiate(this.prefab).getComponent('rect');
this.point=cc.instantiate(this.basepoint).getComponent('move');
var box=cc.find('Canvas/box');
box.addChild(this.point.node);
box.addChild(this.rectyi.node);
box.addChild(this.recter.node);
box.addChild(this.rectsan.node);
box.addChild(this.rectsi.node);
this.xingtai=0;
this.schedule(this.down,this.speed);//速度
通過計時器,每個speed間隔下落一次
},
down(){
if(this.gamestate===0){
this.i--;
this.choose();
//this.scheduleOnce(this.check,0.1);
this.check();
}
},
choose(){
if(this.type===0){this.buildone();}
if(this.type===1){this.buildtwo();}
if(this.type===2){this.buildthree();}
if(this.type===3){this.buildfour();}
if(this.type===4){this.buildfive();}
if(this.type===5){this.buildsix();}
if(this.type===6){this.buildseven();}
},
6.3七種圖片和19種旋轉形態的預儲存和位置更新
buildone(){//一號圖形
var i=this.i;varj=this.j;
this.rectyi.node.x=j*60;this.rectyi.node.y=i*60;
this.recter.node.x=(j+1)*60;this.recter.node.y=i*60
this.rectsan.node.x=j*60;this.rectsan.node.y=(i+1)*60;
this.rectsi.node.x=(j+1)*60;this.rectsi.node.y=(i+1)*60;
this.jmix=j;this.jmax=j+1;
this.one[0]=i; this.two[0]=j; this.three[0]=1;//this.four[0]=1;this.five[0]=0;
this.one[1]=i; this.two[1]=j+1;this.three[1]=1;//this.four[1]=0;this.five[1]=1;
this.one[2]=i+1;this.two[2]=j; this.three[2]=0;//this.four[2]=1;this.five[2]=0;
this.one[3]=i+1;this.two[3]=j+1;this.three[3]=0;//this.four[3]=0;this.five[3]=1;
},
buildtwo(){//二號圖形
var i=this.i;varj=this.j;
if(this.xingtai===2){this.xingtai=0}
if(this.xingtai===0){
this.rectyi.node.x=j*60;this.rectyi.node.y=(i+1)*60;
this.recter.node.x=j*60;this.recter.node.y=i*60
this.rectsan.node.x=(j-1)*60;this.rectsan.node.y=i*60;
this.rectsi.node.x=(j-1)*60;this.rectsi.node.y=(i-1)*60;
this.jmix=j-1;this.jmax=j;
this.one[0]=i+1;this.two[0]=j; this.three[0]=0;//this.four[0]=1;this.five[0]=1;
this.one[1]=i; this.two[1]=j; this.three[1]=1;//this.four[1]=0;this.five[1]=1;
this.one[2]=i; this.two[2]=j-1;this.three[2]=0;//this.four[2]=1;this.five[2]=0;
this.one[3]=i-1;this.two[3]=j-1;this.three[3]=1;//this.four[3]=1;this.five[3]=1;
}
if(this.xingtai===0&&this.jmax===8){this.out=-1};//出圖的歸位
if(this.xingtai===1){
this.rectyi.node.x=j*60;this.rectyi.node.y=(i)*60;
this.recter.node.x=(j-1)*60;this.recter.node.y=(i+1)*60
this.rectsan.node.x=(j)*60;this.rectsan.node.y=(i+1)*60;
this.rectsi.node.x=(j+1)*60;this.rectsi.node.y=(i)*60;
this.jmix=j-1;this.jmax=j+1;
this.one[0]=i; this.two[0]=j; this.three[0]=0;//this.four[0]=1;this.five[0]=0;
this.one[1]=i+1;this.two[1]=j-1;this.three[1]=1;//this.four[1]=1;this.five[1]=0;
this.one[2]=i+1;this.two[2]=j; this.three[2]=0;//this.four[2]=0;this.five[2]=1;
this.one[3]=i; this.two[3]=j+1;this.three[3]=1;//this.four[3]=0;this.five[3]=1;
}
},
buildthree(){//三號
var i=this.i;varj=this.j;
if(this.xingtai===4){this.xingtai=0}
if(this.xingtai===0){
this.rectyi.node.x=(j-1)*60;this.rectyi.node.y=i*60;
this.recter.node.x=(j-1)*60;this.recter.node.y=(i+1)*60;
this.rectsan.node.x=(j)*60;this.rectsan.node.y=(i+1)*60;
this.rectsi.node.x=(j+1)*60;this.rectsi.node.y=(i+1)*60;
this.jmix=j-1;this.jmax=j+1;
this.one[0]=i; this.two[0]=j-1;this.three[0]=1;//this.four[0]=1;this.five[0]=1;
this.one[1]=i+1;this.two[1]=j-1;this.three[1]=0;//this.four[1]=1;this.five[1]=0;
this.one[2]=i+1;this.two[2]=j; this.three[2]=1;//this.four[2]=0;this.five[2]=0;
this.one[3]=i+1;this.two[3]=j+1;this.three[3]=1;//this.four[3]=0;this.five[3]=1;
}
if(this.xingtai===1){
this.rectyi.node.x=(j)*60;this.rectyi.node.y=(i+1)*60;
this.recter.node.x=(j+1)*60;this.recter.node.y=(i+1)*60;
this.rectsan.node.x=(j+1)*60;this.rectsan.node.y=(i)*60;
this.rectsi.node.x=(j+1)*60;this.rectsi.node.y=(i-1)*60;
this.jmix=j;this.jmax=j+1;
this.one[0]=i+1;this.two[0]=j; this.three[0]=1;//this.four[0]=1;this.five[0]=0;
this.one[1]=i+1;this.two[1]=j+1;this.three[1]=0;//this.four[1]=0;this.five[1]=1;
this.one[2]=i; this.two[2]=j+1;this.three[2]=0;//this.four[2]=1;this.five[2]=1;
this.one[3]=i-1;this.two[3]=j+1;this.three[3]=1;//this.four[3]=1;this.five[3]=1;
}
if(this.xingtai===2){
this.rectyi.node.x=(j+1)*60;this.rectyi.node.y=(i)*60;
this.recter.node.x=(j+1)*60;this.recter.node.y=(i-1)*60;
this.rectsan.node.x=(j)*60;this.rectsan.node.y=(i-1)*60;
this.rectsi.node.x=(j-1)*60;this.rectsi.node.y=(i-1)*60;
this.jmix=j-1;this.jmax=j+1;
this.one[0]=i; this.two[0]=j+1;this.three[0]=0;//this.four[0]=1;this.five[0]=1;
this.one[1]=i-1;this.two[1]=j+1;this.three[1]=1;//this.four[1]=0;this.five[1]=1;
this.one[2]=i-1;this.two[2]=j; this.three[2]=1;//this.four[2]=0;this.five[2]=0;
this.one[3]=i-1;this.two[3]=j-1;this.three[3]=1;//this.four[3]=1;this.five[3]=0;
}
if(this.xingtai===3){
this.rectyi.node.x=(j)*60;this.rectyi.node.y=(i-1)*60;
this.recter.node.x=(j-1)*60;this.recter.node.y=(i-1)*60;
this.rectsan.node.x=(j-1)*60;this.rectsan.node.y=(i)*60;
this.rectsi.node.x=(j-1)*60;this.rectsi.node.y=(i+1)*60;
this.jmix=j-1;this.jmax=j;
this.one[0]=i-1;this.two[0]=j; this.three[0]=1;
this.one[1]=i-1;this.two[1]=j-1;this.three[1]=1;
this.one[2]=i; this.two[2]=j-1;this.three[2]=0;
this.one[3]=i+1;this.two[3]=j-1;this.three[3]=0;
}
if(this.xingtai===1&&this.jmix===0){this.out=1};//出圖的歸位
if(this.xingtai===3&&this.jmax===9){this.out=-1};//出圖的歸位
},
buildfour(){//四號
var i=this.i;varj=this.j;
if(this.xingtai===4){this.xingtai=0}
if(this.xingtai===0){
this.rectyi.node.x=(j-1)*60;this.rectyi.node.y=i*60;
this.recter.node.x=(j-1)*60;this.recter.node.y=(i-1)*60
this.rectsan.node.x=(j)*60;this.rectsan.node.y=(i-1)*60;
this.rectsi.node.x=(j+1)*60;this.rectsi.node.y=(i-1)*60;
this.jmix=j-1;this.jmax=j+1;
this.one[0]=i ;this.two[0]=j-1;this.three[0]=0;
this.one[1]=i-1;this.two[1]=j-1;this.three[1]=1;
this.one[2]=i-1;this.two[2]=j; this.three[2]=1;
this.one[3]=i-1;this.two[3]=j+1;this.three[3]=1;
}
if(this.xingtai===1){
this.rectyi.node.x=(j)*60;this.rectyi.node.y=(i+1)*60;
this.recter.node.x=(j-1)*60;this.recter.node.y=(i+1)*60
this.rectsan.node.x=(j-1)*60;this.rectsan.node.y=(i)*60;
this.rectsi.node.x=(j-1)*60;this.rectsi.node.y=(i-1)*60;
this.jmix=j-1;this.jmax=j;
this.one[0]=i+1;this.two[0]=j ;this.three[0]=1;
this.one[1]=i+1;this.two[1]=j-1;this.three[1]=0;
this.one[2]=i ;this.two[2]=j-1;this.three[2]=0;
this.one[3]=i-1;this.two[3]=j-1;this.three[3]=1;
}
if(this.xingtai===2){
this.rectyi.node.x=(j+1)*60;this.rectyi.node.y=(i)*60;
this.recter.node.x=(j+1)*60;this.recter.node.y=(i+1)*60
this.rectsan.node.x=(j)*60;this.rectsan.node.y=(i+1)*60;
this.rectsi.node.x=(j-1)*60;this.rectsi.node.y=(i+1)*60;
this.jmix=j-1;this.jmax=j+1;
this.one[0]=i; this.two[0]=j+1;this.three[0]=1;
this.one[1]=i+1;this.two[1]=j+1;this.three[1]=0;
this.one[2]=i+1;this.two[2]=j; this.three[2]=1;
this.one[3]=i+1;this.two[3]=j-1;this.three[3]=1;
}
if(this.xingtai===3){
this.rectyi.node.x=(j+1)*60;this.rectyi.node.y=(i+1)*60;
this.recter.node.x=(j+1)*60;this.recter.node.y=(i)*60
this.rectsan.node.x=(j+1)*60;this.rectsan.node.y=(i-1)*60;
this.rectsi.node.x=(j)*60;this.rectsi.node.y=(i-1)*60;
this.jmix=j;this.jmax=j+1;
this.one[0]=i+1;this.two[0]=j+1;this.three[0]=0;
this.one[1]=i; this.two[1]=j+1;this.three[1]=0;
this.one[2]=i-1;this.two[2]=j+1;this.three[2]=1;
this.one[3]=i-1;this.two[3]=j; this.three[3]=1;
}
if(this.xingtai===3&&this.jmix===0){this.out=1};//出圖的歸位
if(this.xingtai===1&&this.jmax===9){this.out=-1};//出圖的歸位
},
buildfive(){//五號
var i=this.i;varj=this.j;
if(this.xingtai===2){this.xingtai=0}
if(this.xingtai===0){
this.rectyi.node.x=j*60;this.rectyi.node.y=i*60;
this.recter.node.x=j*60;this.recter.node.y=(i+1)*60
this.rectsan.node.x=(j+1)*60;this.rectsan.node.y=(i-1)*60;
this.rectsi.node.x=(j+1)*60;this.rectsi.node.y=(i)*60;
this.jmix=j;this.jmax=j+1;
this.one[0]=i; this.two[0]=j; this.three[0]=1;
this.one[1]=i+1;this.two[1]=j; this.three[1]=0;
this.one[2]=i-1;this.two[2]=j+1;this.three[2]=1;
this.one[3]=i; this.two[3]=j+1;this.three[3]=0;
}
if(this.xingtai===1){
this.rectyi.node.x=j*60;this.rectyi.node.y=i*60;
this.recter.node.x=(j+1)*60;this.recter.node.y=(i)*60
this.rectsan.node.x=(j)*60;this.rectsan.node.y=(i-1)*60;
this.rectsi.node.x=(j-1)*60;this.rectsi.node.y=(i-1)*60;
this.jmix=j-1;this.jmax=j+1;
this.one[0]=i; this.two[0]=j; this.three[0]=0;
this.one[1]=i; this.two[1]=j+1;this.three[1]=0;
this.one[2]=i-1;this.two[2]=j; this.three[2]=1;
this.one[3]=i-1;this.two[3]=j-1;this.three[3]=1;
}
if(this.xingtai===0&&this.jmix===0){this.out=1};//出圖的歸位
},
buildsix(){//六號
var i=this.i;varj=this.j;
if(this.xingtai===2){this.xingtai=0}
if(this.xingtai===0){
this.rectyi.node.x=j*60;this.rectyi.node.y=(i+1)*60;
this.recter.node.x=j*60;this.recter.node.y=(i)*60
this.rectsan.node.x=(j)*60;this.rectsan.node.y=(i-1)*60;
this.rectsi.node.x=(j)*60;this.rectsi.node.y=(i-2)*60;
this.jmix=j;this.jmax=j;
this.one[0]=i+1;this.two[0]=j;this.three[0]=0;
this.one[1]=i; this.two[1]=j;this.three[1]=0;
this.one[2]=i-1;this.two[2]=j;this.three[2]=0;
this.one[3]=i-2;this.two[3]=j;this.three[3]=1;
}
if(this.xingtai===1){
this.rectyi.node.x=j*60;this.rectyi.node.y=i*60;
this.recter.node.x=(j-1)*60;this.recter.node.y=(i)*60
this.rectsan.node.x=(j+1)*60;this.rectsan.node.y=(i)*60;
this.rectsi.node.x=(j-2)*60;this.rectsi.node.y=(i)*60;
this.jmix=j-2;this.jmax=j+1;
this.one[0]=i;this.two[0]=j; this.three[0]=1;
this.one[1]=i;this.two[1]=j-1;this.three[1]=1;
this.one[2]=i;this.two[2]=j+1;this.three[2]=1;
this.one[3]=i;this.two[3]=j-2;this.three[3]=1;
}
if(this.xingtai===0&&this.jmax===9){this.out=-1};//出圖的歸位
if(this.xingtai===0&&this.jmix===1){this.out=1};//出圖的歸位
if(this.xingtai===0&&this.jmix===0){this.out=2};//出圖的歸位
},
buildseven(){//七號
var i=this.i;varj=this.j;
if(this.xingtai===4){this.xingtai=0}
if(this.xingtai===0){
this.rectyi.node.x=j*60;this.rectyi.node.y=i*60;
this.recter.node.x=(j-1)*60;this.recter.node.y=(i)*60
this.rectsan.node.x=(j+1)*60;this.rectsan.node.y=(i)*60;
this.rectsi.node.x=(j)*60;this.rectsi.node.y=(i+1)*60;
this.jmix=j-1;this.jmax=j+1;
this.one[0]=i; this.two[0]=j; this.three[0]=1;
this.one[1]=i; this.two[1]=j-1;this.three[1]=1;
this.one[2]=i; this.two[2]=j+1;this.three[2]=1;
this.one[3]=i+1;this.two[3]=j; this.three[3]=0;
}
if(this.xingtai===1){
this.rectyi.node.x=j*60;this.rectyi.node.y=i*60;
this.recter.node.x=(j+1)*60;this.recter.node.y=(i)*60;
this.rectsan.node.x=(j)*60;this.rectsan.node.y=(i-1)*60;
this.rectsi.node.x=(j)*60;this.rectsi.node.y=(i+1)*60;
this.jmix=j; this.jmax=j+1;
this.one[0]=i; this.two[0]=j; this.three[0]=0;
this.one[1]=i; this.two[1]=j+1;this.three[1]=1;
this.one[2]=i-1;this.two[2]=j; this.three[2]=1;
this.one[3]=i+1;this.two[3]=j; this.three[3]=0;
}
if(this.xingtai===2){
this.rectyi.node.x=j*60;this.rectyi.node.y=i*60;
this.recter.node.x=(j+1)*60;this.recter.node.y=(i)*60;
this.rectsan.node.x=(j-1)*60;this.rectsan.node.y=(i)*60;
this.rectsi.node.x=(j)*60;this.rectsi.node.y=(i-1)*60;
this.jmix=j-1;this.jmax=j+1;
this.one[0]=i; this.two[0]=j; this.three[0]=0;
this.one[1]=i; this.two[1]=j+1;this.three[1]=1;
this.one[2]=i; this.two[2]=j-1;this.three[2]=1;
this.one[3]=i-1;this.two[3]=j; this.three[3]=1;
}
if(this.xingtai===3){
this.rectyi.node.x=j*60;this.rectyi.node.y=i*60;
this.recter.node.x=(j)*60;this.recter.node.y=(i+1)*60;
this.rectsan.node.x=(j-1)*60;this.rectsan.node.y=(i)*60;
this.rectsi.node.x=(j)*60;this.rectsi.node.y=(i-1)*60;
this.jmix=j-1;this.jmax=j;
this.one[0]=i ;this.two[0]=j; this.three[0]=0;
this.one[1]=i+1;this.two[1]=j; this.three[1]=0;
this.one[2]=i; this.two[2]=j-1;this.three[2]=1;
this.one[3]=i-1;this.two[3]=j; this.three[3]=1;
}
if(this.xingtai===1&&this.jmix===0){this.out=1};//出圖的歸位
if(this.xingtai===3&&this.jmax===9){this.out=-1};//出圖的歸位
},
6.4鍵盤監聽,控制圖片的移動和旋轉,和觸控監聽
onKeyDown (event) {
switch(event.keyCode) {
casecc.KEY.a:
casecc.KEY.left:
if(this.jmix>=1){
this.sidemath();
this.leftside();
this.choose();
}
break;
casecc.KEY.d:
casecc.KEY.right:
if(this.jmax<=8){
this.sidemath();
this.rightside();
this.choose();
}
break;
casecc.KEY.w:
casecc.KEY.up:
this.j+=this.out;
this.choose();
varorixingtai=this.xingtai;
cc.log('變換前的形態'+this.xingtai);
this.xingtai++;
this.choose();
//檢查有沒有重合
for(leti=0;i<4;i++){
if(this.box[this.one[i]][this.two[i]]===1){
cc.log('檢查重合');
this.xingtai=orixingtai;
this.j-=this.out;
this.choose();
cc.log('返回前一步');
}
}
this.out=0;
break;
}
},
觸控監聽程式碼
ontouchmove(){
var self =this;
self.node.on(cc.Node.EventType.TOUCH_START, function (event) {
var touches= event.getTouches();
vartouchLoc = touches[0].getLocation();
self.touchx=touchLoc.x;
}, self.node);
self.node.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
var touches= event.getTouches();
var touchLoc = touches[0].getLocation();
}, self.node);
self.node.on(cc.Node.EventType.TOUCH_END, function (event) {
cc.log('觸控結束')
cc.log('觸控起始點'+self.touchx)
var touches= event.getTouches();
vartouchLoc = touches[0].getLocation();
cc.log('觸控結束點'+touchLoc.x)
if(self.touchx===touchLoc.x){
self.j+=self.out;
self.choose();
varorixingtai=self.xingtai;
self.xingtai++;
self.choose();
//檢查有沒有重合
for(leti=0;i<4;i++){
if(self.box[self.one[i]][self.two[i]]===1){
self.xingtai=orixingtai;
self.j-=self.out;
self.choose();
}
}
self.out=0;
}
if(self.touchx<touchLoc.x){
if(self.jmax<=8){
self.sidemath();
self.rightside();
self.choose();
}
}
if(self.touchx>touchLoc.x){
if(self.jmix>=1){
self.sidemath();
self.leftside();
self.choose();
}
}
}, self.node);
},
6.5邊界碰撞檢測
由於邊界碰撞檢測前文提及沒有規範陣列橫向座標。使用了畫素座標點,預儲存在程式碼中,同時,旋轉出界的檢測判定,由於旋轉中心點選擇合理,計算量少,也做了預先儲存操作。使用的是左側補充偏移量,右側減少偏移量的方法,重製迴游戲區域中。這之中用到了this.xingtai同一圖片的旋轉型別、 this.out出界偏移量 、this.xmix最大邊界、this.xmin最小邊界等全域性變數。在預儲存的程式碼中可以查詢到。
6.6下落檢測
check(){
for(let i=0;i<this.one.length;i++){
if(this.three[i]===1){
if(this.box[this.one[i]-1][this.two[i]]===1){
this.box[this.one[0]][this.two[0]]=1;
this.box[this.one[1]][this.two[1]]=1;
this.box[this.one[2]][this.two[2]]=1;
this.box[this.one[3]][this.two[3]]=1;
this.rectyi.node.name =this.one[0].toString()+this.two[0].toString();
//cc.log('節點名:'+this.rectyi.node.name);
this.recter.node.name =this.one[1].toString()+this.two[1].toString();
//cc.log('節點名:'+this.recter.node.name );
this.rectsan.node.name=this.one[2].toString()+this.two[2].toString();
//cc.log('節點名:'+this.rectsan.node.name);
this.rectsi.node.name =this.one[3].toString()+this.two[3].toString();
//cc.log('節點名:'+this.rectsi.node.name);
this.unschedule(this.down);
this.setcolour();
break;//防止以上三個用法被多次迴圈呼叫
}
}
}
this.cleancheck();
//this.one.length=0;
//this.two.length=0;
//this.three.length=0;
this.arry.length=0;
},
6.7左右移動檢測
sidemath(){//除重:i
var num=0;
this.arry[0]=this.one[0];
for(leti=1;i<4;i++){
for(letj=0;j<this.arry.length;j++){
if(this.arry[j]!==this.one[i]){
num++
if(num===this.arry.length){
this.arry.push(this.one[i]);//後期有一個歸0操作
}
}
}
num=0;
}
},
leftside(){
var num=0;
var mix=100;
for(leti=0;i<this.arry.length;i++){
for(letj=0;j<4;j++){
if(this.arry[i]===this.one[j]){
mix=Math.min(mix,this.two[j]);
}
}
if(this.box[this.arry[i]][mix-1]!==1){
num++//成立才可以左移
}
mix=100;
}
if(this.arry.length===num){
this.j--;
}
},
rightside(){
var num=0
var max=-1;
for(leti=0;i<this.arry.length;i++){
for(letj=0;j<4;j++){
if(this.arry[i]===this.one[j]){
max=Math.max(max,this.two[j]);
}
}
if(this.box[this.arry[i]][max+1]!==1){
num++
//成立才可以右移
}
max=-1;
}
if(this.arry.length===num){
this.j++;
}
},
6.8旋轉歸位檢測
for(let i=0;i<4;i++){
if(this.box[this.one[i]][this.two[i]]===1){
cc.log('檢查重合');
this.xingtai=orixingtai;
this.j-=this.out;
this.choose();
cc.log('返回前一步');
}
}
ui關聯、得分等一系列function
//ui
gameover(){
for(letj=0;j<10;j++){
if(this.box[20][j]===1){
cc.audioEngine.stop(this.audio);
this.gamestate=0;
this.over.active=true;
this.gamestype();
}
}
},
regame(){
cc.director.loadScene("russsia");
},
addscore(){
this.scorenum+=100;
this.score.string=this.scorenum;
},
drawnext(){
this.nextgoal=Math.floor(7*Math.random());
varnext=cc.find('Canvas/kuang1/shownext/next').getComponent('shownext');
next.init(this.nextgoal);
},
gamestype(){
if(this.gamestate===1){
var self =this;
cc.loader.loadRes('play',cc.SpriteFrame,function(err, spriteFrame){
self.button.getComponent(cc.Sprite).spriteFrame = spriteFrame;
});
self.gamestate=0;
self.schedule(self.down,self.speed);//速度
}elseif(this.gamestate===0){
var self =this;
cc.loader.loadRes('stop',cc.SpriteFrame,function(err, spriteF){
self.button.getComponent(cc.Sprite).spriteFrame = spriteF;
});
self.gamestate=1;
self.unschedule(self.down);
}
},
movespeed(){
this.speed=0.2+0.8*this.sliderv.progress;
}
6.9移動時降落反應的延遲導致重疊檢
for(let i=0;i<4;i++){
if(this.box[this.one[i]][this.two[i]]===1){
this.i++;
this.choose();
}
}
最後自己總結下:7種基本圖形。19種旋轉。做好這19個圖形,對19個圖形做好遊戲控制和操作,管理到每個小方塊,做好消行的準備,其實俄羅斯方塊遊戲就出來啦~
感覺自己好不負責任。。
連結: https://pan.baidu.com/s/1pL1yEMn 密碼: 8pwf