亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > HTML > 正文

canvas實(shí)現(xiàn)俄羅斯方塊的方法示例

2024-08-26 00:21:12
字體:
供稿:網(wǎng)友

好久沒使用canvas了,于是通過寫小游戲“俄羅斯方塊”再次熟悉下canvas,如果有一定的canvas基礎(chǔ),要實(shí)現(xiàn)還是不難的。

原理詳解

看游戲最終界面,可知需要實(shí)現(xiàn)以下關(guān)鍵功能:

  • 游戲面板,也就是12 * 20的方格,以及是否填充了方塊信息;
  • 運(yùn)動(dòng)方塊,方塊需要實(shí)現(xiàn)移動(dòng),變形的功能。 
     

 canvas,俄羅斯方塊

界面的實(shí)現(xiàn)

整個(gè)面板就是以左上角(0,0)為原點(diǎn)的坐標(biāo)系,右上角(12,0)左下角(0,20)右下角(12,20),每個(gè)點(diǎn)的坐標(biāo)位置都可以確定。是否已經(jīng)填充方塊,我們可以將每個(gè)方格看成一個(gè)數(shù)組元素,0表示沒有,1表示已經(jīng)填充。12 * 20 的面板使用兩層數(shù)組,即用20個(gè)長度為12的數(shù)組實(shí)現(xiàn)。

var maps = [[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,1,0,1,0], ...];

畫出面板的代碼,用最基礎(chǔ)的canvas的api就能實(shí)現(xiàn)

//格子    for(var i=0;i<12;i++){        for(var j=0;j<20;j++){            ctx.fillRect(i*40,j*40,40,40);            ctx.strokeRect(i*40,j*40,40,40);            if(this.maps[j][i]==1){//方格已經(jīng)有填充內(nèi)容                ctx.save();                ctx.lineWidth=4;                ctx.fillStyle='hsla(200,100%,50%,.5)';                ctx.strokeStyle='hsla(200,100%,50%,.9)';                ctx.fillRect(i*40,j*40,40,40);                ctx.strokeRect(i*40+2,j*40+2,38,38);                ctx.restore();            }        }    }    //邊框    ctx.lineWidth=4;    ctx.strokeStyle='hsla(0,100%,0%,.3)';    ctx.moveTo(0,0);    ctx.lineTo(0,20*40);    ctx.lineTo(12*40,20*40);    ctx.lineTo(12*40,0);    ctx.stroke();    ctx.restore();

方塊的實(shí)現(xiàn)

游戲中用到以下 7 種圖形

canvas,俄羅斯方塊

結(jié)合上面介紹的坐標(biāo)系,數(shù)組 [x1, y1, x2, y2, x3, y3, x4, y4] 就是上面圖形中4個(gè)點(diǎn)坐標(biāo)的數(shù)據(jù)表現(xiàn)形式,7 種圖形的坐標(biāo)分別如下:

var Arr = [[4,0,4,1,5,1,6,1],[4,1,5,1,6,1,6,0],[4,0,5,0,5,1,6,1],[4,1,5,0,5,1,6,0],[5,0,4,1,5,1,6,1],[4,0,5,0,6,0,7,0],[5,0,6,0,5,1,6,1]];

方塊的移動(dòng),遍歷整個(gè)數(shù)組,加上位移向量就行,非常簡單

class Shape {    constructor(m){        this.m = Object.assign([],m);    }    move(x,y){ // 位移        var m = this.m,            l = m.length;        y = y||0;        for (var i=0;i<l;i=i+2){            m[i]+=x;            m[i+1]+=y;        }        return this;    }

方塊的旋轉(zhuǎn),俄羅斯方塊里面方塊除了左右和上下運(yùn)動(dòng),還會(huì)旋轉(zhuǎn),不是嗎?稍微思考下就知道,這不過就是矩陣變換而已,也就是每次圖形繞中心點(diǎn)旋轉(zhuǎn)90度。我這里用數(shù)組第三個(gè)點(diǎn)作為圖形變換的中心點(diǎn),當(dāng)然這樣處理不夠完善。

class Shape {    transform(){//二維矩陣變換        var m =this.m,            l = m.length,            c = Math.ceil(l/2),            x = m[c],            y = m[c+1],            cos = Math.cos(Math.PI/180 * 90),            sin = Math.sin(Math.PI/180 * 90);        for (var i=0;i<l;i=i+2){            if(i == c) continue;            var mx = m[i]- x,                my = m[i+1] - y,                nx = mx*cos - my*sin,                ny = my*cos + mx*sin;            m[i]=x+nx;            m[i+1]=y+ny;        }        return this;        }

邊界條件

主要包括如下三個(gè)方面

