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 相关文章推荐
使用js在页面中绘制表格核心代码
Sep 16 Javascript
jQuery圆形统计图开发实例
Jan 04 Javascript
JavaScript设计模式之工厂模式和构造器模式
Feb 11 Javascript
常用DOM整理
Jun 16 Javascript
基于BootStrap Metronic开发框架经验小结【七】数据的导入、导出及附件的查看处理
May 12 Javascript
jQuery右下角悬浮广告实例
Oct 17 Javascript
BootStrap实现鼠标悬停下拉列表功能
Feb 17 Javascript
vue-router+nginx 非根路径配置方法
Jun 30 Javascript
js设计模式之单例模式原理与用法详解
Aug 15 Javascript
浅谈js中的attributes和Attribute的用法与区别
Jul 16 Javascript
element中table高度自适应的实现
Oct 21 Javascript
Selenium执行JavaScript脚本的方法示例
Dec 31 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
PHP4中实现动态代理
2006/10/09 PHP
解析数组非数字键名引号的必要性
2013/08/09 PHP
php创建多级目录的方法
2015/03/24 PHP
PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
2017/06/20 PHP
十分钟打造AutoComplete自动完成效果代码
2009/12/26 Javascript
div拖拽插件——JQ.MoveBox.js(自制JQ插件)
2013/05/17 Javascript
Jquery的hover方法让鼠标经过li时背景变色
2013/09/06 Javascript
JQuery伸缩导航练习示例
2013/11/13 Javascript
angularjs基础教程
2014/12/25 Javascript
jQuery的bind()方法使用详解
2015/07/15 Javascript
js+html5实现canvas绘制网页时钟的方法
2016/05/21 Javascript
js实现带三角符的手风琴效果
2017/03/01 Javascript
微信小程序 图片上传实例详解
2017/05/05 Javascript
Agularjs妙用双向数据绑定实现手风琴效果
2017/05/26 Javascript
微信小程序 转发功能的实现
2017/08/04 Javascript
判断iOS、Android以及PC端的示例代码
2018/11/15 Javascript
详解vue 兼容IE报错解决方案
2018/12/29 Javascript
详解基于webpack&amp;gettext的前端多语言方案
2019/01/29 Javascript
js构造函数constructor和原型prototype原理与用法实例分析
2020/03/02 Javascript
深入理解Python 关于supper 的 用法和原理
2018/02/28 Python
python 通过字符串调用对象属性或方法的实例讲解
2018/04/21 Python
python实现对csv文件的列的内容读取
2018/07/04 Python
python中property属性的介绍及其应用详解
2019/08/29 Python
python3实现用turtle模块画一棵随机樱花树
2019/11/21 Python
python正则表达式实例代码
2020/03/03 Python
CSS3 优势以及网页设计师如何使用CSS3技术
2009/07/29 HTML / CSS
获奖的大学生创业计划书
2014/01/05 职场文书
缓刑人员的思想汇报
2014/01/11 职场文书
函授生自我鉴定
2014/03/25 职场文书
代理协议书
2014/04/22 职场文书
主题团日活动总结
2014/06/25 职场文书
2014年党课学习心得体会
2014/07/08 职场文书
文秘班元旦晚会活动策划方案
2014/08/28 职场文书
党的群众路线教育实践活动党员个人整改措施
2014/10/27 职场文书
单位租房协议书样本
2014/10/30 职场文书
先进个人推荐材料
2014/12/29 职场文书