久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長(zhǎng)資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

動(dòng)手打造html5俄羅斯方塊的(圖文)

在正文開(kāi)始之前還要啰嗦一下,標(biāo)題中所謂自給自足,是在沒(méi)有參考任何設(shè)計(jì)思路的前提下去開(kāi)發(fā)這游戲的,你可能會(huì)不解,如果參考優(yōu)秀的思路,豈不是事半功倍,當(dāng)然,參考與不參考都有利,我只說(shuō)不參考的利,當(dāng)我煞費(fèi)苦心、歷經(jīng)數(shù)十個(gè)BUG修改,終于完成一件作品的時(shí)候,我可以很自豪地對(duì)別人說(shuō):“看,我開(kāi)發(fā)的游戲!”當(dāng)然,創(chuàng)意不是我的,但這并不影響自己那份“虛榮心”,為一款經(jīng)典的游戲賦予自我的理解,并將它融入游戲中,豈不是一件有意思的事,而且,回過(guò)頭來(lái)再看一看別人的思路,有時(shí)會(huì)拍案而起,“這個(gè)我當(dāng)初怎么就沒(méi)想到呢?”,“原來(lái)這個(gè)問(wèn)題可以這樣解決”,“這個(gè)設(shè)計(jì)思路比我的思路好多了!”,諸如此類(lèi)總比開(kāi)始就直接看別人的思路而阻塞自己的思考要強(qiáng)得多,對(duì)吧?

好叻,正文開(kāi)始~

想先看效果的,先跳轉(zhuǎn)試玩一下吧!

俄羅斯方塊,主游戲界面應(yīng)該由一個(gè)一個(gè)的方塊組成,如下圖,當(dāng)然成品里面這些網(wǎng)格是看不到的,這里只是助于理解,主界面尺寸為400×500,設(shè)定每塊磚(網(wǎng)格)的尺寸為20×20,則每行有20個(gè)磚塊,每列有25個(gè)磚塊。相關(guān)代碼:

brickWidth = 20,    //磚塊大小  width = 400, height = 500;  //畫(huà)布寬高,20X25

動(dòng)手打造html5俄羅斯方塊的(圖文)

提到主界面的網(wǎng)格,就要提到一個(gè)非常重要的變量了,它就是BOARD,一個(gè)二維數(shù)組,形象化地說(shuō)其尺寸是20×26,存儲(chǔ)的值為0或1,0表示該位置沒(méi)有磚塊,1表示該位置有磚塊,在接下來(lái)的一些判定中有重要作用,游戲細(xì)心的同學(xué)可能發(fā)現(xiàn),為什么是20×26,而不是對(duì)應(yīng)主界面網(wǎng)格的20×25,我在一開(kāi)始的時(shí)候也是設(shè)定為20×25的,后來(lái)注意到如果加一行而且這一行的值都為1就可以很容易判斷磚塊是否到觸及主界面底部了。相關(guān)代碼:

// 初始化BOARD,注意縱向有26個(gè),最后一排用來(lái)判斷是否觸底  for(i=0;i<20;i++){      BOARD[i] = [];      for(j=0;j<26;j++) {          if(j==25) {              BOARD[i][j] = 1          } else {              BOARD[i][j] = 0;          }      }  }

動(dòng)手打造html5俄羅斯方塊的(圖文)

接下來(lái)看由4個(gè)磚塊組成的“形狀”,有五種,為了好描述,我把它們?yōu)閯e命名,Tian(田),Chu(鋤頭),Tu(凸起來(lái)),Thunder(閃電),Line(一橫),哈哈有趣的名字,原諒我沒(méi)找到它們的英文名字吧。

首先定義一個(gè)磚頭類(lèi)Brick:

function Brick() { }

其下有幾個(gè)原型變量和方法:

