JS实现——俄罗斯方块

把以下代码保存成Tetris.html文件,使用Google或360浏览器打开

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 4.0 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta name="charset-8"/>
  <title> new document </title>
</head>

<body>
  <div id="space"></div>
  <div id="debug" style="position:relative;top:-600px;left:330px"></div>
</body>

<script>
//定义按键
var KEY_LEFT = 37;
var KEY_RIGHT = 39;
var KEY_ROTATE = 38;
var KEY_ACCELERATE = 40;
var KEY_PAUSE = 13;
var KEY_ONE_STOP = 32;

//定义地图大小
var MAP_R = 18;
var MAP_C = 10;

//定义方块大小
var BLOCK_R = 4;
var BLOCK_C = 4;
//定义各种方块
var BLOCKS = [
//I
[
 [[1,1,1,1],
  [0,0,0,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[0,1,0,0],
  [0,1,0,0],
  [0,1,0,0],
  [0,1,0,0]],
 [[1,1,1,1],
  [0,0,0,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[0,1,0,0],
  [0,1,0,0],
  [0,1,0,0],
  [0,1,0,0]]
],

//L
[
 [[1,0,0,0],
  [1,1,1,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[1,1,0,0],
  [1,0,0,0],
  [1,0,0,0],
  [0,0,0,0]],
 [[1,1,1,0],
  [0,0,1,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[1,0,0,0],
  [1,0,0,0],
  [1,1,0,0],
  [0,0,0,0]]
],

//J
[
 [[1,1,1,0],
  [1,0,0,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[1,1,0,0],
  [0,1,0,0],
  [0,1,0,0],
  [0,0,0,0]],
 [[0,0,1,0],
  [1,1,1,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[1,0,0,0],
  [1,0,0,0],
  [1,1,0,0],
  [0,0,0,0]]
],

//O
[
 [[0,1,1,0],
  [0,1,1,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[0,1,1,0],
  [0,1,1,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[0,1,1,0],
  [0,1,1,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[0,1,1,0],
  [0,1,1,0],
  [0,0,0,0],
  [0,0,0,0]]
],

//S
[
 [[0,1,1,0],
  [1,1,0,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[0,1,0,0],
  [0,1,1,0],
  [0,0,1,0],
  [0,0,0,0]],
 [[0,1,1,0],
  [1,1,0,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[0,1,0,0],
  [0,1,1,0],
  [0,0,1,0],
  [0,0,0,0]]
],

//T
[
 [[0,1,0,0],
  [1,1,1,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[0,1,0,0],
  [0,1,1,0],
  [0,1,0,0],
  [0,0,0,0]],
 [[0,0,0,0],
  [1,1,1,0],
  [0,1,0,0],
  [0,0,0,0]],
 [[0,1,0,0],
  [1,1,0,0],
  [0,1,0,0],
  [0,0,0,0]]
],

//Z
[
 [[1,1,0,0],
  [0,1,1,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[0,1,0,0],
  [1,1,0,0],
  [1,0,0,0],
  [0,0,0,0]],
 [[1,1,0,0],
  [0,1,1,0],
  [0,0,0,0],
  [0,0,0,0]],
 [[0,1,0,0],
  [1,1,0,0],
  [1,0,0,0],
  [0,0,0,0]]
]
];

var map = [];
for(var r = 0; r < MAP_R; r++) {
  map.push([]);
  for(var c = 0; c < MAP_C; c++) {
    map[r][c] = {};
    map[r][c].b = 0;
  }
}

var colors = [‘darkorange‘,‘darkviolet‘,‘mediumblue‘,‘red‘,‘lightseagreen‘,‘yellow‘,‘lime‘];

var enableShadow = true;
var shadow = {};

var currR, currC; //方格当前在Space的左顶点位置
var currType; //当前正在落下方块的种类
var currDir = 0; //当前正在落下方块的方向
var pause = false;

//可以落下
function canFall(currR, currC) {
  for(var c = 0; c < BLOCK_C; c++)
    for(var r = BLOCK_R - 1; r >= 0; r--) {
      if(!BLOCKS[currType][currDir][r][c])
        continue;
      if(currR + r + 1 > MAP_R - 1)
        return false;
      if(map[currR + r + 1][currC + c].b)
        return false;
   }
  return true;
}

//找方块的投影坐标
function makeShadow() {
  shadow.r = currR;
  shadow.c = currC;
  while(canFall(shadow.r, shadow.c)) {
    shadow.r++;
  }
}

//落下状态设置到map
function fall(block) {
  for(var r = 0; r < BLOCK_R; r++)
    for(var c = 0; c < BLOCK_C; c++)
      if(BLOCKS[currType][currDir][r][c]) {
        map[currR + r][currC + c].b = BLOCKS[currType][currDir][r][c];
        map[currR + r][currC + c].c = currType;
      }
}

//可以左移
function canLeft() {
  for(var r = 0; r < BLOCK_R; r++)
    for(var c = 0; c < BLOCK_C; c++) {
      if(!BLOCKS[currType][currDir][r][c])
        continue;
      if(currC + c - 1 < 0)
        return false;
      if(map[currR + r][currC + c - 1].b)
        return false;
   }
  return true;
}

//可以右移
function canRight() {
  for(var r = 0; r < BLOCK_R; r++)
    for(var c = BLOCK_C - 1; c >= 0; c--) {
      if(!BLOCKS[currType][currDir][r][c])
        continue;
      if(currC + c + 1 > MAP_C - 1)
        return false;
      if(map[currR + r][currC + c + 1].b)
        return false;
   }
  return true;
}

//可以旋转
function canRotate() {
  return true;
}

//获得满行的行位置
function checkFullRows() {
  var rows = [];
  var full;
  for(var r = currR; r < MAP_R; r++) {
    full = true;
    for(var c = 0; full && c < MAP_C; c++)
      full = map[r][c].b;
    if(full)
      rows.push(r);
  }
  return rows;
}

function showPop(rows) {
  for(var i = 0; i < rows.length; i++)
    for(var c = 0; c < MAP_C; c++)
      $(rows[i] + ‘-‘ + c).style.backgroundColor = ‘transparent‘;
}

//在map消除指定行位置的行
function popRows(rows) {
  for(var i = 0; i < rows.length; i++)
    for(var r = rows[i] - 1; r >= 0; r--)
      for(var c = 0; c < MAP_C; c++) {
        map[r + 1][c].b = map[r][c].b;
        map[r + 1][c].c = map[r][c].c;
      }
}

document.onkeydown = function(event) {
  var keyCode = window .event?event.keyCode:event.which;

  if(keyCode == KEY_LEFT ||  keyCode == KEY_RIGHT) {
    easeBlock();
    if(enableShadow)
      easeShadow();
    if(keyCode == KEY_LEFT) {
      if(canLeft())
        --currC;
    } else if(keyCode == KEY_RIGHT) {
      if(canRight())
        ++currC;
    }
    drawBlock();
    if(enableShadow) {
      makeShadow();
      drawShadow();
    }
  } else if(keyCode == KEY_ROTATE) {
    if(canRotate()) {
      easeBlock();
      if(enableShadow)
        easeShadow();
      currDir = [1,2,3,0][currDir];
      drawBlock();
      if(enableShadow) {
        makeShadow();
        drawShadow();
      }
    }
  } else if(keyCode == KEY_ACCELERATE) {
    loop();
  } else if(keyCode == KEY_PAUSE) {
    pause = !pause;
    if(pause)
      clearInterval(timer);
    else
      timer = setInterval(loop, 300);
  } else if(keyCode == KEY_ONE_STOP) {
    easeBlock();
    makeShadow();
    currR = shadow.r;
    currC = shadow.c;
    drawBlock();
  }

  //printMapState();
}

function nextBlock() {
  function randInt(n, m) {
    return Math.floor(Math.random() * (m - n)) + n;
  }

  currR = 0;
  currC = MAP_C / 2 - BLOCK_C / 2;
  currType = randInt(0, BLOCKS.length);
  currDir = randInt(0, 4);
}

function printMapState() {
  var debug = $(‘debug‘);
  var html = ‘‘;
  for(var r = 0; r < MAP_R; r++) {
    for(var c = 0; c < MAP_C; c++)
      html += map[r][c].b;
    html += ‘</br>‘;
  }
  debug.innerHTML = html;
}

onload = function() {
init();
nextBlock();
drawBlock();
makeShadow();
drawShadow();

timer = setInterval(loop, 300);
};

function loop() {
  if(canFall(currR, currC)) {
    easeBlock();
    ++currR;
    drawBlock();
  } else {
    fall();
    if(currR == 0) {
      drawBlock();
      clearInterval(timer);
      alert(‘Game Over‘);
      return;
    }
    var rows = checkFullRows();
    if(rows.length > 0) {
      showPop(rows);
      popRows(rows);
      setTimeout(function(){
        drawMap();
      }, 100);
    }
    if(enableShadow)
      easeShadow();
    nextBlock();
    drawBlock();
    if(enableShadow) {
      makeShadow();
      drawShadow();
    }
  }
}

function drawMap() {
  for(var r = 0; r < MAP_R; r++)
    for(var c = 0; c < MAP_C; c++) {
      var div = $(r + ‘-‘ + c);
      if(map[r][c].b) {
        div.style.backgroundColor = colors[map[r][c].c];
      } else {
        div.style.backgroundColor = ‘transparent‘;
      }
    }
}

function drawBlock() {
  for(var r = 0; r < BLOCK_R; r++)
    for(var c = 0; c < BLOCK_C; c++) {
      if(BLOCKS[currType][currDir][r][c]) {
        var div = $((currR + r) + ‘-‘ + (currC + c));
        div.style.backgroundColor = colors[currType];
        div.style.border = ‘1px solid ‘ + colors[currType];
      }
    }
}

function easeBlock() {
  for(var r = 0; r < BLOCK_R; r++)
    for(var c = 0; c < BLOCK_C; c++) {
      if(BLOCKS[currType][currDir][r][c]) {
        var div = $((currR + r) + ‘-‘ + (currC + c));
        div.style.backgroundColor = ‘transparent‘;
        div.style.border = ‘1px solid ‘ + ‘transparent‘;
      }
    }
}

function drawShadow() {
  for(var r = 0; r < BLOCK_R; r++)
    for(var c = 0; c < BLOCK_C; c++) {
      if(BLOCKS[currType][currDir][r][c]) {
        var div = $((shadow.r + r) + ‘-‘ + (shadow.c + c));
        div.style.border = ‘1px solid blue‘;
      }
    }
}

function easeShadow() {
  for(var r = 0; r < BLOCK_R; r++)
    for(var c = 0; c < BLOCK_C; c++) {
      if(BLOCKS[currType][currDir][r][c]) {
        var div = $((shadow.r + r) + ‘-‘ + (shadow.c + c));
        div.style.border = ‘1px solid ‘ + ‘transparent‘;
      }
    }
}

function init() {
  var size = 28;

  var space = $(‘space‘);
  space.style.position = ‘relative‘;
  space.style.width = size * MAP_C + (MAP_C + 1) * 3 + 1 + ‘px‘;
  space.style.height = size * MAP_R + (MAP_R + 1) * 3 + 1 + ‘px‘;
  //space.style.backgroundColor = ‘lavender‘;
  space.style.border = ‘2px solid black‘;

  for(var r = 0; r < MAP_R; r++) {
    for(var c = 0; c < MAP_C; c++) {
      var div = document.createElement(‘div‘);
      div.id = r + ‘-‘ + c;
      div.style.position = ‘absolute‘;
      div.style.top = size * r + (r + 1) * 3 + ‘px‘;
      div.style.left = size * c + (c + 1) * 3 + ‘px‘;
      div.style.width = size + ‘px‘;
      div.style.height = size + ‘px‘;
      space.appendChild(div);
    }
  }
}

function $(id) {
  return document.getElementById(id);
}
</script>
</html>

https://www.cnblogs.com/mq0036/p/4946051.html

原文地址:https://www.cnblogs.com/7qin/p/10884419.html

时间: 2024-10-29 19:46:02

JS实现——俄罗斯方块的相关文章

用纯JS做俄罗斯方块 - 简要思路介绍(1)

大家都知道俄罗斯方块是一款大众化的游戏了,我很小的时候就玩过,今年已经25岁了,可以说俄罗斯方块确实是历史悠久,做俄罗斯方块是我上个星期开始的想法.也许是由于自己从来没有写过这种东西吧,所以有生疏.代码的话,只完成了一小部分,大概1/5左右吧.今天还是决定先写一部分思路. 至于俄罗斯方块的话,有很多的难点,如果有JS去写的话,要考虑到碰撞啊,边界啊,下落等问题,本文这些问题大部分不会考虑到,只是提供一部分思路而已,开始已经说了,因为自己还没写完这个游戏,但是又出于想写博客记录,所以才有了这一系列

[从零开始]使用Vue.js制作俄罗斯方块小游戏(一)创建项目

一.创建项目 开发环境:win10 开发的前置操作:安装npm. 首先在命令行里进入一个文件夹A,然后输入vue init webpack tetris tetris是文件夹的名字,可以随便定义,但不能有大写字母 接下来全部按回车就好. 接下来,我们进入tetris,并运行 cd tetris npm run dev 就会出现这样一个界面. 然后我们根据提示打开浏览器,在地址栏输入http://localhost:8080 就会出现如下界面. 这样我们的项目就搭建好了! 原文地址:https:/

[从零开始]使用Vue.js制作俄罗斯方块小游戏(四)ui实现

STEP ONE:设计游戏规则. 作为一个合格的游戏,我们肯定要设计一个合理的游戏规则. 以下是我的方案: 得分=已固定的方块数*1+已消除的行数*50 方块掉落速度=1+已消除的行数*0.05 方块下落的时间间隔=500/方块掉落速度 ok! STEP TWO:ui实现. 这一步我们放在Index.vue里实现. // 当一个方块固定 squareOk () { this.data.cur_points++ if (this.data.cur_points > this.data.max_po

js 俄罗斯方块

纯JS实现俄罗斯方块,打造属于你的游戏帝国 纯JS俄罗斯方块,打造属于你的游戏帝国. 本文原始作者博客 http://www.cnblogs.com/toutou 俄罗斯方块(Tetris, 俄文:Тетрис)是一款电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名.俄罗斯方块的基本规则是移动.旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分.由于上手简单.老少皆宜,从而家喻户晓,风靡世界.那么,我们的问题来了,学挖掘机技术哪家强? 俄罗斯方块可

JAVASCRIPT实现网页版:俄罗斯方块

HTML+CSS+JS实现俄罗斯方块完整版,素材只有图片,想要的下载图片按提示名字保存,css中用的时候注意路径!!主要在JS中!JS附有详细注释 效果: 按键提示:[键盘按键] 素材:图片名字与代码里对应 1.背景图片:tetris.png 2.失败时候的弹出框图片:game-over.png 3.七种色彩小方块图片: I.png: J.png: L.png: O.png: S.png: T.png: Z.png: HTML代码 <!DOCTYPE html> <html> &l

2015年4-6月-前端开发月刊

同步到github了,可以fork之后pull,7月份的已经创建了一个模板可以提交了:https://github.com/jsfront/month 同时群内也有代码比赛了,https://github.com/jsfront/qa 2015年4-6月-前端开发月刊 4-6月份前端资源分享 1. Javascript 2. 移动Javascript开发 3. CSS3 4. Html5 5. 创业 | 职业|项目管理 6. Angular 7. React 8. 看书学习 9. Git 10.

CSS+js打造的网页版俄罗斯方块游戏

<HTML> <SCRIPT> parent.moveTo((screen.width-775)/2,(screen.height-540)/2); parent.resizeTo(775,540) </SCRIPT> <HEAD> <META NAME="Title" CONTENT="JScript Simple Tetris"> <TITLE>CSS+js打造的网页版俄罗斯方块游戏丨石家庄

HTML+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;"></div> <script>

js俄罗斯方块

<html> <style>.c {margin :1px;width:19px;height:19px;background:red;position:absolute;} .d {margin :1px;width:19px;height:19px;background:gray;position:absolute;} .f {top:0px;left:0px;background:black;position:absolute;} </style> <bod