20250805-40
js实在是太有趣了,昨天晚上花了两个多小时写了一个简易的贪吃蛇,逻辑并不难,今天做了Flappybird的小鸟的运动模块,明天继续研究研究
贪吃蛇练习代码如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { color: #ffffff; font-size: 100px; font-weight: bolder; margin: 0; display: flex; min-height: 100vh; justify-content: center; align-items: center; background-color: #000000; } .grid { display: grid; /* gap: 2px; */ width: auto; height: auto; background-color: #000000; } .cell { width: 30px; height: 30px; background-color: #ffffff; } </style> </head> <body> <script> gamebegin(25, 25) //游戏开始 function gamebegin(row, col) { let snakecolor='green' let foodcolor='red' //储存所有网格 let cells = [] cells = creategrid(row, col) //储存蛇身 let snake = [] //随机网格选蛇头并推入snake数组尾部 let head = randomint(0, row * col - 1) snake.push(head) cells[head].style.backgroundColor = snakecolor //初始化食物 cells[randomint(0, row * col - 1)].style.backgroundColor = foodcolor //初始化方向 let direct = 3 //添加键盘事件 document.addEventListener('keydown', function (e) { if (e.key === 'ArrowUp' && (direct != 1 || snake.length === 1)) direct = 0 if (e.key === 'ArrowDown' && (direct != 0 || snake.length === 1)) direct = 1 if (e.key === 'ArrowLeft' && (direct != 3 || snake.length === 1)) direct = 2 if (e.key === 'ArrowRight' && (direct != 2 || snake.length === 1)) direct = 3 }) //定时处理方向位置的新蛇头 let nexthead const move = setInterval(function () { switch (direct) { case 0://上 if (head < col)//边界处理,以下同上 nexthead = head + col * (row - 1) else nexthead = head - col break; case 1://下 if (head >= col * (row - 1)) nexthead = head - col * (row - 1) else nexthead = head + col break; case 2://左 if (head % col === 0) nexthead += col - 1 else nexthead = head - 1 break; case 3://右 if ((head + 1) % col === 0) nexthead -= col - 1 else nexthead = head + 1 break; } //先尾部判断是否下一步是食物,是则尾部停一步,用来加长蛇身 if (cells[nexthead].style.backgroundColor != foodcolor) { cells[snake[0]].style.backgroundColor = '#ffffff' snake.shift() } //再头部判断是否会撞到自己蛇身 if (cells[nexthead].style.backgroundColor != snakecolor) { snake.push(nexthead) //防止食物生成在蛇身所在位置(效率待优化) if (cells[nexthead].style.backgroundColor === foodcolor) { let randomindex = randomint(0, row * col - 1) while (snake.includes(randomindex)) randomindex = randomint(0, row * col - 1) cells[randomindex].style.backgroundColor = foodcolor } //增加新蛇头 cells[nexthead].style.backgroundColor = snakecolor head = nexthead } else //失败 document.body.innerHTML = "YOU LOSE !" //检测是否霸屏,是则通关 if (snake.length == row * col) document.body.innerHTML = "YOU WIN !" }, 200) } //生成网格 function creategrid(row, col) { let cells = [] const grid = document.createElement('div') grid.classList.add('grid') //定义网格的行列数 grid.style.gridTemplateColumns = `repeat(${col},30px)` grid.style.gridTemplateRows = `repeat(${row},30px)` //将所有单元添加到网格 for (let i = 0; i < row * col; i++) { const cell = document.createElement('div') cell.classList.add('cell') grid.appendChild(cell) cells.push(cell) } document.body.appendChild(grid) //返回所有网格 return cells } //随机数函数 function randomint(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } </script> </body> </html>
Flappybird练习代码如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { margin: 0; display: flex; justify-content: center; height: 100vh; align-items: center; } .box { width: 1200px; height: 800px; background-color: #000; overflow: hidden; position: relative; } .bird { position: relative; transform: translate(-50%, -50%); top: 100px; left: 15%; width: 50px; height: 50px; background-color: #ff0000; } .pillar { background-color: chartreuse; width: 80px; position: absolute; left: 1200px; top: 0; } .show { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 100px; font-weight: bolder; } </style> </head> <body> <script> //初始背景 const box = document.createElement('div') box.classList.add('box') document.body.appendChild(box) //游戏开始 gamebegin() //游戏开始函数 function gamebegin() { //创建玩家 const bird = createbird() //初始速度 speed = 0; //计数器,用于后续平衡速度 i = 0 const birdtimer = setInterval(function () { i++ //每五次计数增加下落速度,同时限制最大速度大小,避免加速度和速度过大 if (i % 5 === 0 && speed <= 10) speed++ let y = +bird.style.top.replace(/px/g, "") //防止飞出上边框 if (y < 0) { y = 0 speed = 0 } bird.style.top = `${y += speed}px` //飞出下边框将导致游戏失败 if (+bird.style.top.replace(/px/g, "") >= 800) { //失败函数 fail() //清除计数器 clearInterval(birdtimer) clearInterval(createpillar) clearInterval(pillarmove) clearInterval(crushcheck) //清除遗存柱子 const ps = document.querySelectorAll('.pillar'); for (let p of ps) p.remove(); } }, 16) //键盘事件,空格飞升 document.addEventListener('keydown', function (e) { if (e.key === ' ') speed = -7//按下空格后速度变化为向上的 '7',达到飞升的效果 }) //定时创建柱子 const createpillar = setInterval(function () { //同时创建上下两条 const pillar1 = document.createElement('div') pillar1.classList.add('pillar') const pillar2 = document.createElement('div') pillar2.classList.add('pillar') //随机缺口位置,缺口大小固定为 200px let h1 = randomint(1, 5) * 100 let h2 = 600 - h1 pillar1.style.height = `${h1}px` pillar2.style.height = `${h2}px` pillar2.style.top = `${h1 + 200}px` //添加到界面 box.appendChild(pillar1) box.appendChild(pillar2) }, 2000) //柱子移动 const pillarmove = setInterval(function () { const pillars = document.querySelectorAll('.pillar') for (const pillar of pillars) { let x = +getComputedStyle(pillar).left.replace(/px/g, "") //柱子移出界面时移除,优化性能 if (x < 0) pillar.remove() else { x -= 4 pillar.style.left = `${x}px` } } }, 16) } //碰撞检测 crushcheck = setInterval(function () { const pillars = document.querySelectorAll('.pillar'); const birds = document.querySelectorAll('.bird'); for (let pillar of pillars) { const p = pillar.getBoundingClientRect(); for (let bird of birds) { const b = bird.getBoundingClientRect(); if (b.left < p.right && b.right > p.left && b.top < p.bottom && b.bottom > p.top) { fail(); clearInterval(birdtimer); clearInterval(createpillar); clearInterval(pillarmove); clearInterval(crushcheck); const ps = document.querySelectorAll('.pillar'); for (let p of ps) p.remove(); } } } }, 16); //创建玩家函数 function createbird() { const bird = document.createElement('div') bird.classList.add('bird') box.appendChild(bird) return bird } //失败函数 function fail() { box.innerHTML = '' const show = document.createElement('div') show.classList.add('show') show.innerHTML = "YOU FAILED" box.appendChild(show) } //随机整数函数 function randomint(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } </script> </body> </html>

浙公网安备 33010602011771号