Brick.prototype.embattle = null;    //磚塊的布局(需重載)  Brick.prototype.isOverturn = 0; //是否翻轉(zhuǎn)  Brick.prototype.originX = 9;    //磚頭的繪制起點(diǎn)X  Brick.prototype.originY = -3;    //磚頭的繪制起點(diǎn)Y  Brick.prototype.direction = 0;  //磚頭朝向  Brick.prototype.autoMoveTimer = null;   //自動(dòng)移動(dòng)計(jì)時(shí)器  Brick.prototype.draw = function() { …… }    //畫(huà)磚塊的方法  Brick.prototype.move = function(moveX, moveY) { …… }    //移動(dòng)的方法  Brick.prototype.autoMove = function() { …… }    //自動(dòng)移動(dòng)的方法  Brick.prototype.change = function() { …… }    //變換磚頭朝向

Brick的子類(lèi)有:Tian,Chu,Tu,Thunder,Line五個(gè),每個(gè)子類(lèi)中都重載Brick的embattle變量,embattle是什么,英譯中的意思是布陣,這個(gè)陣是個(gè)什么陣呢?首先,同學(xué)們要理解我的思路,用Tu的embattle來(lái)舉例,其代碼如下:

this.embattle = [      [ [0,4,5,8], [1,4,5,6], [1,4,5,9], [0,1,2,5] ],  //布局表為4X4表格,數(shù)字為磚頭位置      [ [0,4,5,8], [1,4,5,6], [1,4,5,9], [0,1,2,5] ]   //次行為翻轉(zhuǎn)的情況];

embattle是一個(gè)三維數(shù)組,第一維是是否翻轉(zhuǎn)isOverturn(形象來(lái)說(shuō)就像圖片的水平翻轉(zhuǎn)),第二維是方向direction(上左下右),第三維是形狀的4個(gè)磚塊分布情況,我把每個(gè)新形狀對(duì)象定義在一個(gè)4×4的陣中,例如,Tu的this.embattle[0][0]為[0,4,5,8],數(shù)字即該磚塊的所在位置,如下圖:

動(dòng)手打造html5俄羅斯方塊的(圖文)

所以要確定一個(gè)形狀的位置和樣子,需要isOverturn確定是否翻轉(zhuǎn),需要direction確定其方向,需要originX和originY確定“陣”的位置。

接下來(lái),分別解釋Brick的4個(gè)原型方法。

Brick.prototype.draw

ctx.fillStyle = 'rgb('+Math.floor(Math.random()*256)+','+Math.floor(Math.random()*256)+',  '+Math.floor(Math.random()*256)+')';  for(i=0;i<4;i++) {      tmp = this.embattle[this.isOverturn][this.direction][i];      ctx.fillRect((this.originX+tmp%4)*brickWidth, (this.originY+Math.floor(tmp/4))*brickWidth, brickWidth, brickWidth);      ctx.strokeRect((this.originX+tmp%4)*brickWidth+1, (this.originY+Math.floor(tmp/4))*brickWidth+1, brickWidth-2, brickWidth-2);   //注意+1和減2  }

有上面說(shuō)的確定形狀的位置和樣子的方法,之后就是純粹canvas畫(huà)圖,4個(gè)磚塊一個(gè)一個(gè)地畫(huà),不要看代碼很長(zhǎng)其實(shí)就是那么一點(diǎn)點(diǎn),originX、originY和磚塊在陣中的位置就可以確定畫(huà)磚塊的起點(diǎn)了。注意到代碼的注釋了沒(méi)有,畫(huà)邊框的時(shí)候,它是從起點(diǎn)向外面畫(huà)的,就像我把一個(gè)塑料袋套在另一個(gè)塑料袋的外面,為了以后的清除的方便且不影響其他的磚塊,把邊框畫(huà)進(jìn)fillRect的領(lǐng)土,就像我現(xiàn)在把這個(gè)塑料袋不套在外面而是放進(jìn)這另一個(gè)塑料袋里面一樣,就這個(gè)意思。

Brick.prototype.move

這是最長(zhǎng)的一個(gè)了,移動(dòng)的時(shí)候,moveX和moveY表示橫縱的增量,沒(méi)有同時(shí)非0的情況(這是人為的設(shè)定,要么橫向移動(dòng)要么縱向移動(dòng)),當(dāng)然要判斷即將移動(dòng)到的位置是否違規(guī):

橫向:

如果陣貼靠主界面左側(cè)則不能向左移即moveX不能為-1

(this.originX==0 && moveX==-1)

判斷右邊時(shí)比較麻煩,因?yàn)椴荒苤苯佑藐噥?lái)判斷是否貼靠右側(cè)(看前面的圖就知道陣的右邊和下邊可能沒(méi)有磚塊的),這時(shí)要一個(gè)個(gè)地判斷4個(gè)磚塊是否有至少有一個(gè)在最右,這時(shí)不能向右移動(dòng)

