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 相关文章推荐
jQuery中文入门指南,翻译加实例,jQuery的起点教程
Jan 13 Javascript
jquery select多选框的左右移动 具体实现代码
Jul 03 Javascript
javascript中自定义对象的属性方法分享
Jul 12 Javascript
JavaScript返回0-1之间随机数的方法
Apr 06 Javascript
jQuery+css3实现Ajax点击后动态删除功能的方法
Aug 10 Javascript
JavaScript常用基础知识强化学习
Dec 09 Javascript
使用Bootstrap框架制作查询页面的界面实例代码
May 27 Javascript
使用Vue.js创建一个时间跟踪的单页应用
Nov 28 Javascript
JS设置时间无效问题的解决办法
Feb 18 Javascript
WdatePicker.js时间日期插件的使用方法
Jul 26 Javascript
vue2过滤器模糊查询方法
Sep 16 Javascript
Vue实现星级评价效果实例详解
Dec 30 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
探讨fckeditor在Php中的配置详解
2013/06/08 PHP
用Zend Studio+PHPnow+Zend Debugger搭建PHP服务器调试环境步骤
2014/01/19 PHP
PHP使用mysql_fetch_row查询获得数据行列表的方法
2015/03/18 PHP
PHP文件上传处理案例分析
2016/10/15 PHP
基于CI框架的微信网页授权库示例
2016/11/25 PHP
Laravel Intervention/image图片处理扩展包的安装、使用与可能遇到的坑详解
2017/11/14 PHP
Laravel框架控制器的middleware中间件用法分析
2019/09/30 PHP
js getBoundingClientRect() 来获取页面元素的位置
2010/11/25 Javascript
js window.open弹出新的网页窗口
2014/01/16 Javascript
Jquery EasyUI中弹出确认对话框以及加载效果示例代码
2014/02/13 Javascript
事件委托与阻止冒泡阻止其父元素事件触发
2014/09/02 Javascript
使用Nodejs开发微信公众号后台服务实例
2014/09/03 NodeJs
JQuery拖动表头边框线调整表格列宽效果代码
2014/09/10 Javascript
Nodejs实现的一个简单udp广播服务器、客户端
2014/09/25 NodeJs
js中scrollTop()方法和scroll()方法用法示例
2016/10/03 Javascript
微信小程序组件之srcoll-view的详解
2017/10/19 Javascript
jQuery图片查看插件Magnify开发详解
2017/12/25 jQuery
解决vuecli3.0热更新失效的问题
2018/09/19 Javascript
一起写一个即插即用的Vue Loading插件实现
2019/10/31 Javascript
Vue的双向数据绑定实现原理解析
2020/02/17 Javascript
vue 输入电话号码自动按3-4-4分割功能的实现代码
2020/04/30 Javascript
taro 实现购物车逻辑的实例代码
2020/06/05 Javascript
python3连接MySQL数据库实例详解
2018/05/24 Python
tensorflow实现加载mnist数据集
2018/09/08 Python
python实现一组典型数据格式转换
2018/12/15 Python
Python-接口开发入门解析
2019/08/01 Python
一款纯css3实现的颜色渐变按钮的代码教程
2014/11/12 HTML / CSS
美国宠物商店:Wag.com
2016/10/25 全球购物
美国现代家具购物网站:LexMod
2019/01/09 全球购物
英国女性化妆品收纳和家具网站:Beautify
2019/12/07 全球购物
求职推荐信范文
2013/12/01 职场文书
会计大学生职业生涯规划书范文
2014/01/13 职场文书
2014年保洁员工作总结
2014/11/19 职场文书
红色影片观后感
2015/06/18 职场文书
社区低保工作总结2015
2015/07/23 职场文书
vue-cli4.5.x快速搭建项目
2021/05/30 Vue.js