js html5 css俄罗斯方块游戏再现

这个游戏主要分为三部份,HTML5+CSS+JAVASCRIPT来完成的。在这里详细讲一下js的代码。因为这个游戏的主要部分其实就是js。

大多数都是靠js来完成的。

完成后的效果如下:

HTML代码:

<body>
 <div class="wrap">
 <div class="play_wrap">
 <div id="play_area"></div>
 <div class="play_menu">
 <p>下一个:</p>
 <div id="play_nextType"></div>
 <a id="play_btn_start" class="play_btn" href="javascript:void(0);"
 unselectable="on">开始</a><a id="play_btn_level" class="play_btn" href="javascript:void(0)" unselectable="on"><span class="level_text">中等</span class="level_icon"></span></a>
 <div class="level_menu" id="play_menu_level">
 <ul>
 <li><a href="javascript:void(0)" level=0>简单</a></li>
 <li><a href="javascript:void(0)" level=1>中等</a></li>
 <li><a href="javascript:void(0)" level=2>困难</a></li>
 </ul>
 </div>
 <p>
 分数:<span id="play_score">0</span>
 </p>
 <p>
 方向:<span id="play_direction">bottom</span>
 </p>
 <p>
 说明:<br> -“下”、“左”、“右”键控制方向,“上”为变形;<br> -游戏开始前、暂停时可调整难度;<br>
 -难度分“简单”、“中等”、“困难”三级;<br> -对应的分值为10、20、40;<br>
 -多行同时消去的倍数为1、4、10、20;
 </p>
 </div>
 </div>
 </div>
 </body>

CSS代码:

<style>
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,button,textarea,p,blockquote,th,td
{
 padding: 0;
 margin: 0;
} 

body {
 font-family: "Helvetica Neue", "Hiragino Sans GB", "Segoe UI",
 "Microsoft Yahei", "微软雅黑", Tahoma, Arial, STHeiti, sans-serif;
 font-size: 12px;
 background: #fff;
 color: #333;
} 

a{
 outline:none;
 -moz-outline:none;
 text-decoration: none;
} 

.wrap{
 width:1000px;
 margin:80px auto;
} 

.play_wrap{
 padding-left:260px;
} 

#play_area{
 float:left;
 width:300px;
 height:480px;
 margin:auto;
 background-color:#fefefe;
 border-radius:2px;
 color:black;
 box-shadow:0px 0px 8px #e5e5e5;
 padding:1px 0 0 1px;
} 

#play_area .play_cell{
 float:left;
 width:19px;
 height:19px;
 border:1px solid #eee;
 margin:-1px 0 0 -1px;
} 

#play_area .play_cell.active{
 background:#999;
 border:1px solid #ccc;
} 

#play_area .play_cell.goal{
 background:#0c0;
} 

.play_menu{
 float:left;
 margin-left:60px;
 font-size:14px;
 padding-top:20px;
} 

.play_menu #play_nextType{
 width:60px;
 height:60px;
 padding:1px 0 0 1px;
 margin:10px 0 20px 0;
} 

.play_menu .play_mini_cell{
 float:left;
 width:14px;
 height:14px;
 border:1px solid #fff;
 margin:-1px 0 0 -1px;
} 

.play_menu .play_mini_cell.active{
 background:#999;
 border:1px solid #ccc;
} 

.play_menu p {
 line-height:200%;
 clear:both;
} 

.play_menu a.play_btn{
 display:block;
 margin-bottom:20px;
 width:80px;
 height:28px;
 line-height:28px;
 text-align:center;
 text-decoration: none;
 color:#333;
 background:#fefefe;
 border:1px solid #eee;
 border-radius: 2px;
 box-shadow: 1px 1px 2px #eee;
 border-color:#ddd #d2d2d2 #d2d2d2 #ddd;
 outline: none;
 -moz-outline:none;
} 

.play_menu a.play_btn:hover{
 background-color:#fcfcfc;
 border-color:#ccc;
 box-shadow: inset 0 -2px 6px #eee;
} 

.play_menu a#play_btn_level{
 position:relative;
 margin-bottom:30px;
} 

.level_text{
 margin-left:-10px;
} 

