js 俄罗斯方块源码,简单易懂
1、自己引入jquery
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.box{
width: 400px;
height: 600px;
margin: 20px auto;
border: 5px solid yellowgreen;
}
.row{
height: 20px;
width: 100%;
}
.row div{
width: 18px;
height: 18px;
border: 1px solid transparent;
float: left;
} .row .active{
background: red;
border: 1px solid #ccc;
} .row .butte{
background: goldenrod;
border: 1px solid #FF0000;
} </style>
</head>
<body>
<div class="box"> </div>
</body>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
var $box = $(".box");
var $row = null;
var $dataArr = [];
var timer = null;
var gameRun = true;
var config = [
[
{x:0, y:4},
{x:1, y:4},
{x:0, y:5},
{x:1, y:5}
],
[
{x:0, y:3},
{x:0, y:4},
{x:0, y:5},
{x:0, y:6}
],
[
{x:0, y:5},
{x:1, y:4},
{x:1, y:5},
{x:2, y:4}
],
[
{x:0, y:4},
{x:1, y:4},
{x:1, y:5},
{x:2, y:5}
],
[
{x:0, y:4},
{x:1, y:4},
{x:1, y:5},
{x:1, y:6}
],
[
{x:0, y:4},
{x:1, y:4},
{x:2, y:4},
{x:2, y:5}
],
[
{x:0, y:5},
{x:1, y:4},
{x:1, y:5},
{x:1, y:6}
]
];
var $bullet = [
{x:0, y:3},
{x:0, y:4},
{x:0, y:5},
{x:0, y:6}
];
var $dowm = [
]; for(var i = 0 ; i < 30; i++){
$box.append("<div class='row'></div>");
var temp = [];
for(var j = 0; j < 20; j++){
$box.find(".row").last().append("<div></div>");
temp.push(0);
}
$dataArr.push(temp);
}
$row = $(".row"); dataTemp();
function dataTemp(){
for(var i = 0; i < 30; i++){
for(var j = 0; j < 20; j++){
if($dataArr[i][j] == 1){
$dataArr[i][j] = 0;
}
}
}
for(var i = 0; i < $bullet.length;i++){
$dataArr[$bullet[i].x][$bullet[i].y] = 1; //正在下落的dom
}
/*for(var i = 0;i< $dowm.length ;i++ ){
$dataArr[$dowm[i].x][$dowm[i].y] = 2; //已经下来的dom
}*/
layout();
}; function layout(){
for(var i = 0; i < 30; i++){
for(var j = 0; j < 20; j++){
if($dataArr[i][j] == 0){
$row.eq(i).find("div").eq(j)[0].className = "";
}else if($dataArr[i][j] == 1){
$row.eq(i).find("div").eq(j)[0].className = "active";
}else if($dataArr[i][j] == 2){
$row.eq(i).find("div").eq(j)[0].className = "butte";
}
}
}
}; $(window).on("keydown", function(event) {
if(gameRun){
switch(event.key) {
case "w":
rotate();
break;
case "s":
moveToDown();
break;
case "a":
leftRight(-1);
break;
case "d":
leftRight(1);
break;
default:
break;
}
} }); function rotate(){
var tmpBlock = new Array(4);
for(var i=0; i<4; i++){
tmpBlock[i] = {x:0, y:0};
}
//先算四个点的中心点,则这四个点围绕中心旋转90度。
var cx = Math.round(($bullet[0].x + $bullet[1].x + $bullet[2].x + $bullet[3].x)/4);
var cy = Math.round(($bullet[0].y + $bullet[1].y + $bullet[2].y + $bullet[3].y)/4);
//旋转的主要算法. 可以这样分解来理解。
//先假设围绕源点旋转。然后再加上中心点的坐标。
for(var i=0; i<4; i++){
tmpBlock[i].x = cx+cy-$bullet[i].y;
tmpBlock[i].y = cy-cx+$bullet[i].x;
} if(judegBorder(tmpBlock)){
for(var i=0; i<4; i++){
$bullet[i].x = tmpBlock[i].x;
$bullet[i].y = tmpBlock[i].y;
}
} dataTemp(); } function move(x){
for(var i = 0; i < $bullet.length; i++ ){
$bullet[i].x = $bullet[i].x + x;
}
if(! judegBorder($bullet)){
clearInterval(timer);
createSqure();
return;
}
dataTemp();
} //判断是否越界,越界了,则返回false
function judegBorder(obj){
var flag = true;
for(var i = 0; i < obj.length ; i++){ if(obj[i].x >= 30 || obj[i].x < 0 || obj[i].y >= 20 || obj[i].y < 0){
flag = false;
return false;
} if($dataArr[obj[i].x][obj[i].y] == 2){
flag = false;
return false;
}
}
return flag;
} timer=setInterval(function(){
move(1);
},1000); function createSqure(){ var obj = [];
//记录停下的
for(var i = 0; i < 4; i++){
obj.push({x:$bullet[i].x-1,y:$bullet[i].y});
$dataArr[$bullet[i].x-1][$bullet[i].y] = 2;
}
//消除可以消除的
trimp(obj);
layout();
var randNum =Math.floor(Math.random() * config.length);
//判断是否到顶,没有则添加
for(var i=0; i<4; i++){
if($dataArr[config[randNum][i].x][config[randNum][i].y] == 2){
gameRun = false;
alert("Game Over!");
return;
}
$bullet[i] = {x:config[randNum][i].x, y:config[randNum][i].y}; }
dataTemp();
timer=setInterval(function(){
move(1);
},500);
} function leftRight(num){
var tmpBlock = new Array(4);
for(var i=0; i<4; i++){
tmpBlock[i] = {x:$bullet[i].x, y:$bullet[i].y};
}
for(var i = 0; i < tmpBlock.length; i++ ){
tmpBlock[i].y = tmpBlock[i].y + num;
}
if(judegBorder(tmpBlock)){
for(var i = 0; i < tmpBlock.length; i++ ){
$bullet[i].y = tmpBlock[i].y;
}
}
dataTemp();
} function moveToDown(){
var tmpBlock = new Array(4);
for(var i=0; i<4; i++){
tmpBlock[i] = {x:$bullet[i].x, y:$bullet[i].y};
}
for(var i = 0; i < tmpBlock.length; i++ ){
tmpBlock[i].x = tmpBlock[i].x + 1;
}
if(judegBorder(tmpBlock)){
for(var i = 0; i < tmpBlock.length; i++ ){
$bullet[i].x = tmpBlock[i].x;
}
}
dataTemp();
} function trimp(obj){
for(var i = 0; i < obj.length;i++){
var flag = true; for(var j = 0; j < 20; j++){
if($dataArr[obj[i].x][j] != 2){
flag = false;
}
}
if(flag){
//需要消除
for(var j = 0; j < 20; j++){
$dataArr[obj[i].x][j] = 0;
}
//下面的被消除,往下掉
for(var x = obj[i].x ; x >= 0 ; x--){
for(var y = 0; y < 20;y++){
if($dataArr[x][y] == 2){
$dataArr[x][y] = 0;
$dataArr[x+1][y] = 2;
}
}
}
i--;
}
}
}
</script>
</html>
js 俄罗斯方块源码,简单易懂的更多相关文章
- JS StartMove源码-简单运动框架
这几天学习js运动应用课程时,开始接触一个小例子:“仿Flash的图片轮换播放器”,其中使用的StartMove简单运动框架我觉得挺好用的.这个源码也简单,理解其原理,自己敲即便也就熟悉了. 用的时候 ...
- 使用C#重写网上的60行 Javascript 俄罗斯方块源码 (带注释)
在很久很久以前,就已经看过 60行Js的俄罗斯方块源码.无奈当时能力不够看明白,当时觉得就是个神作. 现在总算有空再看了,顺便用c#实现一遍(超过60行),顺道熟悉下Js API. 网上其他博客也有分 ...
- unity3d俄罗斯方块源码教程+源码和程序下载
小时候,大家都应玩过或听说过<俄罗斯方块>,它是红白机,掌机等一些电子设备中最常见的一款游戏.而随着时代的发展,信息的进步,游戏画面从简单的黑白方块到彩色方块,游戏的玩法机制从最简单的消方 ...
- 从vue.js的源码分析,input和textarea上的v-model指令到底做了什么
v-model是 vue.js 中用于在表单表单元素上创建双向数据绑定,它的本质只是一个语法糖,在单向数据绑定的基础上,增加了监听用户输入事件并更新数据的功能:对,它本质上只是一个语法糖,但到底是一个 ...
- node-pre-gyp以及node-gyp的源码简单解析(以安装sqlite3为例)
title: node-pre-gyp以及node-gyp的源码简单解析(以安装sqlite3为例) date: 2020-11-27 tags: node native sqlite3 前言 简单来 ...
- FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- FFmpeg源码简单分析:libswscale的sws_scale()
===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...
- APIView源码简单分析图
APIView源码简单分析 !声明:下面这个dispatch分发方法不在是父类View里的dispatch了,APIView重新封装了这个dispatch.(整个核心就是initialize_requ ...
- [百度地图] 用于类似 DWZ UI 框架的 百度地图 功能封装类 [MultiZMap.js] 实例源码
MultiZMap 功能说明 MultiZMap.js 本类方法功能大多使用 prototype 原型 实现,它是 ZMap 的多加载版本,主要用于类似 DWZ 这个 多标签的 UI 的框架: 包含的 ...
随机推荐
- SQL Server设置登录验证模式
我们在安装SQL Server的时候可以设置“混合验证模式”,既可以使用windows身份验证登录,也可以使用SQL Server身份验证登录. 如果我们在安装的时候并未设置"混合验证模式& ...
- 响应式web设计之@media
两种方式,一种是直接在link中判断设备的尺寸,然后引用不同的css文件: 1 <link rel="stylesheet" type="text/css" ...
- C++ 操作符new和delete
参考资料: http://en.cppreference.com/w/cpp/memory/new/operator_new http://en.cppreference.com/w/cpp/memo ...
- 原生js--类的扩充和类型检测
扩充类的方法: 1.向原型对象上添加方法或属性.例如:Number.prototype.cl = function(){}; 但这种做法并不推荐,因为ES5之前,无法将这些新添加的方法或属性设置为不可 ...
- Word 2010 制作文档结构之图标自动编号设置
注意: 使用图片自动编号时,如果文档标题使用的样式是通过“将所选内容保存为新快速样式”所生成的样式,则图片自动编号不会生效 因此设置标题样式时,不要 新建样式,直接使用word预设的“标题 1”样式和 ...
- LeetCode 44 Wildcard Matching(字符串匹配问题)
题目链接:https://leetcode.com/problems/wildcard-matching/?tab=Description '?' Matches any single chara ...
- 使用nginx做反代时遇到413 Request Entity Too Large的解决方法
在使用nginx做反向代理的时候,被反代的系统在上传文件的时候遇到413 错误 :Request Entity Too Large 原因是nginx限制了上传文件的大小,在nginx中可以配置最大允许 ...
- 【JSP】EL表达式语言
EL简介 EL语言原本是JSTL1.0中的技术(所以EL和JSTL配合如此亲密和默契也就是自然的了),但是从JSP2.0开始(JSTL1.1)就分离出来纳入了JSP的标准了.因此EL不需要任何jar包 ...
- 【CF633H】Fibonacci-ish II 莫队+线段树
[CF633H]Fibonacci-ish II 题意:给你一个长度为n的序列$a_i$.m个询问,每个询问形如l,r:将[l,r]中的所有$a_i$排序并去重,设得到的新数列为$b_i$,求$b_1 ...
- Qt qDebug() 的使用方法
在Qt程序调试的时候,经常需要打印一些变量,那么我们就需要使用qDebug()函数,这种函数有两种使用方法,如下所示: QString s = "Jack"; qDebug() & ...