婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > canvas實現俄羅斯方塊的方法示例

canvas實現俄羅斯方塊的方法示例

熱門標簽:農村住宅地圖標注 跟電銷機器人做同事 鄭州電銷外呼系統違法嗎 鶴壁手機自動外呼系統怎么安裝 威海營銷外呼系統招商 ai電銷機器人連接網關 濟南辦理400電話 中紳電銷智能機器人 漳州人工外呼系統排名

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

原理詳解

看游戲最終界面,可知需要實現以下關鍵功能:

  • 游戲面板,也就是12 * 20的方格,以及是否填充了方塊信息;
  • 運動方塊,方塊需要實現移動,變形的功能。
     

 

界面的實現

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

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], ...];

畫出面板的代碼,用最基礎的canvas的api就能實現

//格子
    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){//方格已經有填充內容
                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();

方塊的實現

游戲中用到以下 7 種圖形

結合上面介紹的坐標系,數組 [x1, y1, x2, y2, x3, y3, x4, y4] 就是上面圖形中4個點坐標的數據表現形式,7 種圖形的坐標分別如下:

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]];

方塊的移動,遍歷整個數組,加上位移向量就行,非常簡單

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

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

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

邊界條件

主要包括如下三個方面

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

遍歷數組 (1)任意一個點y坐標為19時表示到達了底部;(2)獲取該坐標的y+1位置在maps的信息,如果為1表示已經填充。這兩種情況下,運動方塊的周期結束,將該方塊的坐標填充到maps對應的數組里面即可。

如果坐標的y+1已經有填充,同時當前坐標小于1,即已經在界面的頂部了,那么表示游戲結束。

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位置已經填充
        isEnd = true;
        if(y <= 1){isOver=true;} // 游戲結束
        break;
    }
}

方塊運動周期結束時檢測每一層是否滿格,以及滿格后的處理。某項數組全部元素都為1則表示已經滿格,那么刪除該項數組,同時列表頭再壓入一項每個元素都為0的數組即可。

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){// 表示該層已經滿格
            that.maps.splice(i,1);
            that.score+=10; // 增加分數
            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);
}

總結

這里面實現了俄羅斯方塊的最基本功能,還有關卡等功能點并沒有實現,同時該demo仍然有不完善的地方需要修正。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

標簽:蘇州 咸陽 惠州 營口 紅河 甘南 文山 萍鄉

