H5实现俄罗斯方块(二)
对应的js
1.封装操作dom的js:
(function (document) {
//游戏的实例
var gameInst; /**封装一个返回原型的DOM对象 */
function DomObject(dom){
this.dom=dom;
} /**返回真正的dom元素 */
DomObject.prototype.get=function () {
return this.dom;
}; /**分装事件的注册 */
DomObject.prototype.on=function (eventName,eventHandler) {
this.get().addEventListener(eventName,eventHandler);
}; /**分装操作CSS样式的方法 */
DomObject.prototype.css=function (stylekey,styleValue){
this.get().style[stylekey]=styleValue;
}; /**能够操作以上对象的作法的方法 */
function $(selector,context) {
return new DomObject((context||document).querySelector(selector));
}; /**启动游戏的方法 */
function startGame() {
//注册一个时间 OK时 启动游戏
ResourceManager.onResourceLoaded = function () {
// new Board(); 调用游戏的计时方法
gameInst = new Tetris();
gameInst.startGame();
};
ResourceManager.init();
} /**初始化的一个方法 */
function _init() {
$('#btn-start').on('click',function (ev) {
$('.start-container').css('display','none');
$('.game-container').css('display', 'block');
/**调用游戏启动的方法 */
startGame();
}); $('#btn-setting').on('click', function(ev){
// alert('You clicked the setting button.');
$('.modal-dialog').css('display','block'); }); $('#btn-dialog-close').on('click',function () {
$('.modal-dialog').css('display','none');
gameInst && gameInst.resume();
}); $('#ck-sound').on('click',function () {
var enable=$('#ck-sound').get().checked;
window.TetrisConfig.config.enableSound=enable;
}); $('#btn-game-setting').on('click',function () {
$('.modal-dialog').css('display','block');
gameInst.pause();
});
//暂停和继续
$('#btn-game-pause').on('click', function (evt) {
var el = evt.target;
if (el.innerText === '暂停') {
el.innerText = '继续';
gameInst.pause();
} else {
el.innerText = '暂停';
gameInst.resume();
}
});
}
/**监听事件的方法 */
document.addEventListener('DOMContentLoaded',function (ev) {
_init();
}); })(document);
全局的配置:
(function (window) {
window.TetrisConfig = {
rows: 20,
cols: 13,
speed: 1000,
constSpeed:1000,
intervalId: 0,
config:{ }
};
})(window);
绘制方块的js:
(function (window) {
'use strict';
function Block(blockType) {
this.blockType = blockType;
this.size = 30;
this.originalSize = 32;
this.sprite = window.ResourceManager.getResource('blocks');
} Block.prototype = {
constructor: Block,
draw: function (context, x, y,blockType,size) {
size=size || this.size;
context.drawImage(this.sprite, ((blockType || this.blockType) -1) * this.originalSize, 0, this.originalSize, this.originalSize, x * size, y * size, size, size);
}
}; window.Block = Block; })(window);
放置游戏主元素的面板:
/**放置游戏主元素的面板 */
(function (window) {
'use strict'; function Board(gameInst) {
//传递游戏的实例
this.gameInst=gameInst;
this.blockSize=30;
this.rows=TetrisConfig.rows;
this.cols=TetrisConfig.cols;
/**拿到Canvas对象 */
this.canvas = new Canvas('c_game_main', this.cols * this.blockSize, this.rows * this.blockSize);
this.context=this.canvas.context;
/**生成画布二维数组的数据 */
this.boardList=[]; //绘制方块的属性
this.shape = new window.Shape(); this._init(); //验证是否成功
var b = ResourceManager.getResource('blocks');
console.log(b);
} /**操作_init方法 */
Board.prototype={
constructor:Board,
_init:function(){
this._buildGridData();
this._initGrid(); //初始化的时候绘制方块
this.shape.draw(this.context);
var self=this;
setTimeout(function(){
//调用构建下一步方块的方法
self._buildNextShape();
});
}, //构建下一步方块的方法
_buildNextShape: function () {
this.nextShape = new window.Shape();
this.nextShape.setPosition(this.gameInst.nextshape.cols, this.gameInst.nextshape.rows);
//找到面板
this.gameInst.nextshape.render(this.nextShape);
}, /**_init中的两个方法*/
_buildGridData(){
var i,j;
for(i=0;i<this.rows;i++){
this.boardList[i]=[];
for(j=0;j<this.cols;j++){
this.boardList[i][j]=0;
}
}
// console.log(this.boardList);
},
/**绘制表格数据 */
_initGrid(){
/**设置画笔 */
var i;
this.context.strokeStyle='green';
this.context.linewidth=0.5; //绘制线条的 笔迹
for(i=0;i<this.rows;i++){
/**找到起始点 ()*/
this.context.moveTo(0,i*this.blockSize);
this.context.lineTo(this.canvas.width,i*this.blockSize);
} for(i=0;i<=this.cols;i++){
this.context.moveTo(i*this.blockSize,0);
this.context.lineTo(i*this.blockSize,this.canvas.height);
}
//绘制 线条
this.context.stroke(); //把数据进行缓存
this.gridImageData=this.context.getImageData(0,0,this.canvas.width,this.canvas.height);
},
tick:function(){
//跳动一次加一个数
if(this.validMove(0,1)){
this.shape.y+=1;
}else{
//不能向下移动添加
this.addShapeToBoardList();
//游戏
if(this.gameInst._state==='over'){
this.gameInst.endGame();
return;
} //执行清理方法
this.clearFullRows();
this.shape=this.nextShape;
this.shape.setPosition(this.cols,this.rows,true);
this._buildNextShape();
//添加后重新实例化
// this.shape=new window.Shape();
} //画布刷新一次
this.refresh();
//画出方块
this.shape.draw(this.context); },
refresh:function(){
this.canvas.clear();
//把图像数据推送到Canvas中
this.context.putImageData(this.gridImageData,0,0);
//绘制方块
this.drawBlocks();
}, //边际的检查算法
validMove:function(moveX,moveY){
//下一步的位置
var nextX=this.shape.x+moveX;
var nextY=this.shape.y+moveY; //循环检查有没有越界 (越界的算法)
for(var y=0;y<this.shape.layout.length;y++){
for(var x=0;x<this.shape.layout[y].length;x++){
//判断有没有方块
if(this.shape.layout[y][x]){
if (typeof this.boardList[nextY + y] === 'undefined' //找不到行
|| typeof this.boardList[nextY + y][nextX + x] === 'undefined' //找不到列
||this.boardList[nextY+y][nextX+x] //当前位置已有方块
||nextX+x<0 //超出左边界
||nextX+x>=this.cols //超出右边界
||nextY+y>=this.rows //超出上边界
){
return false;
} }
}
}
return true;
},
//添加堆积容器
addShapeToBoardList:function(){
for(var y=0;y<this.shape.layout.length;y++){
for(var x=0;x<this.shape.layout[y].length;x++){
if(this.shape.layout[y][x]){
var boardX=this.shape.x+x;
var boardY=this.shape.y+y;
if(this.boardList[boardY][boardX]){
//说明已经有了 状态的变化
this.gameInst._state='over';
return;
}else{
//没有碰上默认等于1 让他显示出来
this.boardList[boardY][boardX]=this.shape.blockType; }
}
}
}
},
//绘制方块
drawBlocks:function(){
for(var y=0;y<this.rows;y++){
for(var x=0;x<this.cols;x++){
if(this.boardList[y][x]){
this.shape.block.draw(this.context,x,y,this.boardList[y][x]);
}
}
}
}, //创建空行
createEmptyRow(){
var emptyArr=[];
for(var i=0;i<this.cols;i++){
emptyArr.push(0);
}
return emptyArr;
}, //消除行的方法
clearFullRows:function(){
var self=this;
var lines=0;
//重下往上判断
for(var y=this.rows-1;y>=0;y--){
//全部填充
var filled=this.boardList[y].filter(function(item){return item>0;}).length===this.cols;
//做移除操作
if(filled&&y){
this.boardList.splice(y,1);
//追加一行 用创建的新行进行填充
this.boardList.unshift(this.createEmptyRow());
lines++;
y++;
}
}
//计算出得分
var score=lines*100*lines; //清楚的行数 * 单行得分 * 倍数
//调用得分的方法
var totalScore= this.gameInst.score.addScore(score);
//最高分
this.gameInst.highscore.checkScore(totalScore);
//当前的级别
var currentLevel= this.gameInst.level.checkLevel(totalScore);
if(currentLevel){
//升级算法速度的变化
window.TetrisConfig.speed= Math.floor(window.TetrisConfig.constSpeed *(1-(currentLevel-1) /10 ));
//提示用户 1.暂停游戏
this.gameInst.pause();
setTimeout(function() {
window.alert('恭喜您升级了!');
self.gameInst.resume();
}); } }
};
window.Board = Board; })(window);
绘制面板:
/**
* @param canvasId Canvas元素的ID 属性
* @param width Canvas宽度
* @param height Canvas高度
*/ (function (window){
'user strict'; function Canvas(canvasId, width, height) {
this.canvasId = canvasId;
this.el = document.getElementById(canvasId);
if(!this.el) {
throw new Error ('Must provider a right canvas id.');
}
/**获取Canvas的上下文 */
this.context=this.el.getContext('2d');
this.width=width||window.innerWidth;
this.height=height||window.innerHeight;
this._init();
} /**操作原型 */
Canvas.prototype={
constructor:Canvas,
_init :function(){
/**style 中的宽高 赋值给参数中的值 */
this.el.width=this.width;
this.el.height=this.height;
}, clear:function(fromX,fromY,toX,toY){
fromX=fromX||0;
fromY=fromY||0;
toX=toX||this.width;
toY=toY||this.height;
this.context.clearRect(fromX,fromY,toX,toY)
},
//绘制文本
drawText: function (text, x, y) {
//清理画布
this.clear(0, 0);
//设置画笔
this.context.font = '25px Arial';
this.context.fillStyle = 'purple';
this.context.textAlign = 'center';
this.context.fillText(text, x === undefined ? (this.width / 2) : x, y === undefined ? 45 : y);
}
}; window.Canvas=Canvas; })(window);
H5实现俄罗斯方块(二)的更多相关文章
- H5版俄罗斯方块(2)---游戏的基本框架和实现
前言: 上文中谈到了H5版俄罗斯方块的需求和目标, 这次要实现一个可玩的版本. 但饭要一口一口吃, 很多东西并非一蹴而就. 本文将简单实现一个可玩的俄罗斯方块版本. 下一步会引入AI, 最终采用coc ...
- H5版俄罗斯方块(3)---游戏的AI算法
前言: 算是"long long ago"的事了, 某著名互联网公司在我校举行了一次"lengend code"的比赛, 其中有一题就是"智能俄罗斯方 ...
- H5混合开发二维码扫描以及调用本地摄像头
今天主管给了我个需求,说要用混合开发,用H5调用本地摄像头进行扫描二维码,我之前有做过原生安卓的二维码扫一扫,主要是通过调用zxing插件进行操作的,其中还弄了个闪光灯.但是纯H5的没接触过,心里没底 ...
- 基于EasyNVR+EasyDSS H5视频直播二次开发实现业务需求:直接使用播放页面
之前的"网页直播.微信直播技术解决方案:EasyNVR与EasyDSS流媒体服务器组合之区分不同场景下的easynvr"有介绍一些功能.由于客户需求,我们定制一下功能.给该套方案添 ...
- H5实现扫描二维码功能
为了实现H5扫描二维码功能,我在网上找到了可用的代码:https://github.com/zhiqiang21/WebComponent/tree/master/html5-Qrcode 该程序能基 ...
- Android原生同步登录状态到H5网页避免二次登录
本文解决的问题是目前流行的 Android/IOS 原生应用内嵌 WebView 网页时,原生与H5页面登录状态的同步. 大多数混合开发应用的登录都是在原生页面中,这就牵扯到一个问题,如何把登录状态传 ...
- 微信硬件H5面板开发(二) ---- 实现一个灯的控制
在第一节中讲解了openApi的调用,这一篇讲一下如何实现一个灯的控制.就用微信提供的lamp例子来做,将代码扒下来(实在是没办法,没有示例),整合到自己的项目中.lamp源码:http://file ...
- H5版俄罗斯方块(1)---需求分析和目标创新
前言: 俄罗斯方块和五子棋一样, 规则简单, 上手容易. 几乎每个开发者, 都会在其青春年华时, 签下"xx到此一游". 犹记得大一老师在布置大程作业的时候提过: "什么 ...
- H5版俄罗斯方块(4)---火拼对战的雏形
前言: 勿忘初心, 本系列的目标是实现一款类似QQ"火拼系列"的人机对战版俄罗斯方块. 在完成了基本游戏框架和AI的算法探索后, 让我们来尝试一下人机大战雏形编写. 本系列的文章链 ...
随机推荐
- 164. Maximum Gap *HARD* -- 无序数组找出排序后连续元素的最大间隔
Given an unsorted array, find the maximum difference between the successive elements in its sorted f ...
- 权威第三方报告——获取IT产品竞争力信息的主要途径,类似你买电脑前上的xx论坛看实力评估
Gartner is known for its huge influence on purchasing as well as an unequaled events business. Forre ...
- noip知识点总结之--欧几里得算法和扩展欧几里得算法
一.欧几里得算法 名字非常高大上的不一定难,比如欧几里得算法...其实就是求两个正整数a, b的最大公约数(即gcd),亦称辗转相除法 需要先知道一个定理: gcd(a, b) = gcd(b, a ...
- display:inline-block;如何取消标签之间的距离
<div style="font-size:0px"> <div style=" display:inline-block; zoom:1;*displ ...
- C#基础学习文章导航
第一部分:入个门 C#入门篇-1:HelloWorld的类 C#入门篇-2:什么是变量 C#入门篇-3:数据类型及转换 C#入门篇-4:使用运算符 第二部分:流程控制语句 C#入门篇5-1:流程控制语 ...
- mysql 远程连接速度慢的解决方案
PHP远程连接MYSQL速度慢,有时远程连接到MYSQL用时4-20秒不等,本地连接MYSQL正常,出现这种问题的主要原因是,默认安装的MYSQL开启了DNS的反向解析,在MY.INI(WINDOWS ...
- js 数组 转
1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限, ...
- 通过电脑(计算机)下载google play的应用的方法
手机上安装GOOGLE PLAY很麻烦,经常不成功.于是采用电脑下载APK的方法. 网上传说的下载chrome的插件,然后获取DEVICE ID的方法,经过试用,一直无法获得DEVICE ID. 经过 ...
- [原创]checkstyle下载与安装
checkstyle是一款功能很强的java静态代码检查工具,为eclipse的插件.在网上看了,大致有两种安装方法.第一种 为联网,在eclipse里输入URL下载:另一种为下载好插件后,离线安装. ...
- hduacm 5255
http://acm.hdu.edu.cn/showproblem.php?pid=5255 枚举a和c 求解b #include <cstdio> #include <cstri ...