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经典小游戏汇总
以上是 js canvas实现俄罗斯方块 的全部内容, 来源链接: utcz.com/z/359342.html