js canvas实现俄罗斯方块


Posted in Javascript onOctober 11, 2020

本文实例为大家分享了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>

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

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

Javascript 相关文章推荐
javascript 构建一个xmlhttp对象池合理创建和使用xmlhttp对象
Jan 15 Javascript
60行js代码实现俄罗斯方块
Mar 31 Javascript
js实现键盘Enter键提交表单的方法
May 27 Javascript
jquery实现经典的淡入淡出选项卡效果代码
Sep 22 Javascript
浅谈jquery高级方法描述与应用
Oct 04 Javascript
JavaScript中捕获/阻止捕获、冒泡/阻止冒泡方法
Dec 07 Javascript
使用JS 插件qrcode.js生成二维码功能
Feb 20 Javascript
微信小程序 页面传值详解
Mar 10 Javascript
jquery replace方法去空格
May 08 jQuery
Angular2 http jsonp的实例详解
Aug 31 Javascript
利用jsonp解决js读取本地json跨域的问题
Dec 11 Javascript
vue2.0中set添加属性后视图不能更新的解决办法
Feb 22 Javascript
利用js canvas实现五子棋游戏
Oct 11 #Javascript
H5+css3+js搭建带验证码的登录页面
Oct 11 #Javascript
原生js生成图片验证码
Oct 11 #Javascript
js实现石头剪刀布游戏
Oct 11 #Javascript
js+h5 canvas实现图片验证码
Oct 11 #Javascript
vue2和vue3的v-if与v-for优先级对比学习
Oct 10 #Javascript
如何手写简易的 Vue Router
Oct 10 #Javascript
You might like
实用函数9
2007/11/08 PHP
在yii中新增一个用户验证的方法详解
2013/06/20 PHP
学习php设计模式 php实现单例模式(singleton)
2015/12/07 PHP
基于jquery实现后台左侧菜单点击上下滑动显示
2013/04/11 Javascript
js 获取和设置css3 属性值的实现方法
2013/05/06 Javascript
jquery中的ajax方法怎样通过JSONP进行远程调用
2014/05/04 Javascript
javascript学习笔记之函数定义
2015/06/25 Javascript
jQuery实现图片与文字描述左右滑动自动切换的方法
2015/07/27 Javascript
基于JavaScript实现表格滚动分页
2017/11/22 Javascript
vue中的provide/inject的学习使用
2018/05/09 Javascript
js实现ATM机存取款功能
2020/10/27 Javascript
Javascript confirm多种使用方法解析
2020/09/25 Javascript
python 获取文件列表(或是目录例表)
2009/03/25 Python
详解Python中映射类型的内建函数和工厂函数
2015/08/19 Python
浅析Python3爬虫登录模拟
2018/02/07 Python
matplotlib 纵坐标轴显示数据值的实例
2018/05/25 Python
浅谈Python中的bs4基础
2018/10/21 Python
解决python给列表里添加字典时被最后一个覆盖的问题
2019/01/21 Python
pycharm通过ssh连接远程服务器教程
2020/02/12 Python
python_mask_array的用法
2020/02/18 Python
Python用5行代码实现批量抠图的示例代码
2020/04/14 Python
在keras下实现多个模型的融合方式
2020/05/23 Python
python将字典内容写入json文件的实例代码
2020/08/12 Python
Python 整行读取文本方法并去掉readlines换行\n操作
2020/09/03 Python
matplotlib之pyplot模块之标题(title()和suptitle())
2021/02/22 Python
详解HTML5 Canvas绘制不规则图形时的非零环绕原则
2016/03/21 HTML / CSS
WiFi云数码相框:Nixplay
2018/07/05 全球购物
自行车租赁公司创业计划书
2014/01/28 职场文书
小学生读书感言
2014/02/12 职场文书
庆元旦演讲稿
2014/09/15 职场文书
个人批评与自我批评发言稿
2014/09/28 职场文书
教师节标语大全
2014/10/07 职场文书
接待员岗位职责
2015/02/13 职场文书
2015毕业生实习期工作总结
2015/04/09 职场文书
行政二审代理词
2015/05/25 职场文书
Vue如何实现组件间通信
2021/05/15 Vue.js