• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com专业计算机教程网站
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure
您的位置:首页 > 网页设计 >html5 > 动手打造html5俄罗斯方块的(图文)

动手打造html5俄罗斯方块的(图文)

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-03

本文主要包含html5,俄罗斯方块等相关知识,匿名希望在学习及工作中可以帮助到您
在正文开始之前还要啰嗦一下,标题中所谓自给自足,是在没有参考任何设计思路的前提下去开发这游戏的,你可能会不解,如果参考优秀的思路,岂不是事半功倍,当然,参考与不参考都有利,我只说不参考的利,当我煞费苦心、历经数十个BUG修改,终于完成一件作品的时候,我可以很自豪地对别人说:“看,我开发的游戏!”当然,创意不是我的,但这并不影响自己那份“虚荣心”,为一款经典的游戏赋予自我的理解,并将它融入游戏中,岂不是一件有意思的事,而且,回过头来再看一看别人的思路,有时会拍案而起,“这个我当初怎么就没想到呢?”,“原来这个问题可以这样解决”,“这个设计思路比我的思路好多了!”,诸如此类总比开始就直接看别人的思路而阻塞自己的思考要强得多,对吧?

好叻,正文开始~

想先看效果的,先跳转试玩一下吧!

俄罗斯方块,主游戏界面应该由一个一个的方块组成,如下图,当然成品里面这些网格是看不到的,这里只是助于理解,主界面尺寸为400×500,设定每块砖(网格)的尺寸为20×20,则每行有20个砖块,每列有25个砖块。相关代码:

brickWidth = 20,    //砖块大小
width = 400, height = 500;  //画布宽高,20X25

提到主界面的网格,就要提到一个非常重要的变量了,它就是BOARD,一个二维数组,形象化地说其尺寸是20×26,存储的值为0或1,0表示该位置没有砖块,1表示该位置有砖块,在接下来的一些判定中有重要作用,游戏细心的同学可能发现,为什么是20×26,而不是对应主界面网格的20×25,我在一开始的时候也是设定为20×25的,后来注意到如果加一行而且这一行的值都为1就可以很容易判断砖块是否到触及主界面底部了。相关代码:

// 初始化BOARD,注意纵向有26个,最后一排用来判断是否触底
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;
        }
    }
}


接下来看由4个砖块组成的“形状”,有五种,为了好描述,我把它们为别命名,Tian(田),Chu(锄头),Tu(凸起来),Thunder(闪电),Line(一横),哈哈有趣的名字,原谅我没找到它们的英文名字吧。

首先定义一个砖头类Brick:

function Brick() { }

其下有几个原型变量和方法:

Brick.prototype.embattle = null;    //砖块的布局(需重载)
Brick.prototype.isOverturn = 0; //是否翻转
Brick.prototype.originX = 9;    //砖头的绘制起点X
Brick.prototype.originY = -3;    //砖头的绘制起点Y
Brick.prototype.direction = 0;  //砖头朝向
Brick.prototype.autoMoveTimer = null;   //自动移动计时器
Brick.prototype.draw = function() { …… }    //画砖块的方法
Brick.prototype.move = function(moveX, moveY) { …… }    //移动的方法
Brick.prototype.autoMove = function() { …… }    //自动移动的方法
Brick.prototype.change = function() { …… }    //变换砖头朝向

Brick的子类有:Tian,Chu,Tu,Thunder,Line五个,每个子类中都重载Brick的embattle变量,embattle是什么,英译中的意思是布阵,这个阵是个什么阵呢?首先,同学们要理解我的思路,用Tu的embattle来举例,其代码如下:

this.embattle = [
    [ [0,4,5,8], [1,4,5,6], [1,4,5,9], [0,1,2,5] ],  //布局表为4X4表格,数字为砖头位置
    [ [0,4,5,8], [1,4,5,6], [1,4,5,9], [0,1,2,5] ]   //次行为翻转的情况];

embattle是一个三维数组,第一维是是否翻转isOverturn(形象来说就像图片的水平翻转),第二维是方向direction(上左下右),第三维是形状的4个砖块分布情况,我把每个新形状对象定义在一个4×4的阵中,例如,Tu的this.embattle[0][0]为[0,4,5,8],数字即该砖块的所在位置,如下图:

所以要确定一个形状的位置和样子,需要isOverturn确定是否翻转,需要direction确定其方向,需要originX和originY确定“阵”的位置。

接下来,分别解释Brick的4个原型方法。

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
}

