js canvas实现俄罗斯方块

本文实例为大家分享了canvas实现俄罗斯方块的具体代码,供大家参考,具体内容如下

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
</head>
<body style="margin: 0;">
 <canvas id="tetris" style="border: 1px solid #000;"></canvas>
 <div id="text" style='color: red;font-size: 30px;'>当前分数:0</div>
</body>
<script>
 let cav = document.getElementById('tetris')
 let text = document.getElementById('text')
 let ctx = cav.getContext('2d')
 let k = 40 //倍数
 let speed = 1000
 let grade = 0
 let restartFlag = false
 let timer = null
 let curGraphPositionList = []
 let curtype = undefined
 let transformNum = 0
 let blockGraph = Array(10)
 let beforeUpdateGraph = []
 for(let i = 0;i<blockGraph.length;i++){
  blockGraph[i] = Array(20)
 }
 cav.width = 10*k
 cav.height = 20*k
 ctx.fillStyle="yellow"
 ctx.strokeStyle="black"
 function ramdomRectType(){
  return Math.floor((Math.random()*7)+1)
 }
 function randomXposition(){
  return Math.floor(Math.random()*10)
 }
 function drawRect(position,width){
  ctx.beginPath()
  ctx.rect(position[0],position[1],width,width)
  ctx.fill();
  ctx.stroke()
 }
 function drawGraph(positionList){
  if(positionList.length===0){
   return
  }
  for(let item of positionList){
   let x= item[0]*k
   let y= item[1]*k
   let position = [x,y]
   drawRect(position,k)
  }
 }
 function isOut(position,xOry){//x:0,y:1
  if(xOry===0){
   if(position<0||position>9){
    return true
   }else{
    return false
   }
  }else{
   if(position<0||position>19){
    return true
   }else{
    return false
   }
  }
 }
 function randomRectShape(){
  let rposition = randomXposition()
  let type = ramdomRectType()
  curtype = type
  transformNum = 0
  let positionList = []
  let one = []
  let two = []
  let three = []
  let four = []
  switch(type){
   case 1:
    if(isOut(rposition+2,0)){
     return randomRectShape()
    }else{
     one = [rposition+2,0]
     two = [rposition,1]
     three = [rposition+1,1]
     four = [rposition+2,1]
    }
    break;
   case 2:
    if(isOut(rposition+2,0)){
     return randomRectShape()
    }else{
     one = [rposition,0]
     two = [rposition,1]
     three = [rposition+1,1]
     four = [rposition+2,1]
    }
    break;
   case 3:
    if(isOut(rposition+2,0)){
     return randomRectShape()
    }else{
     one = [rposition+1,0]
     two = [rposition+2,0]
     three = [rposition,1]
     four = [rposition+1,1]
    }
    break;
   case 4:
    if(isOut(rposition+2,0)){
     return randomRectShape()
    }else{
     one = [rposition,0]
     two = [rposition+1,0]
     three = [rposition+1,1]
     four = [rposition+2,1]
    }
    break;
   case 5:
    if(isOut(rposition+2,0)){
     return randomRectShape()
    }else{
     one = [rposition+1,0]
     two = [rposition,1]
     three = [rposition+1,1]
     four = [rposition+2,1]
    }
    break;
   case 6:
    if(isOut(rposition+1,0)){
     return randomRectShape()
    }else{
     one = [rposition,0]
     two = [rposition+1,0]
     three = [rposition,1]
     four = [rposition+1,1]
    }
    break;
   case 7:
    if(isOut(rposition+3,0)){
     return randomRectShape()
    }else{
     one = [rposition,0]
     two = [rposition+1,0]
     three = [rposition+2,0]
     four = [rposition+3,0]
    }
    break;
  }
  positionList.push(one,two,three,four)
  return positionList
 }
 function clearRect(position,width){
  ctx.clearRect(position[0]*k-1,position[1]*k-1,width+2,width+2)
 }
 function clearGraph(curGraphPositionList){
  if(curGraphPositionList.length===0){
   return
  }
  for(let item of curGraphPositionList){
   clearRect(item,k)
  }
 }
 function clearGraphList(){
  let graphList = []
  for(let i = 0;i< blockGraph.length;i++){
   for(let j =0;j< blockGraph[i].length;j++){
    if(blockGraph[i][j]===1){
     graphList.push([i,j])
    }
   }
  }
  clearGraph(graphList)
 }
 function isTouchOtherBlock(position){
  return blockGraph[position[0]][position[1]] === 1
 }
 function updateBlockGraph(graphPositionList){
  for(let i =0;i<graphPositionList.length;i++){
   let x = parseInt(graphPositionList[i][0])
   let y = parseInt(graphPositionList[i][1])
   blockGraph[x][y] = 1
  }
  let transformArray = []
  for(let i=0;i<20;i++){
   let arr = blockGraph.map((item)=>{
    return item[i]
   })
   transformArray.push(arr)
  }
  let flagList = []
  for(let i in transformArray){
   let flag = 1
   for(let j in transformArray[i]){
    if(transformArray[i][j]!==1){
     flag = 0
     break
    }
   }
   flagList.push(flag)
  }
  let score = flagList.filter((item)=>{
   return item === 1
  })
  if(score.length>0){
   grade = grade + score.length
   text.innerHTML = '当前分数:'+grade
   for(let i in transformArray){
    if(flagList[i]===1){
     for(let j in transformArray[i]){
      transformArray[i][j]=undefined
     }
    }
   }
   let hasBlockList = []
   for(let i in transformArray){
    let flagOfHasBlock = 0
    for(let j in transformArray[i]){
     if(transformArray[i][j]!==undefined){
      flagOfHasBlock = 1
      break
     }
    }
    hasBlockList.push(flagOfHasBlock)
   }
   for(let i = transformArray.length -1 ;i>=0;i--){
    if(hasBlockList[i]===1){
     let count = 0
     for(let j = i ;j<19;j++){
      if(hasBlockList[j+1]===0){
       count++
      }else{
       break
      }
     }
     if(count===0){
      continue
     }
     for(let j in transformArray[i]){
      if(transformArray[i][j]===1){
       transformArray[i][j] = undefined
       transformArray[i+count][j] = 1
      }
     }
     hasBlockList[i]=0
     hasBlockList[i+count]=1
    }
   }
   let newBlockGraph = []
   for(let i=0;i<10;i++){
    let arr = transformArray.map((item)=>{
     return item[i]
    })
    newBlockGraph.push(arr)
   }
   clearGraphList()
   blockGraph = newBlockGraph
  }
 }
 function movePosition(curGraphPositionList,direct){
  switch(direct){
   case 'left':
    let minL = Math.min(...curGraphPositionList.map((item)=>{
     return item[0]
    }))
    if(minL-1<0){
     return curGraphPositionList
    }else{
     let changeFlag = true
     let next = curGraphPositionList.map((item)=>{
      return [item[0]-1,item[1]]
     })
     for(let item of next){
      if(isTouchOtherBlock(item)){
       changeFlag = false
      }
     }
     if(changeFlag){
      return next
     }else{
      return curGraphPositionList
     }
    }
    break;
   case 'right':
    let maxR = Math.max(...curGraphPositionList.map((item)=>{
     return item[0]
    }))
    if(maxR+1>9){
     return curGraphPositionList
    }else{
     let changeFlag = true
     let next = curGraphPositionList.map((item)=>{
      return [item[0]+1,item[1]]
     })
     for(let item of next){
      if(isTouchOtherBlock(item)){
       changeFlag = false
      }
     }
     if(changeFlag){
      return next
     }else{
      return curGraphPositionList
     }
    }
    break;
   case 'down':
    let maxD = Math.max(...curGraphPositionList.map((item)=>{
     return item[1]
    }))
    if(maxD>18){
     updateBlockGraph(curGraphPositionList)
     restartFlag = true
     return curGraphPositionList
    }else{
     let changeFlag = true
     let next = curGraphPositionList.map((item)=>{
      return [item[0],item[1]+1]
     })
     for(let item of next){
      if(isTouchOtherBlock(item)){
       changeFlag = false
      }
     }
     if(changeFlag){
      return next
     }else{
      updateBlockGraph(curGraphPositionList)
      restartFlag = true
      return curGraphPositionList
     }
    }
    break;
  }
 }
 function checkOver(positionList){
  for(let i in positionList){
   let x = positionList[i][0]
   let y = positionList[i][1]
   if(blockGraph[x][y]===1){
    over()
    alert('游戏结束')
    return true
   }
  }
  return false
 }
 function drawGraphList(){
  let graphList = []
  for(let i = 0;i< blockGraph.length;i++){
   for(let j =0;j< blockGraph[i].length;j++){
    if(blockGraph[i][j]===1){
     graphList.push([i,j])
    }
   }
  }
  drawGraph(graphList)
 }
 function isComplexData (data) {
  if(data===null||data===undefined){
   return false
  }
  let flag = data.constructor===Array||data.constructor===Object
  return flag
 }

 function deepCopy (data) {
  if(!isComplexData (data)){
   return data
  }
  let result = null
  if(data.constructor===Array){
   result = []
  }else{
   result = {}
  }
  for(let i in data){
   result[i] = deepCopy (data[i])
  }
  return result
 }

 function move(direct){
  clearGraph(curGraphPositionList)
  curGraphPositionList = movePosition(curGraphPositionList,direct)
  if(restartFlag){
   drawGraphList(blockGraph)
  }else{
   drawGraph(curGraphPositionList)
  }
 }
 function transform (curtype) {
  let checkArr = deepCopy(curGraphPositionList)
  if(transformNum>=3){
   transformNum = 0
  }else{
   transformNum++
  }
  switch(curtype){
   case 1:
    caseOne(checkArr)
    break;
   case 2:
    caseTwo(checkArr)
    break;
   case 3:
    caseThree(checkArr)
    break;
   case 4:
    caseFour(checkArr)
    break;
   case 5:
    caseFive(checkArr)
    break;
   case 6:
    caseSix(checkArr)
    break;
   case 7:
    caseSeven(checkArr)
    break;
  }
  //start check outside
  let outflag = false
  let xArr = checkArr.map((item)=>{
   return item[0]
  })
  let yArr = checkArr.map((item)=>{
   return item[1]
  })
  for(let item of xArr){
   if(isOut(item,0)){
    outflag = true
   }
  }
  for(let item of yArr){
   if(isOut(item,1)){
    outflag = true
   }
  }
  if(outflag){
   if(transformNum<=0){
    transformNum = 3
   }else{
    transformNum--
   }
   return
  }
  //end check
  if(!checkTranfromTouchBlock(checkArr)){
    if(transformNum<=0){
     transformNum = 3
    }else{
     transformNum--
    }
    return
  }else{
   clearGraph(curGraphPositionList)
   curGraphPositionList = checkArr
   drawGraph(curGraphPositionList)
  }
 }
 function checkTranfromTouchBlock(checkArr){
  let changeFlag = true
  for(let item of checkArr){
   if(isTouchOtherBlock(item)){
    changeFlag = false
   }
  }
  return changeFlag
 }
 function caseOne(checkarr){
  switch(transformNum){
   case 0:
    checkarr[0][0]=checkarr[0][0]+2
    checkarr[1][0]=checkarr[1][0]-1
    checkarr[1][1]=checkarr[1][1]-1
    checkarr[3][0]=checkarr[3][0]+1
    checkarr[3][1]=checkarr[3][1]+1
    break;
   case 1:
    checkarr[0][1]=checkarr[0][1]+2
    checkarr[1][0]=checkarr[1][0]+1
    checkarr[1][1]=checkarr[1][1]-1
    checkarr[3][0]=checkarr[3][0]-1
    checkarr[3][1]=checkarr[3][1]+1
    break;
   case 2:
    checkarr[0][0]=checkarr[0][0]-2
    checkarr[1][0]=checkarr[1][0]+1
    checkarr[1][1]=checkarr[1][1]+1
    checkarr[3][0]=checkarr[3][0]-1
    checkarr[3][1]=checkarr[3][1]-1
    break;
   case 3:
    checkarr[0][1]=checkarr[0][1]-2
    checkarr[1][0]=checkarr[1][0]-1
    checkarr[1][1]=checkarr[1][1]+1
    checkarr[3][0]=checkarr[3][0]+1
    checkarr[3][1]=checkarr[3][1]-1
    break;
  }
 }
 function caseTwo(checkarr){
  switch(transformNum){
   case 0:
    checkarr[0][1]=checkarr[0][1]-2
    checkarr[1][0]=checkarr[1][0]-1
    checkarr[1][1]=checkarr[1][1]-1
    checkarr[3][0]=checkarr[3][0]+1
    checkarr[3][1]=checkarr[3][1]+1
    break;
   case 1:
    checkarr[0][0]=checkarr[0][0]+2
    checkarr[1][0]=checkarr[1][0]+1
    checkarr[1][1]=checkarr[1][1]-1
    checkarr[3][0]=checkarr[3][0]-1
    checkarr[3][1]=checkarr[3][1]+1
    break;
   case 2:
    checkarr[0][1]=checkarr[0][1]+2
    checkarr[1][0]=checkarr[1][0]+1
    checkarr[1][1]=checkarr[1][1]+1
    checkarr[3][0]=checkarr[3][0]-1
    checkarr[3][1]=checkarr[3][1]-1
    break;
   case 3:
    checkarr[0][0]=checkarr[0][0]-2
    checkarr[1][0]=checkarr[1][0]-1
    checkarr[1][1]=checkarr[1][1]+1
    checkarr[3][0]=checkarr[3][0]+1
    checkarr[3][1]=checkarr[3][1]-1
    break;
  }
 }
 function caseThree(checkarr){
  if(transformNum%2!==0){
   checkarr[0][0]=checkarr[0][0]+1
   checkarr[0][1]=checkarr[0][1]+1
   checkarr[1][1]=checkarr[1][1]+2
   checkarr[2][0]=checkarr[2][0]+1
   checkarr[2][1]=checkarr[2][1]-1
  }else{
   checkarr[0][0]=checkarr[0][0]-1
   checkarr[0][1]=checkarr[0][1]-1
   checkarr[1][1]=checkarr[1][1]-2
   checkarr[2][0]=checkarr[2][0]-1
   checkarr[2][1]=checkarr[2][1]+1
  }
 }

 function caseFour(checkarr){
  if(transformNum%2!==0){
   checkarr[0][0]=checkarr[0][0]+2
   checkarr[1][0]=checkarr[1][0]+1
   checkarr[1][1]=checkarr[1][1]+1
   checkarr[3][0]=checkarr[3][0]-1
   checkarr[3][1]=checkarr[3][1]+1
  }else{
   checkarr[0][0]=checkarr[0][0]-2
   checkarr[1][0]=checkarr[1][0]-1
   checkarr[1][1]=checkarr[1][1]-1
   checkarr[3][0]=checkarr[3][0]+1
   checkarr[3][1]=checkarr[3][1]-1
  }
 }
 function caseFive(checkarr){
  switch(transformNum){
   case 0:
    checkarr[0][0]=checkarr[0][0]+1
    checkarr[0][1]=checkarr[0][1]-1
    checkarr[1][0]=checkarr[1][0]-1
    checkarr[1][1]=checkarr[1][1]-1
    checkarr[3][0]=checkarr[3][0]+1
    checkarr[3][1]=checkarr[3][1]+1
    break;
   case 1:
    checkarr[0][0]=checkarr[0][0]+1
    checkarr[0][1]=checkarr[0][1]+1
    checkarr[1][0]=checkarr[1][0]+1
    checkarr[1][1]=checkarr[1][1]-1
    checkarr[3][0]=checkarr[3][0]-1
    checkarr[3][1]=checkarr[3][1]+1
    break;
   case 2:
    checkarr[0][0]=checkarr[0][0]-1
    checkarr[0][1]=checkarr[0][1]+1
    checkarr[1][0]=checkarr[1][0]+1
    checkarr[1][1]=checkarr[1][1]+1
    checkarr[3][0]=checkarr[3][0]-1
    checkarr[3][1]=checkarr[3][1]-1
    break;
   case 3:
    checkarr[0][0]=checkarr[0][0]-1
    checkarr[0][1]=checkarr[0][1]-1
    checkarr[1][0]=checkarr[1][0]-1
    checkarr[1][1]=checkarr[1][1]+1
    checkarr[3][0]=checkarr[3][0]+1
    checkarr[3][1]=checkarr[3][1]-1
    break;
  }
 }
 function caseSix(checkarr){
  return
 }
 function caseSeven(checkarr){
  if(transformNum%2!==0){
   checkarr[0][0]=checkarr[0][0]+2
   checkarr[0][1]=checkarr[0][1]-2
   checkarr[1][0]=checkarr[1][0]+1
   checkarr[1][1]=checkarr[1][1]-1
   checkarr[3][0]=checkarr[3][0]-1
   checkarr[3][1]=checkarr[3][1]+1
  }else{
   checkarr[0][0]=checkarr[0][0]-2
   checkarr[0][1]=checkarr[0][1]+2
   checkarr[1][0]=checkarr[1][0]-1
   checkarr[1][1]=checkarr[1][1]+1
   checkarr[3][0]=checkarr[3][0]+1
   checkarr[3][1]=checkarr[3][1]-1
  }
 }
 function setTimer(speed) {
  clearInterval(timer)
  timer = setInterval(()=>{
   move('down')
   if(restartFlag){
    newBlock()
   }
  },speed)
 }
 function newBlock(){
  restartFlag = false
  curGraphPositionList = randomRectShape()
  drawGraph(curGraphPositionList)
  let overflag = checkOver(curGraphPositionList)
  if(overflag){
   return
  }
  setTimer(speed)
 }
 function start() {
  newBlock()
 }
 function over() {
  clearInterval(timer)
 }
 start()

 let pauseFlag = false
 document.addEventListener('keydown',(event)=>{
  if(event.keyCode===37){
   move('left')
  }else if(event.keyCode===39){
   move('right')
  }else if(event.keyCode===40){
   speed=30
   setTimer(speed)
  }else if(event.keyCode===32){
   pauseFlag = !pauseFlag
   if(pauseFlag){
    over()
   }else{
    setTimer(speed)
   }
  }else if(event.keyCode===38){
   // clearGraph(curGraphPositionList)
   transform (curtype)
  }
 })
 document.addEventListener('keyup',(event)=>{
  if(event.keyCode===40){
   speed=1000
   setTimer(speed)
  }
 })

