文档章节

一个简单的俄罗斯方块游戏脚本

 一笑乃过
发布于 2017/06/18 20:19
字数 1948
阅读 8
收藏 0
点赞 0
评论 0

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}

body {
font-family: "Microsoft Yahei";
background: pink;
color: #333;
}

a{
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;

}

.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>
</head>
<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>
</html>
<script type="text/javascript" src="jquery-1.12.4.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>

© 著作权归作者所有

共有 人打赏支持
粉丝 1
博文 3
码字总数 2425
作品 0
C++ 实现俄罗斯方块

说明:文章内容均截选自用户“Gamerchen”发布在实验楼上的教程【C++ 实现俄罗斯方块】,未经允许,禁止转载; 俄罗斯方块是很多人的入门游戏啊,小时候常常拿着游戏机玩,现在学了编程,你是...

实验楼 ⋅ 2017/12/20 ⋅ 0

益智游戏--hextris

hextris 是一个快节奏的简单益智游戏,灵感来自于俄罗斯方块。

孔小菜 ⋅ 2015/06/26 ⋅ 0

在STM32F103上编写一个俄罗斯方块游戏

在STM32F103上编写一个俄罗斯方块游戏 代码和视频请在http://dl.dbank.com/c0vhnwzwx4下载 我手边有一块STM32F103VB的板子,在这个板子上有一个LCD显示屏和5个按键,正好可以用来做俄罗斯方块...

ifreecoding ⋅ 2012/09/08 ⋅ 0

yetris 2.0.0 发布,命令行下的俄罗斯方块

yetris 2.0.0 发布,此版本已经完全使用 C++ 编写了一个全新的界面,对游戏进行了改进。 yetris 是一个基于终端运行的俄罗斯方块游戏,有颜色显示和最高分显示,一般俄罗斯方块游戏有的功能在...

oschina ⋅ 2014/03/07 ⋅ 0

yetris —— Linux 控制台下的俄罗斯方块

yetris 是一个基于终端运行的俄罗斯方块游戏,有颜色显示和最高分显示,一般俄罗斯方块游戏有的功能在 yetris 上基本上都有。

oschina ⋅ 2013/02/19 ⋅ 0

分享几个令人震撼的JS和HTML5游戏

或许你对网页游戏仅仅停留在Flash的时代,认为只有Flash才能做出非常绚丽的游戏特效。那么今天就打破大家的这个观念,一起来看看用Javascript和HTML5实现的网页游戏,这些游戏个人认为做得已...

tp_wire ⋅ 2012/06/27 ⋅ 20

yetris 1.7 发布,命令行下的俄罗斯方块

yetris 1.7 增加高分榜,可在游戏时通过 F3 键显示;新版本支持 OS X;修复了一些小 bug。 yetris 是一个基于终端运行的俄罗斯方块游戏,有颜色显示和最高分显示,一般俄罗斯方块游戏有的功能...

oschina ⋅ 2013/03/05 ⋅ 2

yetris 1.5 发布,控制台下的俄罗斯方块

yetris 1.5 增加了帮助窗口用来说明游戏的控制方法,增加了一些定制颜色,更平滑的接口,修复了很多 bug。 yetris 是一个基于终端运行的俄罗斯方块游戏,有颜色显示和最高分显示,一般俄罗斯...

oschina ⋅ 2013/02/25 ⋅ 2

Swing俄罗斯游戏编写详解(附源码)

俄罗斯方块游戏是一个上手简单,老少皆宜的游戏,它的基本规则是移动、旋转和摆放游戏自动产生的各种方块,使之排列成完整的一行或多行并且消除得分。 你能学到什么? 通过本文的阅读,读者可...

王孟君 ⋅ 2016/10/28 ⋅ 0

Java 大白话讲解设计模式之 -- 策略模式

声明:原创作品,转载请注明出处https://www.jianshu.com/p/4d53aa2adb22 在开始说设计模式之前,让我们先聊点别的东西,相信每个人都有自己难忘的童年时光,在那时有很多有趣好玩的事物陪伴...

蛇发女妖 ⋅ 2017/12/24 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Mahout基于内存的DataMode 推荐引擎Demo2

Mahout基于内存的DataMode 推荐引擎Demo2 //注释的部分是基于文件也可以理解为基于日志文件的, //DataModel 可以有很多种,实现abstractDataMode的子类,原则上都可以作为数据源,个人觉得,...

xiaomin0322 ⋅ 22分钟前 ⋅ 0

Docker部署Tomcat及Web应用

一、在线下载docker yum install -y epel-releaseyum install docker-io # 安装dockerchkconfig docker on # 加入开机启动service docker start # 启动docker服务 1 ...

Jeam_ ⋅ 22分钟前 ⋅ 0

研发运营一体化能力成熟度模型

研发运营一体化是指在 IT 软件及相关服务的研发及交付过程中,将应用的需求、开发、测试、部 署和运营统一起来,基于整个组织的协作和应用架构的优化,实现敏捷开发、持续交付和应用运营的无...

stars永恒 ⋅ 27分钟前 ⋅ 0

jQuery缩小放大触发事件

jquery的resize()方法使用 <html> <head> <script type="text/javascript" src="/jquery/jquery.js"></script> <script type="text/javascript"> var i = 0; $(document).ready(function(){ ......

RobertZou ⋅ 28分钟前 ⋅ 0

eclipse python 搭建

https://jingyan.baidu.com/article/9113f81b68ebce2b3214c7e0.html https://www.cnblogs.com/ZhangRuoXu/p/6397756.html https://blog.csdn.net/zhangphil/article/details/78962159 字符集......

之渊 ⋅ 28分钟前 ⋅ 0

weex,react native,flutter

weex: 一次编写,处处运行 RN: 学一次,到处写(针对安卓,IOS平台特性 各自写,会有很大一部分是一样的代码) 这些方案是否真正的解决了跨平台问题呢?从目前的状况来看,很显然是没有的,因...

东东笔记 ⋅ 34分钟前 ⋅ 0

Spring Cloud微服务分布式云架构-集成项目

Spring Cloud集成项目有很多,下面我们列举一下和Spring Cloud相关的优秀项目,我们的企业架构中用到了很多的优秀项目,说白了,也是站在巨人的肩膀上去整合的。在学习Spring Cloud之前大家必...

明理萝 ⋅ 39分钟前 ⋅ 1

SpringMVC图片上传问题解决

当我们上传图片时一直发现: MultipartFile file = null; if (request instanceof MultipartHttpServletRequest) 匹配不上, 解决方案: 在前端xml加入如下配置代码即可 <!-- 图片上传bean --...

泉天下 ⋅ 41分钟前 ⋅ 0

Spring表达式语言(SpEL)

1、SpEL引用 Spring EL在bean创建时执行其中的表达式。此外,所有的Spring表达式都可以通过XML或注解的方式实现。下面将使用Spring表达式语言(SpEL),注入字符串,整数,Bean到属性。 SpEL的...

霍淇滨 ⋅ 57分钟前 ⋅ 0

Gradle使用阿里云镜像

gradle 生命周期中有一个初始化( Initialization )的过程,这个过程运行在 build script 之前,我们可以在这个地方做一点系统全局的设置,如配置仓库地址。 你可以在以下几个位置实现仓库地址...

明MikeWoo ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部