.level_icon{
 display: block;
 position:absolute;
 top:12px;
 right:16px;
 width:0;
 height:0;
 overflow: hidden;
 border:5px solid #FFF;
 border-color: #999 transparent transparent transparent;
} 

.level_menu{
 position:absolute;
 margin:-30px 0 0 1px;
 display:none;
}
.level_menu ul{
 list-style:none;
}
.level_menu li{
 float:left;
}
.level_menu li a{
 display:block;
 padding:3px 10px;
 border:1px solid #e8e8e8;
 margin-left:-1px;
 color:#09c;
}
.level_menu li a:hover{
 background:#09c;
 color:#fefefe;
}
</style>

HTML的代码其实就是一个游戏结构的框架,这里框架其实就是几个div的东西,所以不会太长,理解起来也是挺容易的。而CSS则是控制网页的布局与美观,所以要想吸引玩家,那CSS方面必须下功夫,而这里的CSS只是其实就将游戏区域与菜单区域分为左右两边了。而游戏域内的一个个框其实就是多个div,整齐排列在一起而已。

下面到了js了:

因为在代码已经将一些重要的部分做了注释,所以就不打算逐步分去分析了。说一下整体的写法吧。其实它首先是直接定义了一些图形的坐标,然后根据这些坐标画出一个下一个的图形出来,之后就是利用一个setInterval函数在游戏区域标出每个点,如果不能下落了就直接清除掉时间函数,之后在调用一个创建时间函数的函数出来,在画一个图形出来。具体的细节就看代码吧。

