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的算法探索后, 让我们来尝试一下人机大战雏形编写. 本系列的文章链 ...
随机推荐
- Eclipse管理Java工程(j2se/j2ee/maven)
Eclipse管理J2SE/J2EE(Maven)项目 eclipse是一个集成开发工具,有编译,运行,打包部署等功能.eclipse可以新建多种项目,不同的项目有不同的IDE层次结构,方便用户管理资 ...
- MyBatis执行过程显示SQL语句的log4j配置
log4j.properties文件 log4j.rootLogger=debug,stdout,logfile log4j.appender.stdout=org.apache.log4j.Co ...
- 在CentOS 7 MySQL / MariaDB
在CentOS7中,MariaDB 替代了MySQL;更多复杂的疑问可以在这里查看 MariaDB versus MySQL – Compatibility Install MySQL / Mari ...
- Response返回JSON数据到前台页面
转自博文:<Response JSON数据返回>http://blog.csdn.net/anialy/article/details/8665471 简述: 在servlet填充Resp ...
- 5月21日 CSS样式表加阴影
HTML <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...
- BZOJ3307 雨天的尾巴
首先考虑序列怎么做... 只要把操作差分了,记录在每个点上 然后维护一棵权值线段树,表示每个颜色出现的次数,支持单点修改和查询最大值操作 只要把序列扫一遍就好了,时间复杂度$O(n + m*logZ) ...
- PDF 补丁丁 0.4.2.891 测试版发布:合并PDF文件时设置书签文本和样式
新的测试版在合并文件界面增加了设置书签样式的功能.除了可以为所合并的图片(或PDF文件)指定书签文本之外,还可以指定其文本样式(文本颜色.粗体.斜体).如下图所示. 此外,合并文件界面还添加了文件夹历 ...
- 关于php用simplexml_load_string解析xml出现乱码的小结
最近在做项目时需要通过xml接口读取合作伙伴数据到数据库,在xml解析环节出现有些特殊中文字符乱码的现象.后采取下面的办法终于解决. 1.curl 抓取过来的字符是unicode编码,需要先转换为ut ...
- mysql sql 百万级数据库优化方案
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- 启动、关闭Service
//获取程序界面中的start.stop两个按钮 start = (Button) findViewById(R.id.start); stop = (Button) findViewById(R.i ...