巨人網絡通訊聲明:本文標題《canvas實現俄羅斯方塊的方法示例》,本文關鍵詞  canvas,實現,俄羅斯,方塊,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《canvas實現俄羅斯方塊的方法示例》相關的同類信息!
  • 本頁收集關于canvas實現俄羅斯方塊的方法示例的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    色香蕉成人二区免费| 国产成人精品综合在线观看| 中文字幕av一区 二区| 26uuu亚洲婷婷狠狠天堂| 91精品国模一区二区三区| 欧美日韩一级大片网址| 欧美在线免费视屏| 欧美区一区二区三区| 91精品国产综合久久精品图片| 欧美日韩亚洲国产综合| 欧美一区二区三区免费观看视频 | 日韩欧美高清dvd碟片| 日韩一区二区精品葵司在线| 日韩视频在线永久播放| 精品国产99国产精品| 中文一区二区在线观看| 亚洲人成精品久久久久| 香蕉影视欧美成人| 精品无人区卡一卡二卡三乱码免费卡 | 欧美v亚洲v综合ⅴ国产v| 欧美mv日韩mv亚洲| 国产精品高潮久久久久无| 一区二区成人在线视频| 日本午夜一本久久久综合| 精品一区二区三区av| 成人毛片视频在线观看| 色吊一区二区三区| 日韩欧美激情一区| 亚洲少妇30p| 精品一区二区三区香蕉蜜桃| 91网址在线看| 精品国产电影一区二区| 亚洲精品国产精华液| 国产一区视频网站| 欧美性猛片xxxx免费看久爱| 久久免费视频色| 亚洲成av人片一区二区梦乃 | 亚洲男女毛片无遮挡| 蜜乳av一区二区三区| 99视频在线精品| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 综合分类小说区另类春色亚洲小说欧美| 国产精品网站在线播放| 欧美日韩精品电影| 国产精品久久久久久久久免费相片 | 亚洲三级理论片| 久草在线在线精品观看| 在线观看三级视频欧美| 中文欧美字幕免费| 国产一区二区三区黄视频 | 久久久亚洲综合| 自拍偷在线精品自拍偷无码专区| 日韩成人精品在线| 欧美亚洲另类激情小说| 欧美国产综合一区二区| 麻豆成人综合网| 91精品婷婷国产综合久久 | 精品嫩草影院久久| 午夜精品一区二区三区免费视频| 91视频国产资源| 中文字幕一区视频| 成人激情动漫在线观看| 国产亚洲成aⅴ人片在线观看| 蜜桃久久久久久| 日韩一区国产二区欧美三区| 爽好久久久欧美精品| 欧美男人的天堂一二区| 亚洲亚洲精品在线观看| 91官网在线观看| 亚洲靠逼com| 色老汉av一区二区三区| 亚洲黄色av一区| 91福利视频久久久久| 一区二区三区四区在线免费观看| 91色在线porny| 一区二区三区在线看| 欧美性色黄大片| 天天操天天综合网| 日韩欧美二区三区| 精品一区二区免费在线观看| 久久久国产综合精品女国产盗摄| 国产综合色精品一区二区三区| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 在线播放91灌醉迷j高跟美女 | 在线观看日韩av先锋影音电影院| 日韩理论片中文av| 欧美色图在线观看| 日本不卡中文字幕| 国产精品私人影院| 欧美亚洲综合久久| 麻豆国产欧美一区二区三区| 精品处破学生在线二十三| 国产酒店精品激情| 亚洲视频精选在线| 欧美精品视频www在线观看| 久久成人免费网站| 日韩一区在线看| 欧美日韩日日骚| 国产呦精品一区二区三区网站| 中文字幕免费在线观看视频一区| 色综合中文字幕国产 | 欧美日韩午夜精品| 精品午夜久久福利影院| 18欧美亚洲精品| 精品日产卡一卡二卡麻豆| 成人黄色小视频在线观看| 污片在线观看一区二区| 国产日韩精品一区| 欧美精品在线观看一区二区| 国产美女一区二区三区| 一区二区成人在线| 国产日韩欧美精品一区| 欧美做爰猛烈大尺度电影无法无天| 免费xxxx性欧美18vr| 亚洲日本免费电影| 精品99久久久久久| 欧美日韩精品一区二区三区四区| 成人午夜短视频| 日本欧美一区二区三区| 亚洲欧洲性图库| 国产网红主播福利一区二区| 欧美久久久一区| 色婷婷综合五月| 成人福利视频在线| 国内精品嫩模私拍在线| 午夜精品成人在线| 一区二区三区四区在线播放| 国产精品五月天| 久久久精品影视| 日韩一区二区三区视频在线观看| 色88888久久久久久影院按摩| 成人免费毛片高清视频| 国产一区二区看久久| 久久69国产一区二区蜜臀| 日本系列欧美系列| 日韩精品91亚洲二区在线观看 | 精品一区二区三区免费播放| 午夜电影一区二区三区| 亚洲乱码一区二区三区在线观看| 国产精品久线观看视频| 国产欧美一二三区| 国产精品天干天干在观线| 久久影院电视剧免费观看| 精品国产乱码久久久久久1区2区| 欧美一级电影网站| 精品精品国产高清一毛片一天堂| 欧美一区二区三区小说| 欧美日韩国产bt| 欧美一三区三区四区免费在线看| 欧美视频一区二区在线观看| 欧美日韩大陆在线| 欧美va亚洲va香蕉在线| 欧美xxxxx牲另类人与| 2023国产精品| 国产精品乱人伦| 亚洲女子a中天字幕| 一区二区三区波多野结衣在线观看| 亚洲一区免费视频| 日韩国产欧美在线视频| 麻豆免费看一区二区三区| 国产精品一区二区久久精品爱涩| 丁香桃色午夜亚洲一区二区三区| 不卡一区二区在线| 欧美日韩一区中文字幕| 欧美成人猛片aaaaaaa| 中文字幕国产一区二区| 一级做a爱片久久| 无吗不卡中文字幕| 国产精品1区2区3区在线观看| 99久久精品国产网站| 欧美日韩三级一区| 久久久国产午夜精品 | 热久久国产精品| 国产精品亚洲а∨天堂免在线| 成人美女视频在线观看18| 欧美色图免费看| 久久久亚洲精品一区二区三区| 国产精品视频一二三区| 午夜视频一区在线观看| 国产一区二区三区视频在线播放| 成人亚洲一区二区一| 欧美精品久久99| 国产精品无遮挡| 日本亚洲视频在线| 91一区二区在线| 日韩写真欧美这视频| 国产精品午夜在线| 秋霞影院一区二区| 成人av网站在线观看免费| 91精品国产91久久综合桃花| 国产精品美女www爽爽爽| 日本中文在线一区| 91蜜桃视频在线| 久久这里都是精品| 天天爽夜夜爽夜夜爽精品视频| 99re这里都是精品| 精品国产伦一区二区三区观看体验| 亚洲伊人伊色伊影伊综合网| 成人毛片老司机大片| 26uuu精品一区二区 |