一、案例效果
二、实现思路
创建游戏背景板和小鸟,并分别设置相对定位与绝对定位;
初始化背景图的位置;
初始化小鸟的位置;
设置游戏状态,游戏开始时背景和管道全部向左运动,游戏结束全部停止运动;
使小鸟飞行,其实就是背景图在 X 轴方向的位置不断减小,实现小鸟向右飞行效果;
设置点击事件,每点击一次小鸟在Y轴的位置减小,实现向上飞的效果;
创建管道,X 方向上管道和下管道位置相同,Y 方向上上管道和下管道高度随机,但中间要空出200px;
实现管道向左运动,与背景图向左操作类似,也是在 X 轴方向的位置不断减小;
管道向左运动移出游戏面板最左侧时再回到原位重新执行,实现循环效果;
定义上下管道的临界值,也就是上下管道自身区域;
小鸟位置与上下管道位置重合(相碰撞)时游戏结束;
多次调用管道创建函数,产生多组管道。
三、完整代码+详细注释
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>小游戏:像素鸟</title> <style> * { margin: 0; padding: 0; } #game { width: 800px; height: 600px; background: url('./img/sky.png'); position: relative; margin: auto; overflow: hidden; } #bird { width: 34px; height: 25px; background: url(./img/birds.png) -10px -8px no-repeat; position: absolute; top: 100px; left: 100px; } </style> </head> <body> <!-- 游戏背景 --> <div id="game"> <!-- 小鸟 --> <div id="bird"></div> </div> </body> <script> //获取游戏背景和小鸟 var game = document.getElementById('game'); var birdEle = document.getElementById('bird'); //初始化背景图 var sky = { x: 0 //背景图初始位置为0 } //初始化小鸟 var bird = { speedX: 5, //小鸟在X轴的速度 SpeedY: 0, //小鸟在Y轴的速度 //小鸟坐标 x: birdEle.offsetLeft, //小鸟初始位置在绝对定位的位置 y: birdEle.offsetTop, } var runing = true; //游戏状态 setInterval(function () { if (runing) { //小鸟飞行(其实是背景在动) sky.x -= 5; //背景每次-5px,以实现向左运动的效果 game.style.backgroundPositionX = sky.x + 'px'; //小鸟上下运动 bird.SpeedY += 1; //每一次点击小鸟向上10px后开始自增也就是再自动向下 bird.y += bird.SpeedY; //小鸟自动不断向下运动 //判断游戏状态 if (bird.y < 0) { //超出游戏背景顶部时游戏结束 runing = false; bird.y = 0; } if (bird.y + birdEle.offsetHeight > 600) { //超出游戏背景底部时游戏结束 runing = false; bird.y = 600 - birdEle.offsetHeight; } birdEle.style.top = bird.y + 'px'; } }, 30); //点击时小鸟向上运动 document.onclick = function () { bird.SpeedY = -10; //点击一次向上运动10px } //创建管道 function creatPipe(position) { var pipe = {}; pipe.x = position; pipe.upHeight = 200 + parseInt(Math.random() * 100); //上管道高度为200 - 300px pipe.doHeight = 600 - pipe.upHeight - 200; //下管道高度 pipe.doTop = pipe.upHeight + 200; //上下两管道之间200px //创建上管道 var upPipe = document.createElement('div'); //新建div upPipe.style.width = '52px'; upPipe.style.height = pipe.upHeight + 'px'; upPipe.style.background = 'url(./img/pipe2.png) no-repeat center bottom'; upPipe.style.position = 'absolute'; upPipe.style.top = '0px'; upPipe.style.left = pipe.x + 'px'; game.appendChild(upPipe); //将上管道追加到游戏页面中 //创建下管道 var doPipe = document.createElement('div'); //新建div doPipe.style.width = '52px'; doPipe.style.height = pipe.doHeight + 'px'; doPipe.style.background = 'url(./img/pipe1.png) no-repeat center top'; doPipe.style.position = 'absolute'; doPipe.style.top = pipe.doTop + 'px'; doPipe.style.left = pipe.x + 'px'; game.appendChild(doPipe); //将下管道追加到游戏页面中 //管道进行运动 setInterval(function () { if (runing) { //游戏处于运行状态时管道再运动 pipe.x -= 2; //x方向不断-2px,以实现管道向左运动的效果 upPipe.style.left = pipe.x + 'px'; doPipe.style.left = pipe.x + 'px'; if (pipe.x < -52) { //管道移出最左侧时回到原位,实现不间断效果 pipe.x = 800; } //上下管道临界值 var uCheck = bird.x + 34 > pipe.x && bird.x < pipe.x + 52 && bird.y < pipe.upHeight; var dCheck = bird.x + 34 > pipe.x && bird.x < pipe.x + 52 && bird.y > pipe.upHeight + 200; if (uCheck || dCheck) { //碰到上管道或下管道临界值则游戏终止 runing = false; } } }, 30) } creatPipe(400); //产生四组管道 creatPipe(600); creatPipe(800); creatPipe(1000); </script> </html>
四、案例素材
sky.png
birds.png
pipe1.png
pipe2.png