From 9b86fbfc93c5b01b8654064df15bb675bfca20ca Mon Sep 17 00:00:00 2001 From: lsy Date: Mon, 9 Sep 2024 13:44:53 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=94=E5=9B=9E=E4=B8=BB=E9=A1=B5=E6=9C=89?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/snake/main.html | 13 + web/snake/script.js | 672 ++++++++++++++++++++++++++++++++++++++++++++ web/snake/style.css | 127 +++++++++ 3 files changed, 812 insertions(+) create mode 100644 web/snake/main.html create mode 100644 web/snake/script.js create mode 100644 web/snake/style.css diff --git a/web/snake/main.html b/web/snake/main.html new file mode 100644 index 0000000..ce200dd --- /dev/null +++ b/web/snake/main.html @@ -0,0 +1,13 @@ + + + + + 贪吃蛇 + + + + + + + \ No newline at end of file diff --git a/web/snake/script.js b/web/snake/script.js new file mode 100644 index 0000000..2dfb8e5 --- /dev/null +++ b/web/snake/script.js @@ -0,0 +1,672 @@ +// 随机数 +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