  • 方塊位置不能超出界面的判斷;
  • 方塊到達(dá)底部或放置完成的判斷;
  • 游戲結(jié)束的判斷。

遍歷數(shù)組 (1)任意一個(gè)點(diǎn)y坐標(biāo)為19時(shí)表示到達(dá)了底部;(2)獲取該坐標(biāo)的y+1位置在maps的信息,如果為1表示已經(jīng)填充。這兩種情況下,運(yùn)動(dòng)方塊的周期結(jié)束,將該方塊的坐標(biāo)填充到maps對(duì)應(yīng)的數(shù)組里面即可。

如果坐標(biāo)的y+1已經(jīng)有填充,同時(shí)當(dāng)前坐標(biāo)小于1,即已經(jīng)在界面的頂部了,那么表示游戲結(jié)束。

var isEnd = false,isOver=false,x,y;for(var i=0,sl=that.shape.m.length;i<sl;i=i+2){    x=that.shape.m[i];    y=that.shape.m[i+1];    if(y >= 19){ // 到了底部        isEnd = true;break;    }    if(that.maps[y+1][x]==1){ // y+1位置已經(jīng)填充        isEnd = true;        if(y <= 1){isOver=true;} // 游戲結(jié)束        break;    }}

方塊運(yùn)動(dòng)周期結(jié)束時(shí)檢測每一層是否滿格,以及滿格后的處理。某項(xiàng)數(shù)組全部元素都為1則表示已經(jīng)滿格,那么刪除該項(xiàng)數(shù)組,同時(shí)列表頭再壓入一項(xiàng)每個(gè)元素都為0的數(shù)組即可。

checkPoint(){    var that = this,        maps = that.maps;    for(var i=0,l=maps.length;i<l;i++){        if(Math.min.apply(null,maps[i]) == 1){// 表示該層已經(jīng)滿格            that.maps.splice(i,1);            that.score+=10; // 增加分?jǐn)?shù)            that.maps.unshift([0,0,0,0,0,0,0,0,0,0,0,0]);        }    }    return this;}

綁定事件

主要就是綁定keydown事件,要注意的是左移和右移事件包括了邊界判斷

bindEvent(){    var that = this;    document.addEventListener('keydown',function(e){        switch(e.keyCode){            case 13:        //enter                cancelAnimationFrame(that.timer);                that.init().update();            break;            case 80:        //p                that.pause = !that.pause;                break;              case 40:        //down                that.d = 0.5;                break;            case 37:        //left                var over = false,                    maps = that.maps,                    shape = that.shape,                    m = shape.m;                for(var i=0,l=m.length;i<l;i=i+2){                    if(m[i]<=0 || maps[m[i+1]][m[i]-1] == 1){                        over = true;break;                    }                }                if(!over) shape.move(-1,0);                break;            case 39:        //right                var over = false,                    shape = that.shape,                    maps = that.maps,                    m = shape.m;                for(var i=0,l=m.length;i<l;i=i+2){                    if(m[i]>=11 || maps[m[i+1]][m[i]+1] == 1){                        over = true;break;                    }                }                if(!over) shape.move(1,0);                break;            case 32:        //space                that.shape.transform();                break;        }    },false);}

總結(jié)

這里面實(shí)現(xiàn)了俄羅斯方塊的最基本功能,還有關(guān)卡等功能點(diǎn)并沒有實(shí)現(xiàn),同時(shí)該demo仍然有不完善的地方需要修正。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到HTML教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
春意影院午夜免费入口| 成人av免费在线观看| 成人黄色午夜影院| 亚洲综合精品国产一区二区三区| 北岛玲一区二区三区| 免费大片在线观看| 精品亚洲永久免费精品| 国产精品日本一区二区| 性欧美xxxx视频在线观看| 日韩免费观看高清完整版| 爱福利视频一区二区| 黄免费在线观看| 中文字幕+乱码+中文字幕明步| 亚洲第一福利网| 欧美高清视频| 国产精品美女主播在线观看纯欲| 国产精品久久99久久| 水蜜桃久久夜色精品一区的特点| 国产成人天天5g影院在线观看| 国产又大又粗又爽| 在线免费观看亚洲视频| 99精品视频中文字幕| 精品综合久久久久久97| 欧美热在线视频精品999| 91综合免费在线| 亚洲一区二区视频在线观看| 亚洲无亚洲人成网站77777| 亚洲一区在线免费| 日本不卡视频| 国产亚洲综合在线| 一区二区国产精品视频| 男人艹女人在线观看| 一区av在线播放| **欧美日韩在线| 日韩最新av在线| 精品国产人成亚洲区| 亚洲精品天堂成人片av在线播放| 欧美性猛交xxxx黑人猛交| 玩弄japan白嫩少妇hd| 国产精品日韩欧美综合| 毛片毛片毛片毛| 97超视频在线观看| 成人美女视频在线看| 一区二区三区精密机械公司| 国产丰满果冻videossex| 亚洲婷婷综合网| 国产成人高清激情视频在线观看| 久久美女艺术照精彩视频福利播放| 黄色成人在线观看网站| 免费欧美电影| 亚洲国产精品成人va在线观看| 日韩高清不卡一区| 精品一区二区三区免费毛片| 亚洲欧洲日韩一区二区三区| 国产三级精品三级在线专区| 永久免费精品影视网站| 精品处破学生在线二十三| 欧美videossex| 欧美视频免费在线| h七七www色午夜日本| 免费在线黄网| 美女在线观看视频一区二区| 午夜影院日韩| 少妇人妻好深好紧精品无码| 伊人久久中文字幕| 国产亚洲欧美日韩精品一区二区三区| 国模视频一区| 久久久久久久香蕉| av资源中文在线| 国产乱人伦精品一区二区三区| 精品无码在线观看| 国产亚洲精品久久久久动| 日韩精品一区二区三区第95| 国产视频网址在线| 亚洲欧美偷拍另类| 色诱色偷偷久久综合| 成人在线综合网站| 国产精品一级片在线观看| 日韩区一区二| 久久久www免费人成黑人精品| 熟妇熟女乱妇乱女网站| 久久久噜噜噜久久| 日本亚洲精品| 亚洲免费视频一区| 欧美一级片免费看| 久久精品国产亚洲av麻豆蜜芽| 国产原创在线播放| 一个人在线观看免费视频www| 久久久久久艹| 免费亚洲一区二区| 亚洲狠狠丁香婷婷综合久久久| 日韩精品一区二区三区四区五区| 91嫩草视频在线观看| 国产欧美日产一区| 香蕉国产精品| 日韩欧美视频免费观看| 久久久无码人妻精品无码| 九九热视频免费观看| 国产欧美亚洲一区| 亚洲欧美色图片| jizz视频| 欧美性xxxx18| 亚洲一区二区三区色| 国产免费一区二区三区在线能观看| 国产在线看片免费视频在线观看| 久久久精品国产免大香伊| 免费毛片在线播放免费| 99久久婷婷| 神马久久久久久久久久| 国产尤物久久久| 国产网红在线观看| 久久在线精品视频| 日韩av手机在线免费观看| 色偷偷91综合久久噜噜| 色av一区二区| 2020国内自拍视频| 成年人在线观看| 日韩国产在线播放| 黄色免费在线观看网站| 三级视频网站在线| 欧美一区二区三级| 欧美做受高潮中文字幕| 国产精品亲子伦av一区二区三区| 中文字幕字幕中文在线中不卡视频| av网站在线免费看推荐| 欧美日韩综合在线| 日本十八禁视频无遮挡| 亚洲精品天堂在线观看| 久久免费在线观看| 欧美日韩大陆在线| 久久精品亚洲国产奇米99| 免费日韩av电影| 国产性色视频| www.jizz在线观看| 不卡一区二区三区四区五区| 免费三级网站| 四虎永久免费在线观看| 啪啪小视频网站| 亚洲成人一区二区在线观看| 天天亚洲美女在线视频| 2023国产精品自拍| 亚洲欧美一区二区在线观看| www中文在线| 中文字幕中文在线| 自拍亚洲一区欧美另类| 欧美激情20| 777777777亚洲妇女| 在线视频在线视频7m国产| 中文字幕人妻色偷偷久久| 日本欧美国产| 三级亚洲高清视频| 88国产精品视频一区二区三区| 97超碰在线免费| 性囗交免费视频观看| 亚洲综合久久久| 欧美xxxhd| 青青草在线视频免费观看| 国内精品久久久久国产| 国产电影一区二区三区爱妃记| 久久综合五月天| 黄色高清无遮挡| 日韩精品视频播放| www.四虎成人| 日韩乱码一区二区三区| 久久久久无码精品国产| 欧美xxxx在线| 精品1区2区3区4区| 一区二区三区不卡在线视频| 欧美成人精品一区二区综合免费| 一级黄色在线播放| 欲色天天网综合久久| 性感女国产在线| 欧美日韩中文在线观看| 久久久久久a亚洲欧洲aⅴ| 久久色精品视频| 午夜影院免费看| 亚洲欧洲日本国产| www.欧美| 91亚洲大成网污www| 99久久亚洲| 成人自拍爱视频| 精品国产户外野外| 欧美日本免费一区二区三区| 亚洲一区网址| 日韩小视频在线观看专区| 91精品国产一区二区三区香蕉| 亚洲免费观看高清| 亚洲网中文字幕| 成人在线免费观看黄色| 成人黄色免费视频| wwwxxxx欧美| 精品欧美一区二区久久久久| 红桃视频成人在线观看| 成人午夜精品久久久久久久蜜臀| 人妻av无码一区二区三区| 最近中文字幕一区二区三区| 国产精品天美传媒沈樵| 麻豆视频观看网址久久| 3d动漫啪啪精品一区二区免费| 亚洲国产精品久久久久久久| 加勒比免费视频| 韩国xxxx做受gayxxxx| 999热精品视频| av成人免费观看| 久久视频国产精品免费视频在线| 日本在线一区二区三区| 色欲av无码一区二区人妻| 亚洲精品xxx| 在线观看午夜av| 国产精品老女人| 久久网站免费观看| 青草视频在线观看免费| 亚洲毛片在线播放| www.久久成人| 国产精品久久久久永久免费观看| 日韩欧美第二区在线观看| 国产精品99精品无码视亚| 久久精品理论片| 999sesese| 深爱五月激情五月| 亚洲国产一二三区| 鲁啊鲁视频在线精品| chinesegaysextube| 992tv成人免费视频| 亚洲另类在线观看| 天天影视色综合| 国产精品无码一区二区三区免费| 亚洲一二三在线| 欧美tickling网站挠脚心| 国产日韩欧美中文在线播放| 韩国av电影在线观看| 天堂在线视频免费观看| 日韩精品影音先锋| 欧美最猛性xxxxx(亚洲精品)| 69中国xxxxxxxxx69| www.黄色com| 99久久婷婷国产精品综合| 久久久www成人免费毛片| 亚洲欧美日韩精品一区| 亚洲一区二区自偷自拍| 国产一区在线免费观看| 日本一区二区黄色| 手机看片1024国产| 成人3d动漫一区二区三区91| 亚洲啪啪91| 欧美日韩性在线观看| 五月天色婷婷丁香| 国产欧美日产一区| 美臀av在线| 15—17女人毛片| av网站手机在线观看| 亚洲成人基地| 国产美女主播在线播放| 春意影院普通入口| 午夜在线a亚洲v天堂网2018| 国产一级片播放| 日韩视频在线免费看| 蜜桃成人365av| 中文字幕精品国产| 97精品久久久午夜一区二区三区| 婷婷久久国产对白刺激五月99| 亚洲成人精品久久久| 国产成人手机视频| 国产精品视频久久| 福利微拍一区二区| 久久r热视频| 蜜桃久久精品一区二区| 亚洲bt欧美bt日本bt| 香蕉伊大人中文在线观看| 亚洲综合精品四区| 91精品国产91久久久久久久久| 韩国黄色一级大片| 欧美大电影免费观看| 国产欧美日韩精品a在线观看| 99在线|亚洲一区二区| 日产精品一线二线三线芒果| 国产精品一区在线观看你懂的| 亚洲精品日韩专区silk| 九色porny视频在线观看| 国产精品无码久久久久一区二区| 午夜精品久久久久久毛片| 日韩免费高清| 亚洲欧洲三级电影| 国产日本一区二区| 午夜亚洲福利老司机| 欧美一区二区三区综合| 亚洲欧美国产一本综合首页| 国产在线观看福利| 国产精品普通话对白| 国产乱码精品一区二区| 嫩草影院一区二区三区| 国产农村老头老太视频| av大片免费观看| 精品一区二区无码| 91在线看www| 天堂在线视频免费| 国产污视频在线看| 麻豆精品久久精品色综合| 91av在线影院| 在线日本制服中文欧美| 丝袜美腿一区二区三区动态图| 色综合久久一区二区三区| 无码人妻av免费一区二区三区| 丁香花五月婷婷| 国产网站一区二区| 国产高潮呻吟久久久| 激情综合网五月婷婷| 久久亚洲精品视频| 国产精久久久久久| 欧美风情第一页| 国产精品久久久久av免费| 波多野结衣在线网址| 亚洲国产成人av好男人在线观看| 欧美日本在线观看| www.成人在线视频| 亚洲欧洲三级| 欧美h版在线| 亚洲精品中文综合第一页| 日韩中文字幕国产精品| 免费一级欧美片在线观看网站| 一区二区三区 在线观看视| 国产精品免费视频xxxx| 亚洲精品性视频| 91在线九色porny| 久久porn| 欧美不卡激情三级在线观看| 国产精品videossex国产高清| 老熟妻内射精品一区|