FlyBird小游戏是css、js、html相结合制作的。
![]()
整体思路:
首先将窗体做出,把背景图放在面板中,然后添加计分和游戏结束游戏开始的画面,把游戏背景中地面移动实现把柱子在面板中实现进场及移动,小鸟放在面板中鼠标点击控制小鸟上升下降,最后写判断小鸟与柱子碰撞、地面碰撞和窗体顶部碰撞的方法。
HTML代码如下:
HTML引用css 、js来实现动画效果,audio src添加了背景音乐以及声音特效。
css代码如下:
| |
#box { width: 343px; height: 480px; background: url("../img/bg.jpg"); margin: 100px auto 0; position: relative; user-select: none; overflow: hidden }
#scoreBoard { text-align: center; position: absolute; top: 30px; width: 100% }
@keyframes header { from { top: 75px } 50% { top: 115px } to { top: 75px } }
#header { width: 80%; position: absolute; left: 10%; top: 75px; animation: header 1.2s linear infinite }
#header > div { position: absolute; right: 10px; top: 20px; background: url("../img/bird1.png") no-repeat }
@keyframes bird { 0% { opacity: 1 } 50% { opacity: 0 } 100% { opacity: 1; } }
#header > div > img { animation: bird .3s linear infinite }
#start { position: absolute; left: 129px; top: 300px }
@keyframes slider { 0% { left: 0 } 100% { left: -343px } }
#slider { width: 999px; position: absolute; top: 422px; animation: slider 5s linear infinite }
#slider > img { float: left }
#flyBird { display: none; position: absolute; left: 40px; top: 75px }
#pipeBox { width: 100%; height: 422px; position: absolute; left: 0; top: 0; margin: 0; padding: 0; list-style: none }
#pipeBox > li { width: 62px; height: 100%; position: absolute; left: 400px; }
#pipeBox > li > div:nth-child(1) { width: 100%; background: url("../img/up_mod.png"); position: absolute }
#pipeBox > li > div:nth-child(1) > img { position: absolute; bottom: 0 }
#pipeBox > li > div:nth-child(2) { width: 100%; background: url("../img/down_mod.png"); position: absolute; bottom: 0 } @keyframes gameOver { from{top:-200px;} to{top:150px} } #gameOver { position: absolute; top: 150px; width: 100%; text-align: center; display: none; animation: gameOver 1s linear; }
|
js代码如下:
| |
const start = document.getElementById('start') const header = document.getElementById('header') const flyBird = document.getElementById('flyBird') const box = document.getElementById('box') const pipeBox = document.getElementById('pipeBox') const scoreBoard = document.getElementById('scoreBoard') const gameOver = document.getElementById('gameOver') const ok = document.getElementById('ok')
const audios = document.getElementsByTagName('audio')
let speed = 0 const maxSpeed = 8
let downTimer = null let upTimer = null let pipeTimer = null let crashTimer = null
let scoreNum = 0
function birdDown() { //小鸟头朝下 flyBird.src = 'img/down_bird0.png' // speed=speed+.3//0.3 0.6 0.9 1.2 1.5 1.8 // if(speed>=maxSpeed){ // speed=maxSpeed // } speed = speed < maxSpeed ? speed + .3 : maxSpeed flyBird.style.top = flyBird.offsetTop + speed + 'px' }
function crash(obj1, obj2) { if (obj1.offsetLeft + obj1.offsetWidth < obj2.parentElement.offsetLeft || obj2.parentElement.offsetLeft + obj2.offsetWidth < obj1.offsetLeft || obj1.offsetTop + obj1.offsetHeight < obj2.offsetTop || obj2.offsetTop + obj2.offsetHeight < obj1.offsetTop) return false return true }
function death() { clearInterval(downTimer)// const lis = pipeBox.getElementsByTagName('li') for (let i = 0; i < lis.length; i++) { clearInterval(lis[i].appearTimer) } clearInterval(pipeTimer) clearInterval(upTimer) clearInterval(crashTimer) box.onclick = null audios[2].play() audios[0].pause() gameOver.style.display = 'block' ok.onclick = function () { window.location.reload() } }
start.onclick = function (event) { let ev = event || window.event if (ev.stopPropagation) { ev.stopPropagation()//部分浏览器清除事件冒泡的方式 } else { ev.cancelBubble = true//另一部分浏览器清除事件冒泡的方式 } //1.start和header消失 start.style.display = 'none' header.style.display = 'none' //2.出现小鸟,并且工作 flyBird.style.display = 'inline-block' downTimer = setInterval(birdDown, 30)
box.onclick = function () { //小鸟头朝上 flyBird.src = 'img/up_bird0.png' //停止下落 clearInterval(downTimer) // clearInterval(upTimer) audios[1].play() speed = maxSpeed upTimer = setInterval(function () { speed = speed - .7 if (speed <= 0) { //清除当前定时器,使小鸟不上升 clearInterval(upTimer) //再次调用downTimer downTimer = setInterval(birdDown, 30) } flyBird.style.top = flyBird.offsetTop - speed + 'px' }, 30) } //3.出现柱子,并且工作 pipeTimer = setInterval(function () { let li = document.createElement('li')// let topH = Math.random() * (240 - 60) + 60 let bottomH = 300 - topH li.innerHTML = ` <div style="height: ${topH}px"> <img src="img/up_pipe.png" alt=""> </div> <div style="height: ${bottomH}px"> <img src="img/down_pipe.png" alt=""> </div> ` li.lock = false
li.appearTimer = setInterval(function () { li.style.left = li.offsetLeft - 3 + 'px' if (!li.lock && li.offsetLeft + li.offsetWidth < flyBird.offsetLeft) {
//加分函数 !function () { scoreNum++ console.log(scoreNum) let scoreStr = String(scoreNum)//380 scoreBoard.innerHTML = '' for (let i = 0; i < scoreStr.length; i++) { scoreBoard.innerHTML = scoreBoard.innerHTML + '<img src="img/' + scoreStr[i] + '.jpg">' } }() li.lock = true } if (li.offsetLeft < -70) { pipeBox.removeChild(li) } }, 30) pipeBox.appendChild(li) /*let topH = Math.random() * 180 + 60 let bottomH = 300 - topH console.log() pipeBox.innerHTML=` ${pipeBox.innerHTML} <li> <div style="height: ${topH}px"> <img src="img/up_pipe.png" alt=""> </div> <div style="height: ${bottomH}px" > <img src="img/down_pipe.png" alt=""> </div> </li> `*/ }, 3000) //4.死亡 crashTimer = setInterval(function () { //天花板或地板死亡 if (flyBird.offsetTop <= 0 || flyBird.offsetTop + flyBird.offsetHeight >= 422) { death() } //碰到管道 const lis = pipeBox.getElementsByTagName('li') for (let i = 0; i < lis.length; i++) { if (crash(flyBird, lis[i].children[0]) || crash(flyBird, lis[i].children[1])) { death() } }
}, 30) //5.BGM audios[0].play() }
|