欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

HTML5 實現(xiàn)的一個俄羅斯方塊實例代碼

 更新時間:2016年09月19日 14:51:50   投稿:lqh  
這篇文章主要介紹了HTML5 實現(xiàn)的一個俄羅斯方塊實例代碼的相關(guān)資料,需要的朋友可以參考下

示例簡單,運行地址為:http://chendd.cn/demo/html/canvas/elsfk.html,得需要支持html5瀏覽器的環(huán)境。

實現(xiàn)的功能:方塊旋轉(zhuǎn)(W鍵)、自動下落、移動(ASD)、消行、快速下落(空格鍵)、下落陰影、游戲結(jié)束。

為實現(xiàn)功能:消行時的計分、等級、以及不同等級的下落速度等。

學(xué)習(xí)了xiaoE的Java版本的俄羅斯方塊后,自己動手使用html5的canvas實現(xiàn)的,

參考效果圖如下:

詳細(xì)代碼如下:

<!DOCTYPE html>

<html>

 <head>

 <meta charset="utf-8">

 <title>俄羅斯方塊</title>

 <style type="text/css">
  /*整個畫布*/
  
  #tetris {
  border: 6px solid grey;
  }
  /*游戲面板*/
 </style>

 </head>

 <body>

 <canvas id="tetris" width="565" height="576"></canvas>

 <script type="text/javascript">
  var canvas = document.getElementById("tetris");
  var context = canvas.getContext("2d");
  var padding = 6,
  size = 32,
  minX = 0,
  maxX = 10,
  minY = 0,
  maxY = 18,
  score = 0,
  level = 1;
  var gameMap = new Array(); //游戲地圖,二維數(shù)組
  var gameTimer;
  initGameMap();
  //繪制垂直線條
  drawGrid();
  var arrays = basicBlockType();
  var blockIndex = getRandomIndex();
  //隨機畫一個方塊意思意思
  var block = getPointByCode(blockIndex);
  context.fillStyle = getBlockColorByIndex(blockIndex);
  drawBlock(block);
  /**

  * 初始化游戲地圖

  */
  function initGameMap() {
  for (var i = 0; i < maxY; i++) {
   var row = new Array();
   for (var j = 0; j < maxX; j++) {
   row[j] = false;
   }
   gameMap[i] = row;
  }
  }
  /**

  * 方塊旋轉(zhuǎn)

  * 順時針:

  * A.x =O.y + O.x - B.y

  * A.y =O.y - O.x + B.x

  */
  function round() {
  //正方形的方塊不響應(yīng)旋轉(zhuǎn)  
  if (blockIndex == 4) {
   return;
  }
  //循環(huán)處理當(dāng)前的方塊,找新的旋轉(zhuǎn)點
  for (var i = 1; i < block.length; i++) {
   var o = block[0];
   var point = block[i];
   //旋轉(zhuǎn)后的位置不能與現(xiàn)有格子的方塊沖突
   var tempX = o.y + o.x - point.y;
   var tempY = o.y - o.x + point.x;
   if (isOverZone(tempX, tempY)) {
   return; //不可旋轉(zhuǎn)
   }
  }
  clearBlock();
  //可以旋轉(zhuǎn),設(shè)置新的旋轉(zhuǎn)后的坐標(biāo)
  for (var i = 1; i < block.length; i++) {
   var o = block[0];
   var point = block[i];
   //旋轉(zhuǎn)后的位置不能與現(xiàn)有格子的方塊沖突
   var tempX = o.y + o.x - point.y;
   var tempY = o.y - o.x + point.x;
   block[i] = {
   x: tempX,
   y: tempY
   };
  }
  drawBlock();
  }
  function moveDown() {
  
  var overFlag = canOver();
  if(overFlag){
   //如果不能向下移動了,將當(dāng)前的方塊坐標(biāo)載入地圖
   window.clearInterval(gameTimer);
   add2GameMap();
   //清除游戲區(qū)域內(nèi)的不同顏色的格子,使用單一顏色重新繪制地圖堆積物
   redrawGameMap();
   return;//游戲結(jié)束
  }
  
  var flag = moveTo(0, 1);
  //如果可以移動,則繼續(xù)移動
  if (flag) {
   return;
  }
  //如果不能向下移動了,將當(dāng)前的方塊坐標(biāo)載入地圖
  add2GameMap();
  
  //進(jìn)行消行動作
  clearLines();
  //清除游戲區(qū)域內(nèi)的不同顏色的格子,使用單一顏色重新繪制地圖堆積物
  redrawGameMap();
  //如果不能向下移動,則繼續(xù)下一個方塊
  nextBlock();
  }
  
  /**

  * 消行動作,返回消除的行數(shù)

  */
  function clearLines() {
  var clearRowList = new Array();
  for (var i = 0; i < maxY; i++) {
   var flag = true;
   for (var j = 0; j < maxX; j++) {
   if (gameMap[i][j] == false) {
    flag = false;
    break;
   }
   }
   if (flag) {
   clearRowList.push(i); //記錄消除行號的索引
   }
  }
  var clearRows = clearRowList.length;
  //所謂的消行就是將待消除行的索引,下方所有的格子上移動
  for (var x = 0; x < clearRows; x++) {
   var index = clearRowList[x];
   for (var i = index; i > 0; i--) {
   for (var j = 0; j < maxX; j++) {
    gameMap[i][j] = gameMap[i - 1][j];
   }
   }
  }
  if (clearRows > 0) {
   for (var i = 0; i < maxY; i++) {
   //此處可以限制滿足相關(guān)條件的方塊進(jìn)行清除操作&& j < clearRowList[clearRows - 1]
   for (var j = 0; j < maxX; j++) {
    if (gameMap[i][j] == false) {
    clearBlockByPoint(i, j);
    }
   }
   }
  }
  }
  /**

  * 重繪游戲地圖

  */
  function redrawGameMap() {
  drawGrid();
  for (var i = 0; i < maxY; i++) {
   for (var j = 0; j < maxX; j++) {
   if (gameMap[i][j]) {
    roadBlock(j, i);
   }
   }
  }
  }
  /**

  * 打印陰影地圖

  */
  function drawShadowBlock() {
  var currentBlock = block;
  var shadowPoints = getCanMoveDown();
  if (shadowPoints != null && shadowPoints.length > 0) {
   for (var i = 0; i < shadowPoints.length; i++) {
   var point = shadowPoints[i];
   if (point == null) {
    continue;
   }
   var start = point.x * size;
   var end = point.y * size;
   context.fillStyle = "#abcdef";
   context.fillRect(start, end, size, size);
   context.strokeStyle = "black";
   context.strokeRect(start, end, size, size);
   }
  }
  }
  /**

  * 返回最多可移動到的坐標(biāo)位置(統(tǒng)計總共可以下落多少步驟)

  * @return最多可移動到的坐標(biāo)位置

  */
  function getCanMoveDown() {
  var nps = canMove(0, 1, block);
  var last = null;
  if (nps != null) {
   last = new Array();
   while ((nps = canMove(0, 1, nps)) != null) {
   if (nps != null) {
    last = nps;
   }
   }
  }
  return last;
  }
  
  function canOver(){
  var flag = false;
  for (var i = 0; i < block.length; i++) {
   var point = block[i];
   var x = point.x;
   var y = point.y;
   if(isOverZone(x , y)){
   flag = true;
   break;
   }
  }
  return flag;
  }
  
  function drawLevelScore() {
  
  }
  /**

  * 將不能移動的各種填充至地圖

  */
  function add2GameMap() {
  for (var i = 0; i < block.length; i++) {
   var point = block[i];
   var x = point.x;
   var y = point.y;
   var gameMapRow = gameMap[y]; //獲取到地圖的一行
   gameMapRow[x] = true; //將此行中的某個格子標(biāo)記為堆積物
   gameMap[y] = gameMapRow; //再將行給設(shè)置回來
  }
  }
  function moveLeft() {
  moveTo(-1, 0);
  }
  function moveRight() {
  moveTo(1, 0);
  }
  function quickDown() {
  while (moveTo(0, 1));
  }
  function moveTo(moveX, moveY) {
  var move = canMove(moveX, moveY, block); //判定是否可以移動
  if (move == null) {
   return false;
  }
  clearBlock();
  for (var i = 0; i < block.length; i++) {
   var point = block[i];
   point.x = point.x + moveX;
   point.y = point.y + moveY;
  }
  drawBlock();
  return true;
  }
  /**

  * 下一個方塊

  */
  function nextBlock() {
  blockIndex = getRandomIndex();
  block = getPointByCode(blockIndex);
  context.fillStyle = getBlockColorByIndex(blockIndex);
  drawBlock();
  }
  document.onkeypress = function(evt) {
  var key = window.event ? evt.keyCode : evt.which;
  switch (key) {
   case 119: //向上旋轉(zhuǎn) W
   round();
   break;
   case 115: //向下移動 S
   moveDown();
   break;
   case 97: //向左移動 A
   moveLeft();
   break;
   case 100: //向右移動 D
   moveRight();
   break;
   case 32: //空格鍵快速下落到底
   quickDown();
   break;
  }
  }
  /**

  * 判定是否可以移動

  * @parammoveX 橫向移動的個數(shù)

  * @parammoveY 縱向移動的個數(shù)

  */
  function canMove(moveX, moveY, currentBlock) {
  var flag = true;
  var newPoints = new Array();
  for (var i = 0; i < currentBlock.length; i++) {
   var point = currentBlock[i];
   var tempX = point.x + moveX;
   var tempY = point.y + moveY;
   if (isOverZone(tempX, tempY)) {
   flag = false;
   break;
   }
  }
  if (flag) {
   for (var i = 0; i < currentBlock.length; i++) {
   var point = currentBlock[i];
   var tempX = point.x + moveX;
   var tempY = point.y + moveY;
   newPoints[i] = {
    x: tempX,
    y: tempY
   };
   }
   return newPoints;
  }
  return null;
  }
  /**

  * 判定是否可以移動

  * @paramx 預(yù)移動后的橫坐標(biāo)

  * @paramy 預(yù)移動后的縱坐標(biāo)

  */
  function isOverZone(x, y) {
  return x < minX || x >= maxX || y < minY || y >= maxY || gameMap[y][x];
  }
  document.body.click();
  
  gameTimer = window.setInterval(moveDown , 800);
  
  /**

  * 初始化方塊的基礎(chǔ)數(shù)據(jù)

  */
  function basicBlockType() {
  var arrays = new Array();
  arrays[0] = [{
   x: 4,
   y: 0
  }, {
   x: 3,
   y: 0
  }, {
   x: 5,
   y: 0
  }, {
   x: 6,
   y: 0
  }];
  arrays[1] = [{
   x: 4,
   y: 0
  }, {
   x: 3,
   y: 0
  }, {
   x: 5,
   y: 0
  }, {
   x: 4,
   y: 1
  }];
  arrays[2] = [{
   x: 4,
   y: 0
  }, {
   x: 3,
   y: 0
  }, {
   x: 5,
   y: 0
  }, {
   x: 3,
   y: 1
  }];
  arrays[3] = [{
   x: 4,
   y: 0
  }, {
   x: 5,
   y: 0
  }, {
   x: 3,
   y: 1
  }, {
   x: 4,
   y: 1
  }];
  arrays[4] = [{
   x: 4,
   y: 0
  }, {
   x: 5,
   y: 0
  }, {
   x: 4,
   y: 1
  }, {
   x: 5,
   y: 1
  }];
  arrays[5] = [{
   x: 4,
   y: 0
  }, {
   x: 3,
   y: 0
  }, {
   x: 5,
   y: 0
  }, {
   x: 5,
   y: 1
  }];
  arrays[6] = [{
   x: 4,
   y: 0
  }, {
   x: 3,
   y: 0
  }, {
   x: 4,
   y: 1
  }, {
   x: 5,
   y: 1
  }];
  return arrays;
  }
  function basicBlockColor() {
  return ["#A00000", "#A05000", "#A0A000", "#00A000", "#00A0A0", "#0000A0", "#A000A0"];
  }
  function getBlockColorByIndex(typeCodeIndex) {
  var arrays = basicBlockColor();
  return arrays[typeCodeIndex];
  }
  /**

  * 根據(jù)編號返回指定編號的方塊

  * @paramtypeCodeIndex 方塊編號索引

  */
  function getPointByCode(typeCodeIndex) {
  var arrays = basicBlockType();
  return arrays[typeCodeIndex];
  }
  /**

  * 獲取隨即出現(xiàn)方塊的范圍值

  * @paramlens 隨機數(shù)的范圍

  */
  function getRandomIndex() {
  return parseInt(Math.random() * (arrays.length - 1), 10);
  }
  /**

  * 繪制方塊,按格子單個繪制

  */
  function drawBlock() {
  drawGrid();
  for (var i = 0; i < block.length; i++) {
   var point = block[i];
   var start = point.x * size;
   var end = point.y * size;
   context.fillStyle = getBlockColorByIndex(blockIndex);
   context.fillRect(start, end, size, size);
   context.strokeStyle = "black";
   context.strokeRect(start, end, size, size);
  }
  drawShadowBlock();
  }
  /**

  * 繪制障礙物

  */
  function roadBlock(x, y) {
  context.fillStyle = "darkgray";
  var start = x * size;
  var end = y * size;
  context.fillRect(start, end, size, size);
  }
  /**

  * 繪制新的方塊先清除之前的方塊

  */
  function clearBlock() {
  for (var i = 0; i < block.length; i++) {
   var point = block[i];
   var start = point.x * size;
   var end = point.y * size;
   context.clearRect(start, end, size, size);
  }
  }
  /**

  * 初始化一個新的行

  */
  function initGameMapRow() {
  var array = new Array();
  for (var i = 0; i < maxX; i++) {
   array[i] = false;
  }
  return array;
  }
  /**

  * 根據(jù)坐標(biāo)清除指定格子的內(nèi)容

  * @paramx 橫坐標(biāo)

  * @paramy 縱坐標(biāo)

  */
  function clearBlockByPoint(x, y) {
  var start = y * size;
  var end = x * size;
  context.clearRect(start, end, size, size);
  }
  /**

  * 清掉所有位置的空白格的繪圖

  */
  function clearAllNullPoint() {
  for (var i = 0; i < maxY; i++) {
   for (var j = 0; j < maxX; j++) {
   if (gameMap[i][j] == false) {
    clearBlockByPoint(i, j);
   }
   }
  }
  }
  /**

  * 繪制網(wǎng)格線

  * @paramcontext 繪圖對象

  */
  function drawGrid() {
  clearAllNullPoint(); //清除掉當(dāng)前方塊下落位置造成的陰影
  context.strokeStyle = "grey"; //畫筆顏色
  for (var i = 0; i <= maxX; i++) {
   var start = i * size;
   var end = start + size;
   context.beginPath();
   context.moveTo(start, 0);
   context.lineTo(size * i, size * maxY);
   context.stroke();
   context.closePath();
  }
  //繪制水平線條
  for (var i = 0; i <= maxY; i++) {
   var start = i * size;
   var end = start + size;
   context.beginPath();
   context.moveTo(0, size * i);
   context.lineTo(size * maxX, size * i);
   context.stroke();
   context.closePath();
  }
  }
 </script>

 </body>

</html>

以上就是HTML5 實現(xiàn)的一個俄羅斯方塊的實例,有興趣的小伙伴可以參考下,謝謝大家對本站的支持!

相關(guān)文章

最新評論