JavaScript实现简洁的俄罗斯方块完整实例


Posted in Javascript onMarch 01, 2016

本文实例讲述了JavaScript实现简洁的俄罗斯方块。分享给大家供大家参考,具体如下:

先来看看运行效果图:

JavaScript实现简洁的俄罗斯方块完整实例

完整实例代码如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>俄罗斯方块</title>
<style type="text/css">
 .c{margin:1px; width:19px; height:19px; background:red; position:absolute;}
 .d{margin:1px; width:19px; height:19px; background:gray; position:absolute;}
 .f{top:0px; left:0px; background:black; position:absolute;}
 .e{top:0px; background:#151515; position:absolute;}
 .g{width:100px; height:20px; color:white; position:absolute;}
</style>
<script type="text/javascript">
var row = 18;
var col = 10;
var announcement = 6;
var size = 20;
var isOver = false;
var shapes = ("0,1,1,1,2,1,3,1;1,0,1,1,1,2,2,2;2,0,2,1,2,2,1,2;0,1,1,1,1,2,2,2;1,2,2,2,2,1,3,1;1,1,2,1,1,2,2,2;0,2,1,2,1,1,2,2").split(";");
var tetris;
var container;
function createElm(tag,css)
{
 var elm = document.createElement(tag);
 elm.className = css;
 document.body.appendChild(elm);
 return elm;
}
function Tetris(css,x,y,shape)
{
 // 创建4个div用来组合出各种方块
 var myCss = css?css:"c";
 this.divs = [createElm("div",myCss),createElm("div",myCss),createElm("div",myCss),createElm("div",myCss)];
 if(!shape)
 {
  this.divs2 = [createElm("div",myCss),createElm("div",myCss),createElm("div",myCss),createElm("div",myCss)];
  this.score = createElm("div","g");
  this.score.style.top = 10*size+"px";
  this.score.style.left = (col- -1)*size+"px";
  this.score.innerHTML = "score:0";
 }
 this.container = null;
 this.refresh = function()
 {
  this.x = (typeof(x)!='undefined')?x:3;
  this.y = (typeof(y)!='undefined')?y:0;
  // 如果有传参,优先使用参数的,如果有预告,优先使用预告,都没有就自己生成
  if(shape)
   this.shape = shape;
  else if(this.shape2)
   this.shape = this.shape2;
  else
   this.shape = shape?shape:shapes[Math.floor((Math.random()*shapes.length-0.000000001))].split(",");
  this.shape2 = shapes[Math.floor((Math.random()*shapes.length-0.000000001))].split(",");
  if(this.container && !this.container.check(this.x,this.y,this.shape))
  {
   isOver = true;
   alert("游戏结束");
  }
  else
  {
   this.show();
   this.showScore();
   this.showAnnouncement();
  }
 }
 // 显示方块
 this.show = function()
 {
  for(var i in this.divs)
  {
   this.divs[i].style.top = (this.shape[i*2+1]- -this.y)*size+"px";
   this.divs[i].style.left = (this.shape[i*2]- -this.x)*size+"px";
  }
 }
 // 显示预告
 this.showAnnouncement = function()
 {
  for(var i in this.divs2)
  {
   this.divs2[i].style.top = (this.shape2[i*2+1]- -1)*size+"px";
   this.divs2[i].style.left = (this.shape2[i*2]- -1- -col)*size+"px";
  }
 }
 // 显示分数
 this.showScore = function()
 {
  if(this.container && this.score)
  {
   this.score.innerHTML = "score:" + this.container.score;
  }
 }
 // 水平移动方块的位置
 this.hMove = function(step)
 {
  if(this.container.check(this.x- -step,this.y,this.shape))
  {
   this.x += step;
   this.show();
  }
 }
 // 垂直移动方块位置
 this.vMove = function(step)
 {
  if(this.container.check(this.x,this.y- -step,this.shape))
  {
   this.y += step;
   this.show();
  }
  else
  {
   this.container.fixShape(this.x,this.y,this.shape);
   this.container.findFull();
   this.refresh();
  }
 }
 // 旋转方块
 this.rotate = function()
 {
  var newShape = [this.shape[1],3-this.shape[0],this.shape[3],3-this.shape[2],this.shape[5],3-this.shape[4],this.shape[7],3-this.shape[6]];
  if(this.container.check(this.x,this.y,newShape))
  {
   this.shape = newShape;
   this.show();
  }
 }
 this.refresh();
}
function Container()
{
 this.init = function()
 {
  // 绘制方块所在区域
  var bgDiv = createElm("div","f");
  bgDiv.style.width = size*col+"px";
  bgDiv.style.height = size*row+"px";
  // 绘制预告所在区域
  var bgDiv = createElm("div","e");
  bgDiv.style.left = size*col+"px";
  bgDiv.style.width = size*announcement+"px";
  bgDiv.style.height = size*row+"px";
  // 清空积分
  this.score = 0;
 }
 this.check = function(x,y,shape)
 {
  // 检查边界越界
  var flag = false;
  var leftmost=col;
  var rightmost=0;
  var undermost=0;
  for(var i=0;i<8;i+=2)
  {
   // 记录最左边水平坐标
   if(shape[i]<leftmost)
    leftmost = shape[i];
   // 记录最右边水平坐标
   if(shape[i]>rightmost)
    rightmost = shape[i];
   // 记录最下边垂直坐标
   if(shape[i+1]>undermost)
    undermost = shape[i+1];
   // 判断是否碰撞
   if(this[(shape[i+1]- -y)*100- -(shape[i]- -x)])
    flag = true;
  }
  // 判断是否到达极限高度
  for(var m=0;m<3;m++)
   for(var n=0;n<col;n++)
    if(this[m*100+n])
     flag = true;
  if((rightmost- -x+1)>col || (leftmost- -x)<0 || (undermost- -y+1)>row || flag)
   return false;
  return true;
 }
 // 用灰色方块替换红色方块,并在容器中记录灰色方块的位置
 this.fixShape = function(x,y,shape)
 {
  var t = new Tetris("d",x,y,shape);
  for(var i=0;i<8;i+=2)
   this[(shape[i+1]- -y)*100- -(shape[i]- -x)] = t.divs[i/2];
 }
 // 遍历整个容器,判断是否可以消除
 this.findFull = function()
 {
  var s = 0;
  for(var m=0;m<row;m++)
  {
   var count = 0;
   for(var n=0;n<col;n++)
    if(this[m*100+n])
     count++;
   if(count==col)
   {
    s++;
    this.removeLine(m);
   }
  }
  this.score -= -this.calScore(s);
 }
 this.calScore = function(s)
 {
  if(s!=0)
   return s- -this.calScore(s-1)
  else
   return 0;
 }
 // 消除指定一行方块
 this.removeLine = function(row)
 {
  // 移除一行方块
  for(var n=0;n<col;n++)
   document.body.removeChild(this[row*100+n]);
  // 把所消除行上面所有的方块下移一行
  for(var i=row;i>0;i--)
  {
   for(var j=0;j<col;j++)
   {
    this[i*100- -j] = this[(i-1)*100- -j]
    if(this[i*100- -j])
     this[i*100- -j].style.top = i*size + "px";
   }
  }
 }
}
function init()
{
 container = new Container();
 container.init();
 tetris = new Tetris();
 tetris.container = container;
 document.onkeydown = function(e)
 {
  if(isOver) return;
  var e = window.event?window.event:e;
  switch(e.keyCode)
  {
   case 38: //up
    tetris.rotate();
    break;
   case 40: //down
    tetris.vMove(1);
    break;
   case 37: //left
    tetris.hMove(-1);
    break;
   case 39: //right
    tetris.hMove(1);
    break;
  }
 }
 setInterval("if(!isOver) tetris.vMove(1)",500);
}
</script>
</head>
<body onload="init()">
</body>
</html>

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
js兼容标准的表格变色效果
Jun 28 Javascript
javascript 必知必会之closure
Sep 21 Javascript
jQuery中noconflict函数的实现原理分解
Feb 03 Javascript
在AngularJS中使用AJAX的方法
Jun 17 Javascript
JQuery移动页面开发之屏幕方向改变与滚屏的实现
Dec 03 Javascript
Bootstrap 网站实例之单页营销网站
Oct 20 Javascript
Bootstrap CSS布局之代码
Dec 17 Javascript
Vue页面骨架屏的实现方法
May 22 Javascript
JavaScript箭头函数中的this详解
Jun 19 Javascript
纯JS实现五子棋游戏
May 28 Javascript
解决Vue router-link绑定事件不生效的问题
Jul 22 Javascript
SpringBoot+Vue开发之Login校验规则、实现登录和重置事件
Oct 19 Javascript
用NODE.JS中的流编写工具是要注意的事项
Mar 01 #Javascript
JS实现图片平面旋转的方法
Mar 01 #Javascript
JS显示日历和天气的方法
Mar 01 #Javascript
jQuery使用模式窗口实现在主页面和子页面中互相传值的方法
Mar 01 #Javascript
jQuery获取某天的农历日期并判断是否除夕或新年的方法
Mar 01 #Javascript
jQuery实现获取table表格第一列值的方法
Mar 01 #Javascript
JavaScript Date对象详解
Mar 01 #Javascript
You might like
缅甸的咖啡简史
2021/03/04 咖啡文化
php学习笔记 面向对象的构造与析构方法
2011/06/13 PHP
初识Laravel
2014/10/30 PHP
PHP自定session保存路径及删除、注销与写入的方法
2014/11/18 PHP
jquery 操作表格实现代码(多种操作打包)
2011/03/20 Javascript
AngularJS基础学习笔记之指令
2015/05/10 Javascript
JavaScript_ECMA5数组新特性详解
2016/06/12 Javascript
详解Javascript中prototype属性(推荐)
2016/09/03 Javascript
JS 获取HTML标签内的子节点的方法
2016/09/21 Javascript
BootStrap轻松实现微信页面开发代码分享
2016/10/21 Javascript
深入nodejs中流(stream)的理解
2017/03/27 NodeJs
Vue中的v-cloak使用解读
2017/03/27 Javascript
Javascript 详解封装from表单数据为json串进行ajax提交
2017/03/29 Javascript
vue+axios实现登录拦截的实例代码
2017/05/22 Javascript
Vue精简版风格指南(推荐)
2018/01/30 Javascript
用node.js写一个jenkins发版脚本
2019/05/21 Javascript
Vue 实例事件简单示例
2019/09/19 Javascript
为什么Vue3.0使用Proxy实现数据监听(defineProperty表示不背这个锅)
2019/10/14 Javascript
[38:27]完美世界DOTA2联赛PWL S2 Forest vs FTD.C 第二场 11.26
2020/11/30 DOTA
python在windows下实现备份程序实例
2014/07/04 Python
python进阶教程之词典、字典、dict
2014/08/29 Python
python登陆asp网站页面的实现代码
2015/01/14 Python
浅谈Python浅拷贝、深拷贝及引用机制
2016/12/15 Python
Django 登陆验证码和中间件的实现
2018/08/17 Python
python实现蒙特卡罗方法教程
2019/01/28 Python
python绘制彩虹图
2019/12/16 Python
Python私有属性私有方法应用实例解析
2020/09/15 Python
美国诺德斯特龙百货官网:Nordstrom
2016/08/23 全球购物
Stubhub英国:购买体育、演唱会和剧院门票
2018/06/10 全球购物
护理专业毕业生自我鉴定
2013/10/08 职场文书
项目负责人任命书
2014/06/04 职场文书
稽核岗位职责
2015/02/10 职场文书
优质服务标语口号
2015/12/26 职场文书
《绝招》教学反思
2016/02/20 职场文书
85句关于理想的名言警句大全
2019/08/22 职场文书
关于React Native 无法链接模拟器的问题
2021/06/21 Javascript