javascript实现俄罗斯方块游戏
观摩一下《编程之美》:“程序虽然很难写,却很美妙。要想把程序写好,需要写好一定的基础知识,包括编程语言、数据结构与算法。程序写得好,需要缜密的逻辑思维能力和良好的梳理基础,而且熟悉编程环境和编程工具。”
学了几年的计算机,你有没有爱上编程。话说,没有尝试自己写过一个游戏,算不上热爱编程。
俄罗斯方块曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事,它看似简单但却变化无穷,令人上瘾。相信大多数同学,曾经为它痴迷得茶不思饭不想。
游戏规则
1、一个用于摆放小型正方形的平面虚拟场地,其标准大小:行宽为10,列高为20,以每个小正方形为单位。
2、一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。
I:一次最多消除四层
J(左右):最多消除三层,或消除二层
L:最多消除三层,或消除二层
O:消除一至二层
S(左右):最多二层,容易造成孔洞
Z (左右):最多二层,容易造成孔洞
T:最多二层
方块会从区域上方开始缓慢继续落下。玩家可以以90度为单位旋转方块,以格子为单位左右移动方块,让方块加速落下。方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。当区域中某一列横向格子全部由方块填满,则该列会消失并成为玩家的得分。同时删除的列数越多,得分指数上升。
分析与解法
每块方块落下的过程中,我们可以做:
1)旋转到合适的方向
2)水平移动到某一列
3)垂直下落到底部
首先,需要用一个二维数组,area[18][10]表示18*10的游戏区域。其中,数组中值为0表示空,1表示有方块。
方块一共7种,每种有4种方向。定义activeBlock[4],在编译之前这个数组的值预定算好,在程序中直接使用。
难点
1)边界检查。
//检查左边界,尝试着朝左边移动一个,看是否合法。
function checkLeftBorder(){
for(var i=0; i<activeBlock.length; i++){
if(activeBlock[i].y==0){
return false;
}
if(!isCellValid(activeBlock[i].x, activeBlock[i].y-1)){
return false;
}
}
return true;
} //同理,需要检测右边界和底边界
2)旋转, 需要数理逻辑, 一个点相对另外一个点旋转90度的问题。
3)定时和监听键盘事件机制让游戏自动运行下去。
//开始
function begin(e){
e.disabled = true;
status = 1;
tbl = document.getElementById("area");
if(!generateBlock()){
alert("Game over!");
status = 2;
return;
}
paint();
timer = setInterval(moveDown,1000);
}
document.onkeydown=keyControl;
程序过程
1)用户点开始->构造一个活动图形, 设置定时器。
//当前活动的方块, 它可以左右下移动, 变型。当它触底后, 将会更新area;
var activeBlock;
//生产方块形状, 有7种基本形状。
function generateBlock(){
activeBlock = null;
activeBlock = new Array(4);
//随机产生0-6数组,代表7种形态。
var t = (Math.floor(Math.random()*20)+1)%7;
switch(t){
case 0:{
activeBlock[0] = {x:0, y:4};
activeBlock[1] = {x:1, y:4};
activeBlock[2] = {x:0, y:5};
activeBlock[3] = {x:1, y:5}; break;
}
//省略部分代码..............................
case 6:{
activeBlock[0] = {x:0, y:5};
activeBlock[1] = {x:1, y:4};
activeBlock[2] = {x:1, y:5};
activeBlock[3] = {x:1, y:6};
break;
}
}
//检查刚生产的四个小方格是否可以放在初始化的位置.
for(var i=0; i<4; i++){
if(!isCellValid(activeBlock[i].x, activeBlock[i].y)){
return false;
}
}
return true;
}
2)每次向下移动后, 都检查是否触底, 如果触底了, 则尝试消行。
//消行
function deleteLine(){
var lines = 0;
for(var i=0; i<18; i++){
var j=0;
for(; j<10; j++){
if(area[i][j]==0){
break;
}
}
if(j==10){
lines++;
if(i!=0){
for(var k=i-1; k>=0; k--){
area[k+1] = area[k];
}
}
area[0] = generateBlankLine();
}
}
return lines;
}
3)完了之后再构造一个活动图形, 再设置定时器。
效果图
有待优化
1)设置不同形状方块的颜色。
思路:在创建方块函数内,设定activeBlockColor颜色,七种不同形态方块颜色各异(除了修改generateBlock方法之外,还需要修改paintarea方法。因为一开始考虑不周全,消除一行后,重绘方块的同时将颜色统一,因此可以考虑移除表格n行,然后在顶部增添n行,以保证没消除方块的完整性)。
2)当当前方块下落时,可以提前查看下一个方块。
思路:将generateBlock方法拆分成两部分,一部分用于随机尝试下一个方块,一部分用于缓存当前所要描绘的方块。当当前方块碰到底部被固定后,下一方块开始描绘,同时又再次随机产生新方块。如此反复。
演示链接:http://topview123.sinaapp.com/game/tetris.html
javascript实现俄罗斯方块游戏的更多相关文章
- 教你看懂网上流传的60行JavaScript代码俄罗斯方块游戏
早就听说网上有人仅仅用60行JavaScript代码写出了一个俄罗斯方块游戏,最近看了看,今天在这篇文章里面我把我做的分析整理一下(主要是以注释的形式). 我用C写一个功能基本齐全的俄罗斯方块的话,大 ...
- Javascript写俄罗斯方块游戏
俄罗斯方块这个游戏也做了移动端的兼容, 这个游戏难点是怎么翻转方块, 自己实现的方式是把方块放到一个二维数组, 然后逆时针旋转二维数组. 也有别的方法,比如直接用一个全局变量代表一个方向, 翻转的时候 ...
- 俄罗斯方块游戏JavaScript代码
JavaScript代码俄罗斯方块游戏 早就听说网上有人仅仅用60行JavaScript代码写出了一个俄罗斯方块游戏,最近看了看,今天在这篇文章里面我把我做的分析整理一下(主要是以注释的形式). 我用 ...
- 60行JavaScript代码俄罗斯方块
教你看懂网上流传的60行JavaScript代码俄罗斯方块游戏 早就听说网上有人仅仅用60行JavaScript代码写出了一个俄罗斯方块游戏,最近看了看,今天在这篇文章里面我把我做的分析整理一下( ...
- 经典 HTML5 & Javascript 俄罗斯方块游戏
Blockrain.js 是一个使用 HTML5 & JavaScript 开发的经典俄罗斯方块游戏.只需要复制和粘贴一段代码就可以玩起来了.最重要的是,它是响应式的,无论你的显示屏多么宽都能 ...
- 60行代码:Javascript 写的俄罗斯方块游戏
哈哈这个实在是有点意思 备受打击当初用java各种类写的都要几百行啦 先看效果图: 游戏结束图: javascript实现源码: [javascript] view plaincopyprint? & ...
- 使用JS实现俄罗斯方块游戏
简单的JS俄罗斯方块游戏源码 效果图: 代码如下,复制即可使用: <!DOCTYPE html> <html> <head> <meta charset=&q ...
- 青瓷引擎之纯JavaScript打造HTML5游戏第二弹——《跳跃的方块》Part 10(排行榜界面&界面管理)
继上一次介绍了<神奇的六边形>的完整游戏开发流程后(可点击这里查看),这次将为大家介绍另外一款魔性游戏<跳跃的方块>的完整开发流程. (点击图片可进入游戏体验) 因内容太多,为 ...
- 从零开始---控制台用c写俄罗斯方块游戏(1)
从零开始---控制台用c写俄罗斯方块游戏(1) 很少写博文,一来自身知识有限,二来自己知道,已经有很多这样的博文了,三就是因为懒,文笔也一般,四来刚出来工作,时间也不多 之所以写这篇博文,是因为应群里 ...
随机推荐
- MyBatis 学习记录2 Mapper对象是如何生成的
主题 以前我一直有一个问题不懂.并且觉得很神奇.就是Mybatis我们开发的时候只需要定义接口,并没有写实现类,为什么我们运行的时候就可以直接使用? 现在我想分享下这部分大致是怎么实现的. 在启动的时 ...
- C++防止文件重复包含
引用自:https://blog.csdn.net/xhfight/article/details/51550446 为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifnde ...
- Elasticsearch-PHP 索引操作
索引操作 本节通过客户端来介绍一下索引API的各种操作.索引操作包含任何管理索引本身(例如,创建索引,删除索引,更改映射等等). 我们通过一些常见的操作的代码片段来介绍,然后在表格中列出剩下的方法.R ...
- python开源项目Scrapy抓取文件乱码解决
scrapy进行页面抓去的时候,保存的文件出现乱码,经过分析是编码的原因,只需要把编码转换为utf-8即可,代码片段 ...... import chardet ...... cont ...
- drbd switch off
DRBD secondary to primary: drbdadm disconnect all drbdadm primary r0 --force mount /dev/drbd0 /mnt [ ...
- 【sdut2878】Circle
题目链接http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/2878.html 题意 n个结点编号为0 ...
- 搭建yum本地源_阿里云CentOS服务器初始化设置
CentOS服务器初始化设置其实不分阿里云或其它服务器了,操作配置过程与步骤也差不多一.挂载硬盘 1.磁盘分区 fdisk -l #查看设备,一般可以看到设备名为/dev/xvdb fdisk /de ...
- QuickSort模板
#include <iostream> using namespace std; struct node { int index; char name[20]; }; node data[ ...
- p2944 [USACO09MAR]地震损失2Earthquake Damage 2
传送门 分析 我们让s到1,关键点到t分别连流量为inf的边 于是我们可以考虑跑s到t的最小割 于是我们将所有点拆为两个点,关键点和1的两个点之间连inf,其余点连1 将原图的边也连上,流量为inf ...
- LIS和LCS LCIS
首先介绍一下LIS和LCS的DP解法O(N^2) LCS:两个有序序列a和b,求他们公共子序列的最大长度 我们定义一个数组DP[i][j],表示的是a的前i项和b的前j项的最大公共子序列的长度,那么由 ...