|| (this.originX+tmp[0]%4==19 && moveX==1)  || (this.originX+tmp[1]%4==19 && moveX==1)  || (this.originX+tmp[2]%4==19 && moveX==1)  || (this.originX+tmp[3]%4==19 && moveX==1)

最后還要判斷即將到達(dá)的位置是否已經(jīng)有磚塊了。

|| (BOARD[this.originX+tmp[0]%4+moveX][this.originY+Math.floor(tmp[0]/4)]==1)  || (BOARD[this.originX+tmp[1]%4+moveX][this.originY+Math.floor(tmp[1]/4)]==1)  || (BOARD[this.originX+tmp[2]%4+moveX][this.originY+Math.floor(tmp[2]/4)]==1)  || (BOARD[this.originX+tmp[3]%4+moveX][this.originY+Math.floor(tmp[3]/4)]==1)

縱向:

即將到達(dá)的位置是否已經(jīng)有磚塊了,注意到下面的代碼的&& moveX==0,原來(lái)是沒(méi)有的,后來(lái)發(fā)現(xiàn)每次磚塊怎么剛剛靠上下面堆著的磚塊就不能再移動(dòng)了,原來(lái)橫向移動(dòng)的時(shí)候也進(jìn)行了這個(gè)判斷,即剛剛靠上下面的磚塊,如果這時(shí)想左右移動(dòng),但下方有磚塊,但是問(wèn)題來(lái)了,下面有沒(méi)有磚塊跟我左右移動(dòng)有什么關(guān)系呢?是吧。

if((as==1 || bs==1 || cs==1 || ds==1) && moveX==0) { …… }

縱向終止判斷里面主要做了幾件事:清除autoMoveTimer,設(shè)置BOARD在該形狀當(dāng)前位置的值為1,有可以消除的整行就消除,加分改分,判斷勝利/失敗,刪除當(dāng)前對(duì)象,召喚下一個(gè)形狀。

橫縱都沒(méi)違規(guī)時(shí):

這時(shí),把該形狀前一個(gè)位置的磚塊清除,更新originX和originY,再畫(huà)出來(lái)。

for(i=0;i<4;i++) {      tmp = this.embattle[this.isOverturn][this.direction][i];      ctx.clearRect((this.originX+tmp%4)*brickWidth, (this.originY+Math.floor(tmp/4))*brickWidth, brickWidth, brickWidth);  }  this.originX += moveX;  this.originY += moveY;  this.draw();

Brick.prototype.autoMove

只做一件事,設(shè)置計(jì)時(shí)器,定時(shí)向下移動(dòng)。

var status, self = this;this.autoMoveTimer = setInterval(function() {      status = self.move(0,1);  },speed);

Brick.prototype.change

改變形狀的朝向,很好辦啊,不是有embattle數(shù)組了嗎?當(dāng)然沒(méi)有那么簡(jiǎn)單,不只是換個(gè)數(shù)組這么簡(jiǎn)單。要考慮改變方向之后占用的位置是否已經(jīng)有磚塊了,如果形狀是貼著主界面右邊界就更糟糕了,比如原來(lái)是豎著的Line,改變其方向變?yōu)闄M,占用陣的0、1、2、3,如果Line貼著右邊界,originX為19,變?yōu)闄M向,占用陣的0、1、2、3,后面三個(gè)磚塊已經(jīng)溢出了主界面。