有上面说的确定形状的位置和样子的方法,之后就是纯粹canvas画图,4个砖块一个一个地画,不要看代码很长其实就是那么一点点,originX、originY和砖块在阵中的位置就可以确定画砖块的起点了。注意到代码的注释了没有,画边框的时候,它是从起点向外面画的,就像我把一个塑料袋套在另一个塑料袋的外面,为了以后的清除的方便且不影响其他的砖块,把边框画进fillRect的领土,就像我现在把这个塑料袋不套在外面而是放进这另一个塑料袋里面一样,就这个意思。

Brick.prototype.move

这是最长的一个了,移动的时候,moveX和moveY表示横纵的增量,没有同时非0的情况(这是人为的设定,要么横向移动要么纵向移动),当然要判断即将移动到的位置是否违规:

横向:

如果阵贴靠主界面左侧则不能向左移即moveX不能为-1

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

判断右边时比较麻烦,因为不能直接用阵来判断是否贴靠右侧(看前面的图就知道阵的右边和下边可能没有砖块的),这时要一个个地判断4个砖块是否有至少有一个在最右,这时不能向右移动

|| (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)

最后还要判断即将到达的位置是否已经有砖块了。

|| (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)

纵向:

即将到达的位置是否已经有砖块了,注意到下面的代码的&& moveX==0,原来是没有的,后来发现每次砖块怎么刚刚靠上下面堆着的砖块就不能再移动了,原来横向移动的时候也进行了这个判断,即刚刚靠上下面的砖块,如果这时想左右移动,但下方有砖块,但是问题来了,下面有没有砖块跟我左右移动有什么关系呢?是吧。

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

纵向终止判断里面主要做了几件事:清除autoMoveTimer,设置BOARD在该形状当前位置的值为1,有可以消除的整行就消除,加分改分,判断胜利/失败,删除当前对象,召唤下一个形状。

横纵都没违规时:

这时,把该形状前一个位置的砖块清除,更新originX和originY,再画出来。

for(i=0;i<4;i++) {
    tmp = this.embattle[this.isOverturn][this.direction][i];
    ctx.clearRect((t
  


 

您可能想查找下面的文章:

  • HTML5知识点总结
  • HTML5的本地存储
  • HTML5本地存储之IndexedDB
  • Html5实现文件异步上传功能
  • Html5新标签datalist实现输入框与后台数据库数据的动态匹配
  • 详解HTML5 window.postMessage与跨域
  • HTML5拖放API实现拖放排序的实例代码
  • 解决html5中video标签无法播放mp4问题的办法
  • HTML5新特性 多线程(Worker SharedWorker)
  • Html5新增标签有哪些

相关文章

  • 2017-08-06浅谈html5增强的页面元素
  • 2018-12-03HTML5标准学习-编码详解
  • 2017-08-06HTML5 用动画的表现形式装载图像
  • 2018-12-03Vue.directive的自定义指令详解
  • 2017-08-06HTML5调用手机摄像头拍照的实现思路及代码
  • 2018-12-03借助toDataURL实现将HTML5 Canvas的内容保存为图片
  • 2018-12-03Web SQL数据库的使用教程
  • 2018-12-03 html5视频与声频详解
  • 2018-12-03如何解决layer弹出层中H5播放器全屏出错
  • 2017-08-06用HTML5中的Canvas结合公式绘制粒子运动的教程

文章分类

  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure

最近更新的内容

    • 突破canvas语法限制 让他支持链式语法_html5教程技巧
    • safari 支不支持HTML5的录音?
    • 为什么现在HTML5的优势越来越大
    • H5的时代什么时候才会到来?
    • 极客学院HTML5新特性基础视频课件源码
    • 几个解决兼容IE6\7\8不支持html5标签的几个方法
    • 利用HTML5中Geolocation获取地理位置调用Google Map API在Google Map上定位_html5教程技巧
    • 关于HTML5 history API 的介绍
    • html5如何使用canvas画空心圆与实心圆
    • HTML5进度条特效_html5教程技巧

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有