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 俄罗斯方块源码,简单易懂的更多相关文章

  1. JS StartMove源码-简单运动框架

    这几天学习js运动应用课程时,开始接触一个小例子:“仿Flash的图片轮换播放器”,其中使用的StartMove简单运动框架我觉得挺好用的.这个源码也简单,理解其原理,自己敲即便也就熟悉了. 用的时候 ...

  2. 使用C#重写网上的60行 Javascript 俄罗斯方块源码 (带注释)

    在很久很久以前,就已经看过 60行Js的俄罗斯方块源码.无奈当时能力不够看明白,当时觉得就是个神作. 现在总算有空再看了,顺便用c#实现一遍(超过60行),顺道熟悉下Js API. 网上其他博客也有分 ...

  3. unity3d俄罗斯方块源码教程+源码和程序下载

    小时候,大家都应玩过或听说过<俄罗斯方块>,它是红白机,掌机等一些电子设备中最常见的一款游戏.而随着时代的发展,信息的进步,游戏画面从简单的黑白方块到彩色方块,游戏的玩法机制从最简单的消方 ...

  4. 从vue.js的源码分析,input和textarea上的v-model指令到底做了什么

    v-model是 vue.js 中用于在表单表单元素上创建双向数据绑定,它的本质只是一个语法糖,在单向数据绑定的基础上,增加了监听用户输入事件并更新数据的功能:对,它本质上只是一个语法糖,但到底是一个 ...

  5. node-pre-gyp以及node-gyp的源码简单解析(以安装sqlite3为例)

    title: node-pre-gyp以及node-gyp的源码简单解析(以安装sqlite3为例) date: 2020-11-27 tags: node native sqlite3 前言 简单来 ...

  6. FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  7. FFmpeg源码简单分析:libswscale的sws_scale()

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  8. APIView源码简单分析图

    APIView源码简单分析 !声明:下面这个dispatch分发方法不在是父类View里的dispatch了,APIView重新封装了这个dispatch.(整个核心就是initialize_requ ...

  9. [百度地图] 用于类似 DWZ UI 框架的 百度地图 功能封装类 [MultiZMap.js] 实例源码

    MultiZMap 功能说明 MultiZMap.js 本类方法功能大多使用 prototype 原型 实现,它是 ZMap 的多加载版本,主要用于类似 DWZ 这个 多标签的 UI 的框架: 包含的 ...

随机推荐

  1. 二分法求平方根(Python实现)

    使用二分法(Bisection Method)求平方根. def sqrtBI(x, epsilon): assert x>0, 'X must be non-nagtive, not ' + ...

  2. C#设计模式--装饰器模式

    0.C#设计模式-简单工厂模式 1.C#设计模式--工厂方法模式 2.C#设计模式--抽象工厂模式 3.C#设计模式--单例模式 4.C#设计模式--建造者模式 5.C#设计模式--原型模式 6.C# ...

  3. Linux 安装GCC讲解(在线和无网离线)

    本文主要介绍如何在无网络的环境下怎么离线安装GCC,如果有网,只需要通过命令 yum install gcc 进行安装就可以了,yum会自动把所有关联的依赖包也一起安装了,一键安装. yum inst ...

  4. 使用atomic一定是线程安全的吗?

    这个问题很少遇到,但是答案当然不是.atomic在set方法里加了锁,防止了多线程一直去写这个property,造成难以预计的数值.但这也只是读写的锁定.跟线程安全其实还是差一些.看下面. @inte ...

  5. 神奇的thrust::device_vector与nvcc编译选项

    在C++的GPU库thrust中,有两种vector thrust::device_vector<int> D; //GPU使用的内存中的向量 thrust::host_vector< ...

  6. cas 单点登录 --自定义审计日记@Audit()

    错误信息: org.springframework.webflow.execution.ActionExecutionException: Exception thrown executing [An ...

  7. scrapy-redis的使用与解析

      scrapy-redis是一个基于redis的scrapy组件,通过它可以快速实现简单分布式爬虫程序,该组件本质上提供了三大功能: scheduler - 调度器 dupefilter - URL ...

  8. linux写文件,追加内容

    覆盖文件 echo "hello" > filename 追加文件 echo "haha" >> filename

  9. Saltstack之api

    Salt-API 1,htps证书 2,配置文件 3,验证.使用PAM验证 4,启动salt-api 安装salt-api yum -y install salt-api 创建用户 useradd - ...

  10. PAT天梯赛L2-003 月饼【贪心】

    L2-003. 月饼 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不 ...