<script type="text/javascript" src="jquery-1.6.2.min.js"></script>
 <script type="text/javascript">
 var Tetris = function(options){
 //方块区域
 this.e_playArea = $("#play_area");
 //开始按钮
 this.e_startBtn = $("#play_btn_start");
 //分数
 this.e_playScore = $("#play_score");
 //方向
 this.e_playDirection = $("#play_direction");
 //等级按钮
 this.e_levelBtn = $("#play_btn_level");
 //等级菜单
 this.e_levelMenu = $("#play_menu_level");
 //下一个方块的类型
 this.e_nextType = $("#play_nextType");
 //总的列数
 this.cellCol = 15;
 //总的行数
 this.cellRow = 24;
 //每个小方块的属性数组
 this.cellArr = [];
 //保存右上方下一个那里的小图形数组
 this.miniCellArr = [];
 //分数
 this.score = 0;
 //方向
 this.direction = "bottom";
 //定时器的ID
 this.timer = null;
 //定时器的时间数组
 this.interval = [600,300,100];
 //等级的分数数组
 this.levelScore = [10,20,40];
 //消除的行数多少而给的倍数
 this.doubleScore = [1,4,10,20];
 //默认等级1
 this.level = 1;
 //游戏是否进行
 this.playing = false;
 //游戏暂停标记
 this.turning = false;
 //游戏结束标记
 this.death = false;
 //一开始方块列出现的位置
 this.offsetCol = Math.floor(this.cellCol/2);
 //一开始方块行出现的位置
 this.offsetRow = -3; 

 this.tetrisArr = [];
 /*
 0,1,15,16
 0,1,15,16
 */
 this.tetrisArr[0] = [
 [0,1,this.cellCol,this.cellCol+1],
 [0,1,this.cellCol,this.cellCol+1]
 ];
 /*
 1,14,15,16
 0,15,30,31
 14,15,16,29
 -1,0,15,30
 */
 this.tetrisArr[1] = [
 [1,this.cellCol-1,this.cellCol,this.cellCol+1],
 [0,this.cellCol,this.cellCol*2,this.cellCol*2+1],
 [this.cellCol-1,this.cellCol,this.cellCol+1,this.cellCol*2-1],
 [-1,0,this.cellCol,this.cellCol*2]
 ];
 /*
 -1,14,15,16
 0,1,15,30
 14,15,16,31
 0,15,29,30
 */
 this.tetrisArr[2] = [
 [-1,this.cellCol-1,this.cellCol,this.cellCol+1],
 [0,1,this.cellCol,this.cellCol*2],
 [this.cellCol-1,this.cellCol,this.cellCol+1,this.cellCol*2+1],
 [0,this.cellCol,this.cellCol*2-1,this.cellCol*2]
 ];
 /*
 0,15,16,31
 15,16,29,30
 */
 this.tetrisArr[3] = [
 [0,this.cellCol,this.cellCol+1,this.cellCol*2+1],
 [this.cellCol,this.cellCol+1,this.cellCol*2-1,this.cellCol*2]
 ];
 /*
 0,14,15,29
 14,15,30,31
 */
 this.tetrisArr[4] = [
 [0,this.cellCol-1,this.cellCol,this.cellCol*2-1],
 [this.cellCol-1,this.cellCol,this.cellCol*2,this.cellCol*2+1]
 ];
 /*
 0,14,15,16
 0,15,16,30
 14,15,16,30
 0,14,15,30
 */
 this.tetrisArr[5] = [
 [0,this.cellCol-1,this.cellCol,this.cellCol+1],
 [0,this.cellCol,this.cellCol+1,this.cellCol*2],
 [this.cellCol-1,this.cellCol,this.cellCol+1,this.cellCol*2],
 [0,this.cellCol-1,this.cellCol,this.cellCol*2]
 ];
 /*
 0,15,30,45
 14,15,16,17
 */
 this.tetrisArr[6] = [
 [0,this.cellCol,this.cellCol*2,this.cellCol*3],
 [this.cellCol-1,this.cellCol,this.cellCol+1,this.cellCol+2]
 ];
 this.tetrisType = [1,1];
 this.tetrisType = [1,0];
 this.tetrisTypeArr = []; 

 this.preTetris = [];
 this.thisTetris = [];
 this.fullArr = []; 

 this.start();
 }
 Tetris.prototype = {
 //开始入口函数
 start : function(){
 this.init();
 this.menu();
 this.control();
 },
 //选择设置
 setOptions : function(options){
 this.score = options.score === 0 ? options.score
 : (options.score || this.score);
 this.level = options.level === 0 ? options.level
 : (options.level || this.level);
 },
 resetArea : function(){
 $(".play_cell.active").removeClass("active");
 this.setOptions({
 "score" : 0
 });
 this.e.playScore.html(this.score);
 },
 //菜单
 menu : function(){
 var self = this;
 this.e_startBtn.click(function(){
 self.e_levelMenu.hide();
 if(self.playing){
 self.pause();
 } else if(self.death){
 self.resetArea();
 self.play();
 } else {
 self.play();
 }
 });
 this.e_levelBtn.click(function(){
 if(self.playing)return;
 self.e_levelMenu.toggle();
 });
 this.e_levelMenu.find("a").click(function(){
 self.e_levelMenu.hide();
 self.e_levelBtn.find(".level_text").html($(this).html());
 self.setOptions({
 "level" : $(this).attr("level")
 });
 });
 },
 play : function(){
 var self = this;
 this.e_startBtn.html("暂停");
 this.playing = true;
 this.death = false;
 if(this.turning){
 this.timer = setInterval(function(){
 self.offsetRow++;
 self.showTetris();
 },this.interval[this.level]);
 } else {
 this.nextTetris();
 }
 },
 pause : function(){
 this.e_startBtn.html("开始");
 this.playing = false;
 clearTimeout(this.timer);
 },
 //初始化游戏
 init : function(){
 var self =this,_ele,_miniEle,_arr = [];
 //创建小方块放进cellArr里
 for(var i=0;i<this.cellCol;++i){
 for(var j=0;j<this.cellRow;++j){
 _ele = document.createElement("div");
 _ele.className = "play_cell";
 _ele.id = "play_cell_"+ i + "_" + j;
 this.cellArr.push($(_ele));
 this.e_playArea.append(_ele);
 }
 }
 //创建下一个图形的小方块
 for(var m=0;m<16;++m){
 _miniEle = document.createElement("div");
 _miniEle.className = "play_mini_cell";
 this.miniCellArr.push($(_miniEle));
 this.e_nextType.append(_miniEle);
 }
 //保存三维数组tetrisArr的前两维数据编号,k为其第一维编号,j为其二维
 for(var k=0,klen=this.tetrisArr.length;k<klen;++k){
 for(var j=0,jlen=this.tetrisArr[k].length;j<jlen;++j){
 this.tetrisTypeArr.push([k,j]);
 }
 }
 //下一个图形的【x】【y】
 this.nextType = this.tetrisTypeArr[Math.floor(this.tetrisTypeArr.length*Math.random())];
 this.showNextType();
 },
 //按键控制函数
 control : function(){
 var self = this;
 $("html").keydown(function(e){
 if(!self.playing)
 return !self.playing;
 switch(e.keyCode){
 case 37:
 self.direction = "left";
 break;
 case 38:
 self.direction = "top";
 break;
 case 39:
 self.direction = "right";
 break;
 case 40:
 self.direction = "bottom";
 break;
 default:
 return;
 break;
 }
 //显示当前的按键操作
 self.e_playDirection.html(self.direction);
 //实行按键的操作函数
 self.drive();
 return false;
 });
 },
 //改变图形的状态
 changTetris : function(){
 var _len = this.tetrisArr[this.tetrisType[0]].length;
 if(this.tetrisType[1] < _len-1){
 this.tetrisType[1]++;
 } else {
 this.tetrisType[1] = 0;
 }
 },
 //按键的操作函数
 drive : function(){
 switch(this.direction){
 case "left":
 if(this.offsetCol>0){
 this.offsetCol--;
 }
 break;
 case "top":
 this.changTetris();
 break;
 case "right":
 this.offsetCol++;
 break;
 case "bottom":
 if(this.offsetRow<this.cellRow-2){
 this.offsetRow++;
 }
 break;
 default:
 break;
 }
 //显示图形的函数
 this.showTetris(this.direction);
 },
 //显示图形的函数
 showTetris : function(dir){
 var _tt = this.tetrisArr[this.tetrisType[0]][this.tetrisType[1]],_ele,self=this;
 this.turning = true;
 this.thisTetris = [];
 for(var i=_tt.length-1;i>=0;--i){
 _ele = this.cellArr[_tt[i]+this.offsetCol+this.offsetRow*this.cellCol];
 //规定左右移动不能超出边框
 if(this.offsetCol<7&&(_tt[i]+this.offsetCol+1)%this.cellCol==0){
 this.offsetCol++;
 return;
 }else if(this.offsetCol>7&&(_tt[i]+this.offsetCol)%this.cellCol==0){
 this.offsetCol--;
 return;
 }
 //判断是否下落是与方块碰撞了,排除向左移动时碰到左边的方块而停止下落
 if(_ele&&_ele.hasClass("active")&&dir=="left"&&($.inArray(_ele,this.preTetris)<0)){
 if(($.inArray(_ele,this.cellArr)-$.inArray(this.preTetris[i],this.cellArr))%this.cellCol!=0){
 this.offsetCol++;
 return;
 }
 }
 if(_ele&&_ele.hasClass("active")&&dir=="right"&&($.inArray(_ele,this.preTetris)<0)){
 if(($.inArray(_ele,this.cellArr)-$.inArray(this.preTetris[i],this.cellArr))%this.cellCol!=0){
 this.offsetCol--;
 return;
 }
 }
 //找到某个div进行下落的过程
 //否则找不到直接结束下落的过程
 if(_ele){
 //找到一个div有class=active,而且不是上一次自身的位置,那么就停止
 //向下走了,因为遇到障碍物了
 //否则这个div符合,存起来
 if(_ele.hasClass("active")&&($.inArray(_ele,this.preTetris)<0)){
 this.tetrisDown();
 return;
 } else {
 this.thisTetris.push(_ele);
 }
 } else if(this.offsetRow>0){
 this.tetrisDown();
 return;
 }
 }
 //将上一次的位置的标记全部去除
 for(var j=0,jlen=this.preTetris.length;j<jlen;++j){
 this.preTetris[j].removeClass("active");
 }
 //标记这一次的位置
 for(var k=0,klen=this.thisTetris.length;k<klen;k++){
 this.thisTetris[k].addClass("active");
 }
 //储存起现在的位置,会成为下一次的前一次位置
 this.preTetris = this.thisTetris.slice(0);
 },
 //无法下落时进行的函数
 tetrisDown : function(){
 clearInterval(this.timer);
 var _index;
 this.turning = false;
 //是否填充满一行的检测
 forOuter:for(var j=0,jlen=this.preTetris.length;j<jlen;++j){
 _index = $.inArray(this.preTetris[j],this.cellArr);
 for(var k=_index-_index%this.cellCol,klen=_index-_index%this.cellCol+this.cellCol;k<klen;++k){
 if(!this.cellArr[k].hasClass("active")){
 continue forOuter;
 }
 }
 if($.inArray(_index-_index%this.cellCol,this.fullArr)<0)
 this.fullArr.push(_index-_index%this.cellCol);
 }
 if(this.fullArr.length){
 this.getScore();
 return;
 }
 //如果图形在6-9的div内被标记,那么游戏结束
 for(var i=6;i<9;++i){
 if(this.cellArr[i].hasClass("active")){
 this.gameOver();
 alert("you lost!");
 return;
 }
 }
 this.nextTetris();
 },
 //下一个图形
 nextTetris : function(){
 var self = this;
 clearInterval(this.timer);
 this.preTetris = [];
 this.offsetRow = -2;
 this.offsetCol = 7;
 this.tetrisType = this.nextType;
 this.nextType = this.tetrisTypeArr[Math.floor(this.tetrisTypeArr.length*Math.random())];
 this.showNextType();
 this.timer = setInterval(function(){
 self.offsetRow++;
 self.showTetris();
 },this.interval[this.level]);
 },
 showNextType : function(){
 //_nt为找到在this.nextType[0]行,this.nextType[1]列的一行数据
 var _nt = this.tetrisArr[this.nextType[0]][this.nextType[1]],_ele,_index;
 //找到class=active的元素,之后全部删除class元素
 this.e_nextType.find(".active").removeClass("active");
 for(var i=0,ilen=_nt.length;i<ilen;++i){
 //因为offsetCol的最小值只能为2,所以在tetrisArr数组中赋的值都减了2
 //这里要加回2来处理,才能在小的视图里安放图形
 if(_nt[i]>this.cellCol-2){
 _index = (_nt[i]+2)%this.cellCol-1+4*parseInt((_nt[i]+2)/this.cellCol);
 }else{
 _index = _nt[i] + 1;
 }
 _ele = this.miniCellArr[_index];
 _ele.addClass("active");
 }
 },
 //获取分数
 getScore : function(){
 var self = this;
 //对完整的行消除,对元素进行向下移动
 for(var i=this.fullArr.length-1;i>=0;--i){
 for(var j=0;j<this.cellCol;++j){
 this.cellArr[j+this.fullArr[i]].removeClass("active");
 if(j==this.cellCol-1){
 for(var k=this.fullArr[i];k>=0;--k){
 if(this.cellArr[k].hasClass("active")){
  this.cellArr[k].removeClass("active");
  this.cellArr[k+this.cellCol].addClass("active");
 }
 }
 }
 }
 }
 this.score += this.levelScore[this.level]*this.doubleScore[this.fullArr.length-1];
 this.e_playScore.html(this.score);
 this.fullArr = [];
 this.nextTetris();
 },
 //游戏结束
 gameOver : function(){
 this.death = true;
 this.pause();
 return;
 }
 };
 $(document).ready(function(e){
 var t = new Tetris();
 });
 </script> 