</script>
</html>

更多有趣的经典小游戏实现专题,分享给大家:

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

javascript经典小游戏汇总

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • JS俄罗斯方块,包含完整的设计理念

    下面是俄罗斯方块的截图: 请到这里下载源码: 俄罗斯方块 在线演示 下载地址下面是代码: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml&q

  • JAVASCRIPT代码编写俄罗斯方块网页版

    俄罗斯方块方块是小时候的一个回忆,从最开始的掌上的黑白游戏机,到电视游戏机,到电脑,无不有它的痕迹,今天我们来一起重温它的一种实现方法,也算是整理一下我的思路吧...... HTML+CSS+JS实现俄罗斯方块完整版,素材只有图片,想要的下载图片按提示名字保存,css中用的时候注意路径!!主要在JS中!JS附有详细注释 效果: 按键提示:[键盘按键] 素材:图片名字与代码里对应 1.背景图片:tetris.png 2.失败时候的弹出框图片:game-over.png 3.七种色彩小方块图片:  

  • JavaScript实现俄罗斯方块游戏过程分析及源码分享

    观摩一下<编程之美>:"程序虽然很难写,却很美妙.要想把程序写好,需要写好一定的基础知识,包括编程语言.数据结构与算法.程序写得好,需要缜密的逻辑思维能力和良好的梳理基础,而且熟悉编程环境和编程工具." 学了几年的计算机,你有没有爱上编程.话说,没有尝试自己写过一个游戏,算不上热爱编程. 俄罗斯方块曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事,它看似简单但却变化无穷,令人上瘾.相信大多数同学,曾经为它痴迷得茶不思饭不想. 游戏规则 1.一个用于摆放小型正方形的平

  • 60行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;"&g

  • 使用JS代码实现俄罗斯方块游戏

    简单的JS俄罗斯方块游戏源码,先给大家展示下效果图,如果大家感觉不错,请参考实现代码, 效果图: 代码如下,复制即可使用: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>使用JS实现俄罗斯方块游戏</title> <style type="text/css"> .MainFrame { border: 1px

  • JS+Canvas实现的俄罗斯方块游戏完整实例

    本文实例讲述了JS+Canvas实现的俄罗斯方块游戏.分享给大家供大家参考,具体如下: 试玩(没有考虑兼容低版本浏览器): ********************************************************************** 9月3日更新: 修复了隐藏的比较深的BUG 加上暂停.再来一次功能 速度随分数增高而递减 添加log日志 ****************************************************************

  • JavaScript实现简洁的俄罗斯方块完整实例

    本文实例讲述了JavaScript实现简洁的俄罗斯方块.分享给大家供大家参考,具体如下: 先来看看运行效果图: 完整实例代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>俄罗斯方块</title> <style ty

  • javascript实现俄罗斯方块游戏的思路和方法

    观摩一下<编程之美>:"程序虽然很难写,却很美妙.要想把程序写好,需要写好一定的基础知识,包括编程语言.数据结构与算法.程序写得好,需要缜密的逻辑思维能力和良好的梳理基础,而且熟悉编程环境和编程工具." 学了几年的计算机,你有没有爱上编程.话说,没有尝试自己写过一个游戏,算不上热爱编程. 俄罗斯方块曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事,它看似简单但却变化无穷,令人上瘾.相信大多数同学,曾经为它痴迷得茶不思饭不想. 游戏规则 1.一个用于摆放小型正方形的平

  • js html5 css俄罗斯方块游戏再现

    这个游戏主要分为三部份,HTML5+CSS+JAVASCRIPT来完成的.在这里详细讲一下js的代码.因为这个游戏的主要部分其实就是js. 大多数都是靠js来完成的. 完成后的效果如下: HTML代码: <body> <div class="wrap"> <div class="play_wrap"> <div id="play_area"></div> <div class=&q

  • JS 俄罗斯方块完美注释版代码

    R #board tr td{ width: 20px; height: 20px; } /** * JS俄罗斯方块完美注释版 v 1.01 * 从学c语言那一会儿都想写一个俄罗斯方块,可是每次动起手总觉得难度太大. * 今天终于用了大约4个小时写出来了. 其中在涉及到方块变型的时候还咨询了 * 同学来帮忙; * * 个人觉得难点有这么几个: * 1: 边界检查, 不多说, 想通了就行 * 2: 旋转, 还是数学上的方法, 一个点相对另外一个点旋转90度的问题. * 4: 让整个程序在点开始之后

随机推荐