動(dòng)手打造html5俄羅斯方塊的(圖文)

解決方案是:如果有越界的磚塊就把陣往左挪一挪,直到不再越界。

while(ox+tmp[0]%4 > 19 || ox+tmp[1]%4 > 19 || ox+tmp[2]%4 > 19 || ox+tmp[3]%4 > 19) {      ox -= 1;  }

最后,如果都沒(méi)事,就可以清除原位置,畫(huà)出改變方向之后的形狀了。

并不是太完美,因?yàn)橛行┛ㄎ坏那闆r沒(méi)考慮進(jìn)來(lái),什么是卡位,看下圖,你知道Line實(shí)例調(diào)用change方法的結(jié)果是什么了嗎?事實(shí)上,它不應(yīng)該成功改變方向的,對(duì)吧?還有其他一些卡位的情況。

動(dòng)手打造html5俄羅斯方塊的(圖文)

Brick的4個(gè)原型方法就介紹到這里了。現(xiàn)在如果我要在右邊的信息界面顯示下一個(gè)的形狀,最直接的方法就是,通過(guò)該形狀的構(gòu)造函數(shù)實(shí)例化一個(gè)對(duì)象,為防止其自動(dòng)調(diào)用autoMove,為構(gòu)造函數(shù)添加了isModel來(lái)判斷是不是供提示用的。

還有按鍵事件監(jiān)聽(tīng)、NextBrick函數(shù)和deleteObj自己看看吧,很容易看懂,游戲的入口就是NextBrick函數(shù)。

還有就是,我無(wú)法確定deleteObj是否真的成功讓GC把對(duì)象回收了。

