// 随机数 function random(min, max) { if(max){ return Math.floor(Math.random() * (max - min)) + min; } else{ return Math.floor(Math.random() * 10); } } // 定义尺寸 const lengthX=50 const lengthY=50 const backWidth=16 const backHeight=16 // 游戏当前模式 let gameMode=null // 蛇数组 let snakeAll=[] // 食物模型 const food=document.createElement('div') food.style.width=backWidth+'px' food.style.height=backHeight+'px' food.classList.add('food') for(let i=0;i<4;i++){ let foodSingle=document.createElement('div') foodSingle.classList.add('foodSingle') food.appendChild(foodSingle) } // 食物总数 let foodNumber=0 let foodNumberNow=0 // 颜色 let color=['AliceBlue','PaleGoldenrod','Cyan','LightBlue','LightCyan','Beige','LightGrey','LightGreen'] // 创建地图 const map=document.createElement('div') map.style.width=lengthX*backWidth+'px' map.style.height=lengthY*backHeight+'px' map.classList.add('map') document.body.appendChild(map) // 添加地图格子 let mapBlock=[] for(let i=0;i=0 && mapBlock[Number(parentNode.dataset.mapBlockX)-1][Number(parentNode.dataset.mapBlockY)].childNodes.length===0){ snakeAll[i].snake.unshift(snake) mapBlock[Number(parentNode.dataset.mapBlockX)-1][Number(parentNode.dataset.mapBlockY)].appendChild(snake) snakeAll[i].snake[snakeAll[i].snake.length-1].parentNode.removeChild(snakeAll[i].snake[snakeAll[i].snake.length-1]) snakeAll[i].snake.pop() } else if(Number(parentNode.dataset.mapBlockX)-1<=0){ snakeDie(snakeAll[i].snake,i) } else{ if(mapBlock[Number(parentNode.dataset.mapBlockX)-1][Number(parentNode.dataset.mapBlockY)].childNodes[0].classList.contains('food')){ foodEat(mapBlock[Number(parentNode.dataset.mapBlockX)-1][Number(parentNode.dataset.mapBlockY)],snakeAll[i].snake,snake) } else{ snakeDie(snakeAll[i].snake,i) } } break case 1: parentNode=snakeAll[i].snake[0].parentNode if (Number(parentNode.dataset.mapBlockX)+1=lengthX-1){ snakeDie(snakeAll[i].snake,i) } else{ if(mapBlock[Number(parentNode.dataset.mapBlockX)+1][Number(parentNode.dataset.mapBlockY)].childNodes[0].classList.contains('food')){ foodEat(mapBlock[Number(parentNode.dataset.mapBlockX)+1][Number(parentNode.dataset.mapBlockY)],snakeAll[i].snake,snake) } else{ snakeDie(snakeAll[i].snake,i) } } break case 2: parentNode=snakeAll[i].snake[0].parentNode if (Number(parentNode.dataset.mapBlockY)-1>=0 && mapBlock[Number(parentNode.dataset.mapBlockX)][Number(parentNode.dataset.mapBlockY)-1].childNodes.length===0){ snakeAll[i].snake.unshift(snake) mapBlock[Number(parentNode.dataset.mapBlockX)][Number(parentNode.dataset.mapBlockY)-1].appendChild(snake) snakeAll[i].snake[snakeAll[i].snake.length-1].parentNode.removeChild(snakeAll[i].snake[snakeAll[i].snake.length-1]) snakeAll[i].snake.pop() } else if(Number(parentNode.dataset.mapBlockY)-1<=0){ snakeDie(snakeAll[i].snake,i) } else{ if(mapBlock[Number(parentNode.dataset.mapBlockX)][Number(parentNode.dataset.mapBlockY)-1].childNodes[0].classList.contains('food')){ foodEat(mapBlock[Number(parentNode.dataset.mapBlockX)][Number(parentNode.dataset.mapBlockY)-1],snakeAll[i].snake,snake) } else{ snakeDie(snakeAll[i].snake,i) } } break case 3: parentNode=snakeAll[i].snake[0].parentNode if (Number(parentNode.dataset.mapBlockY)+1=lengthY-1){ snakeDie(snakeAll[i].snake,i) } else{ if(mapBlock[Number(parentNode.dataset.mapBlockX)][Number(parentNode.dataset.mapBlockY)+1].childNodes[0].classList.contains('food')){ foodEat(mapBlock[Number(parentNode.dataset.mapBlockX)][Number(parentNode.dataset.mapBlockY)+1],snakeAll[i].snake,snake) } else{ snakeDie(snakeAll[i].snake,i) } } break } } } setInterval(move,moveSpeed) // 死亡函数 function snakeDie(snake,site){ snakeAll.splice(site,1) if (snake[0].dataset.id==='0'){ diePanelOpen(snake) return } if(gameMode==='double'&&snake[0].dataset.id==='1'){ diePanelOpen(snake) return } for (let i = 0; i < snake.length/3*2 ; i++) { let parentNode = snake[snake.length-1].parentNode parentNode.removeChild(snake[snake.length-1]) snake.pop() parentNode.appendChild(food.cloneNode(true)) foodNumberNow+=1 } for (let i = snake.length-1; i >= 0 ;--i) { snake[i].parentNode.removeChild(snake[i]) snake.pop() } snakeCreate() } // 清空地图函数 function mapClear() { foodNumberNow=0 snakeAll=null snakeAll=[] const snakeClear=document.querySelectorAll('.snake') for (let i = 0; i < snakeClear.length ; i++) { snakeClear[i].parentNode.removeChild(snakeClear[i]) } const foodClear=document.querySelectorAll('.food') for (let i = 0; i < foodClear.length ; i++) { foodClear[i].parentNode.removeChild(foodClear[i]) } } // 死亡面板 const diePanelInfo=document.createElement('div') diePanelInfo.classList.add('diePanelInfo') map.appendChild(diePanelInfo) const diePanelText=document.createElement('div') diePanelInfo.appendChild(diePanelText) const diePanelScoreDiv=document.createElement('div') diePanelInfo.appendChild(diePanelScoreDiv) const diePanelScoreText=document.createElement('p') diePanelScoreText.innerText=`长度:` diePanelScoreDiv.appendChild(diePanelScoreText) const diePanelScore=document.createElement('p') diePanelScoreDiv.appendChild(diePanelScore) const diePanelPick=document.createElement('div') diePanelPick.classList.add('diePanelPick') map.appendChild(diePanelPick) diePanelPick.addEventListener('click',mapClear) diePanelPick.addEventListener('click',function () { diePanelInfo.style.display='none' diePanelPick.style.display='none' }) const diePickHome=document.createElement('div') diePickHome.innerText="返回主页" diePanelPick.appendChild(diePickHome) diePickHome.addEventListener('click',function (){ gameMode = null mapTextNameDiv.style.display='block' mapTextStartDiv.style.display='block' }) const diePickRest=document.createElement('div') diePickRest.innerText="重新开始" diePanelPick.appendChild(diePickRest) diePickRest.addEventListener('click',function (){ if (gameMode==='single'){singleMode()} else if (gameMode==='double'){doubleMode()} else if (gameMode==='double'){aiMode()} }) // 开始死亡面板函数 function diePanelOpen(snake){ document.removeEventListener('click',key1) document.removeEventListener('click',key2) clearInterval(aiMoveTime) playerOneDiv.style.display="none" playerTwoDiv.style.display="none" diePanelInfo.style.display='block' diePanelPick.style.display='block' snakeAll=null snakeAll=[] if(gameMode==='single'||gameMode==='ai'){ diePanelScoreText.style.display='inline-block' diePanelText.innerText='游戏结束' diePanelScore.innerText=playerOneScore.innerText } else if(gameMode==='double'){ diePanelScoreText.style.display='none' if(snake[0].dataset.id==='1'){ diePanelScore.innerHTML='一号获胜' } else{ diePanelScore.innerHTML='二号获胜' } } } // 人机移动逻辑 function aiMove(snake){ const food=document.querySelectorAll('.food')[snake.snake[0].dataset.id] const snakeX=Number(snake.snake[0].parentNode.dataset.mapBlockX) const snakeY=Number(snake.snake[0].parentNode.dataset.mapBlockY) const foodX=Number(food.parentNode.dataset.mapBlockX) const foodY=Number(food.parentNode.dataset.mapBlockY) if(snake.direction!=='1'&&snakeX-1>=0&&mapBlock[snakeX-1][snakeY].childNodes.length>0){ if (mapBlock[snakeX-1][snakeY].children[0].classList.contains('food')){ snake.directionTest=0 return } } if(snake.direction!=='0'&&snakeX+10){ if (mapBlock[snakeX+1][snakeY].children[0].classList.contains('food')){ snake.directionTest=1 return } } if(snake.direction!=='3'&&snakeY-1>=0&&mapBlock[snakeX][snakeY-1].childNodes.length>0){ if (mapBlock[snakeX][snakeY-1].children[0].classList.contains('food')){ snake.directionTest=2 return } } if(snake.direction!=='2'&&snakeY+10){ if (mapBlock[snakeX][snakeY+1].children[0].classList.contains('food')){ snake.directionTest=3 return } } switch(random(0,2)){ case 0: if(snake.direction!=='1'&&snakeX-1>=0&&foodX>snakeX&&mapBlock[snakeX-1][snakeY].childNodes.length===0){ snake.directionTest=0 return } if(snake.direction!=='0'&&snakeX+1=0&&foodY>snakeY&&mapBlock[snakeX][snakeY-1].childNodes.length===0){ snake.directionTest=2 return } if(snake.direction!=='2'&&snakeY+1=0&&mapBlock[snakeX][snakeY-1].childNodes.length===0){ snake.directionTest=2 return } if(snake.direction!=='0'&&snakeX+1=0&&mapBlock[snakeX-1][snakeY].childNodes.length===0){ snake.directionTest=0 return } } } function aiMoveOpen(){ if (snakeAll.length===1){ return } else if (snakeAll.length===0){ clearInterval(aiMoveTime) return } for (let i = 1; i < snakeAll.length ; i++) { aiMove(snakeAll[i]) } } let aiMoveTime // 按键监听 const key1=function(e){ if(snakeAll.length>0){ if (e.key==='w'){ snakeAll[0].directionTest=0 } else if (e.key==='s'){ snakeAll[0].directionTest=1 } else if (e.key==='a'){ snakeAll[0].directionTest=2 } else if (e.key==='d'){ snakeAll[0].directionTest=3 } } if(snakeAll.length>0){ if (e.key==="ArrowUp"){ snakeAll[1].directionTest=0 } else if (e.key==="ArrowDown"){ snakeAll[1].directionTest=1 } else if (e.key==="ArrowLeft"){ snakeAll[1].directionTest=2 } else if (e.key==="ArrowRight"){ snakeAll[1].directionTest=3 } } } const key2=function(e){ if(snakeAll.length>0){ if (e.key==="ArrowUp"||e.key==='w'){ snakeAll[0].directionTest=0 } else if (e.key==="ArrowDown"||e.key==='s'){ snakeAll[0].directionTest=1 } else if (e.key==="ArrowLeft"||e.key==='a'){ snakeAll[0].directionTest=2 } else if (e.key==="ArrowRight"||e.key==='d'){ snakeAll[0].directionTest=3 } } } // 单人模式 function singleMode(){ // 改变当前模式 gameMode='single' // 开启辅助操作页面 playerOneDiv.style.display="block" // 生成蛇 snakeCreate() // 更换提示文字颜色 playerOneText.style.color=snakeAll[0].snake[0].style.backgroundColor; // 显示长度 playerOneScore.innerHTML=`${snakeAll[0].snake.length}` // 生成食物 foodNumber=10 for(let i=0;i