源码下载:http://xiazai.jb51.net/201610/yuanma/js-html5els(jb51.net).rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • JS俄罗斯方块,包含完整的设计理念

    下面是俄罗斯方块的截图: 请到这里下载源码: 俄罗斯方块 在线演示 下载地址下面是代码: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml&q

  • Linux下用C++实现俄罗斯方块

    本文实例为大家分享了C++实现俄罗斯方块游戏代码,供大家参考,具体内容如下 1.block.c #include <stdio.h> #include <termios.h> #include <unistd.h> #include <stdlib.h> #include <setjmp.h> #include <sys/time.h> #include <string.h> #include "block.h&

  • 一个MIDP俄罗斯方块游戏的设计和实现

    文章来源:csdn 作者:陈万飞 作者简介 陈万飞,男,中南大学数软系学士,曾任北京长城软件高级程序员,系统分析师.有较为丰富的j2se,j2ee开发经验.目前致力于j2me研究工作.可通过chen_cwf@163.net与他联系 摘要 本文给出了一个基于MIDP1.0的俄罗斯方块游戏的设计方案,并给出全部实现源代码.该游戏的最大特色是屏幕自适应,无论各种手机,PDA的屏幕大小如何,该游戏总是能获得最佳的显示效果.游戏在J2me wireless toolkit 2.1的4种模拟器上测试通过.

  • 60行js代码实现俄罗斯方块

    这是我之前网上看到的,很牛逼的一位大神写的,一直膜拜中 <!doctype html><html><head></head><body> <div id="box" style="width:252px;font:25px/25px 宋体;background:#000;color:#9f9;border:#999 20px ridge;text-shadow:2px 3px 1px #0f0;"&g

  • C++俄罗斯方块游戏 无需图形库的俄罗斯方块

    本文实例为大家分享了C++俄罗斯方块游戏的具体实现代码,供大家参考,具体内容如下. #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<time.h> #include<conio.h> #define MOD 28 #define SIZE_N 19 #define SIZE_M 12 int cur_x,cur_y; int score,mark,next,map

  • javascript实现俄罗斯方块游戏的思路和方法

    观摩一下<编程之美>:"程序虽然很难写,却很美妙.要想把程序写好,需要写好一定的基础知识,包括编程语言.数据结构与算法.程序写得好,需要缜密的逻辑思维能力和良好的梳理基础,而且熟悉编程环境和编程工具." 学了几年的计算机,你有没有爱上编程.话说,没有尝试自己写过一个游戏,算不上热爱编程. 俄罗斯方块曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事,它看似简单但却变化无穷,令人上瘾.相信大多数同学,曾经为它痴迷得茶不思饭不想. 游戏规则 1.一个用于摆放小型正方形的平

  • Java俄罗斯方块小游戏

    去年就已经学了这个技术了,一直没去写,现在抽个时间写了个俄罗斯方块游戏. 只有简单的新游戏,暂停,继续,积分功能.简单的实现了俄罗斯的经典功能. 不介绍了,有兴趣的自己运行一下,后面贴出了图片. 代码: package cn.hncu; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.Act

  • JS 俄罗斯方块完美注释版代码

    R #board tr td{ width: 20px; height: 20px; } /** * JS俄罗斯方块完美注释版 v 1.01 * 从学c语言那一会儿都想写一个俄罗斯方块,可是每次动起手总觉得难度太大. * 今天终于用了大约4个小时写出来了. 其中在涉及到方块变型的时候还咨询了 * 同学来帮忙; * * 个人觉得难点有这么几个: * 1: 边界检查, 不多说, 想通了就行 * 2: 旋转, 还是数学上的方法, 一个点相对另外一个点旋转90度的问题. * 4: 让整个程序在点开始之后

  • shell脚本编写的俄罗斯方块游戏代码

    粘贴以下代码到一个空的Shell脚本文件中,并在Bash 中运行即可! 复制代码 代码如下: #!/bin/bash # Tetris Game# 10.21.2003 xhchen<[email]xhchen@winbond.com.tw[/email]> #APP declarationAPP_NAME="${0##*[\\/]}"APP_VERSION="1.0" #颜色定义cRed=1cGreen=2cYellow=3cBlue=4cFuchsi

  • 用Python编写一个简单的俄罗斯方块游戏的教程

    俄罗斯方块游戏,使用Python实现,总共有350+行代码,实现了俄罗斯方块游戏的基本功能,同时会记录所花费时间,消去的总行数,所得的总分,还包括一个排行榜,可以查看最高记录. 排行榜中包含一系列的统计功能,如单位时间消去的行数,单位时间得分等. 附源码: from Tkinter import * from tkMessageBox import * import random import time #俄罗斯方块界面的高度 HEIGHT = 18 #俄罗斯方块界面的宽度 WIDTH = 10

随机推荐