還有就是,我本想增加關(guān)卡功能,因?yàn)榭梢宰杂稍O(shè)置速度(speed變量),就把這功能放一放了。

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
成人国产精品| 亚洲精华国产欧美| 综合视频一区| 蜜臀av性久久久久蜜臀aⅴ四虎| 国产精品专区免费| 国产一区二区三区日韩精品| 精品国产一区二| 国产一区二区三区久久| 久久婷婷国产| 国产一区二区三区日韩精品| 91亚洲国产高清| 欧美成人基地| 婷婷六月综合| 天堂av在线一区| 亚洲精品乱码日韩| 国产亚洲欧美日韩精品一区二区三区| 欧美天堂一区二区| 国产精品第一国产精品| 精品入口麻豆88视频| 国产一区二区三区四区五区 | 国产午夜精品一区在线观看| 欧美三区不卡| 国模大尺度视频一区二区| 天堂中文av在线资源库| 91精品国产91久久久久久黑人| 99精品在线观看| 久久夜色精品| 欧美黑人做爰爽爽爽| 日韩国产欧美| 老司机久久99久久精品播放免费| 91精品国产自产观看在线| 精品一区不卡| 桃色一区二区| 日韩视频久久| 日韩视频1区| 美日韩一区二区三区| 日韩在线二区| 免费人成黄页网站在线一区二区| 国产精品一区亚洲| 亚洲精品**中文毛片| 亚洲欧美日本国产专区一区| 91午夜精品| 日韩毛片视频| 亚洲久草在线| 国产在线看片免费视频在线观看| 亚洲欧美日本日韩| 久久精品一区二区国产| 久久免费大视频| 亚州欧美在线| 国产综合色区在线观看| 综合五月婷婷| 首页国产精品| 亚洲欧洲日韩精品在线| 热三久草你在线| 亚洲精品三级| 日韩精品网站| 国产日韩欧美一区| 亚洲高清激情| 国产精品亚洲四区在线观看 | 日本大胆欧美人术艺术动态| 欧美日韩亚洲一区在线观看| 99久久精品网| 国产日产精品_国产精品毛片| 久久精品免费一区二区三区| 日韩高清中文字幕一区| 日韩在线观看不卡| 欧美视频精品全部免费观看| 国产高清一区| 久久久久伊人| 天堂俺去俺来也www久久婷婷| 秋霞影院一区二区三区| 国产精品一区免费在线| 亚洲激情不卡| 在线天堂资源www在线污| 日韩精品视频一区二区三区| 香蕉久久99| 久久精品凹凸全集| 久久免费福利| 久久成人一区| 国产美女高潮在线| 欧美日韩亚洲一区在线观看| 精品91久久久久| 视频在线观看一区二区三区| 日韩欧美网址| 欧美国产另类| 日韩国产一区二| 99视频在线精品国自产拍免费观看| 国产日韩欧美一区二区三区 | 欧美一区二区三区久久| 黄色日韩在线| 日韩一区二区在线免费| 老司机精品视频网| 91精品国产一区二区在线观看| 亚洲精品中文字幕乱码| 国产精品久久久久久久久妇女| 欧美在线精品一区| 在线视频免费在线观看一区二区| 欧美sm一区| 精品精品国产三级a∨在线| 日本成人手机在线| 91九色精品国产一区二区| 日韩精品欧美| 日韩黄色大片网站| 国产欧洲在线| 97精品国产| 精品国产一区二| 久久精品国产久精国产爱| 久久国产欧美日韩精品| 日韩一区二区三区高清在线观看| 视频一区二区三区在线| 亚洲免费精品| 国产模特精品视频久久久久| 欧美~级网站不卡| 天堂√中文最新版在线| 久久精品系列| 国产三级一区| 久久精品xxxxx| 青青伊人久久| 国产欧美日韩精品一区二区三区| 日日夜夜免费精品| 日本精品国产| 国产精选久久| 欧美1区2区3| 狠狠久久伊人| a天堂资源在线| 日韩欧美一区二区三区在线视频 | 伊人成人在线视频| 国产韩日影视精品| 亚洲一区二区三区免费在线观看| 香蕉国产精品| 亚洲资源av| 亚洲综合图色| 日韩av一区二| 国产精品亚洲综合久久| 精品久久久网| 视频二区不卡| 蜜桃成人av| 日韩一区精品字幕| 日韩不卡手机在线v区| 国产三级一区| 久久不见久久见免费视频7| 久久99久久人婷婷精品综合| 精品国产网站| 99久久夜色精品国产亚洲1000部| 亚洲精品在线观看91| 蜜臀av亚洲一区中文字幕| 欧美综合精品| 日本一区二区高清不卡| 另类中文字幕国产精品| av一区二区高清| 亚洲精品动态| 国产精品成人3p一区二区三区| 国产一区二区亚洲| 国产91久久精品一区二区| 午夜一级在线看亚洲| 亚洲精品观看| 精品一区二区三区视频在线播放| 午夜欧美巨大性欧美巨大| 美女精品在线| 国产精品毛片久久久| 国产网站在线| 老鸭窝亚洲一区二区三区| 91精品啪在线观看国产爱臀| 精品精品99| 一区二区自拍| 国产精品丝袜在线播放| 特黄毛片在线观看| 亚洲免费一区三区| 日韩av在线播放网址| 精品一区三区| 亚洲精品影视| 岛国av免费在线观看| 午夜宅男久久久| 欧美1区2区3| 一区在线免费| 久久影院资源站| 一区免费视频| 麻豆91在线播放| 国产精品免费看| 国产精品第一| 久久高清国产| 国产一区不卡| 日韩中文字幕不卡| 精品视频一区二区三区四区五区| 欧美特黄一级大片| 日韩欧美中文在线观看| 国产一区精品福利| 亚洲资源网站| 日韩av免费| 欧美日本久久| 日韩一区二区免费看| 你懂的国产精品| 蜜桃91丨九色丨蝌蚪91桃色| 色婷婷色综合| 日韩高清电影一区| 久久精品亚洲人成影院| 国产激情久久| 欧美中文日韩| 日韩精品不卡一区二区| 欧美日韩一区二区三区在线电影|