国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

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

2019-11-20 08:56:52
字體:
來源:轉載
供稿:網(wǎng)友

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

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

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

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

參考效果圖如下:

詳細代碼如下:

<!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;  }  }  /**  * 方塊旋轉  * 順時針:  * A.x =O.y + O.x - B.y  * A.y =O.y - O.x + B.x  */  function round() {  //正方形的方塊不響應旋轉    if (blockIndex == 4) {   return;  }  //循環(huán)處理當前的方塊,找新的旋轉點  for (var i = 1; i < block.length; i++) {   var o = block[0];   var point = block[i];   //旋轉后的位置不能與現(xiàn)有格子的方塊沖突   var tempX = o.y + o.x - point.y;   var tempY = o.y - o.x + point.x;   if (isOverZone(tempX, tempY)) {   return; //不可旋轉   }  }  clearBlock();  //可以旋轉,設置新的旋轉后的坐標  for (var i = 1; i < block.length; i++) {   var o = block[0];   var point = block[i];   //旋轉后的位置不能與現(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){   //如果不能向下移動了,將當前的方塊坐標載入地圖   window.clearInterval(gameTimer);   add2GameMap();   //清除游戲區(qū)域內(nèi)的不同顏色的格子,使用單一顏色重新繪制地圖堆積物   redrawGameMap();   return;//游戲結束  }    var flag = moveTo(0, 1);  //如果可以移動,則繼續(xù)移動  if (flag) {   return;  }  //如果不能向下移動了,將當前的方塊坐標載入地圖  add2GameMap();    //進行消行動作  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++) {   //此處可以限制滿足相關條件的方塊進行清除操作&& 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);   }  }  }  /**  * 返回最多可移動到的坐標位置(統(tǒng)計總共可以下落多少步驟)  * @return最多可移動到的坐標位置  */  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; //將此行中的某個格子標記為堆積物   gameMap[y] = gameMapRow; //再將行給設置回來  }  }  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: //向上旋轉 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 預移動后的橫坐標  * @paramy 預移動后的縱坐標  */  function isOverZone(x, y) {  return x < minX || x >= maxX || y < minY || y >= maxY || gameMap[y][x];  }  document.body.click();    gameTimer = window.setInterval(moveDown , 800);    /**  * 初始化方塊的基礎數(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ù)坐標清除指定格子的內(nèi)容  * @paramx 橫坐標  * @paramy 縱坐標  */  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(); //清除掉當前方塊下落位置造成的陰影  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)的一個俄羅斯方塊的實例,有興趣的小伙伴可以參考下,謝謝大家對本站的支持!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 清原| 赤水市| 平山县| 连南| 江门市| 卢龙县| 衡阳县| 五指山市| 远安县| 平乡县| 平遥县| 务川| 偏关县| 四平市| 永年县| 花莲市| 固原市| 宜昌市| 西青区| 留坝县| 莎车县| 察雅县| 太湖县| 柳江县| 元氏县| 湘乡市| 星子县| 四川省| 东至县| 白山市| 黔江区| 鄂托克旗| 栾川县| 桃园市| 铜陵市| 阿拉尔市| 安远县| 雷州市| 岑巩县| 沙湾县| 康保县|