<body>
<div class="title">
<img src="./img/head.jpg" alt=""><img src="./img/bird0.png">
</div>
<div class="start">
<img src="./img/start.jpg" alt="" id="ck">
</div>
<div class="jifenban">
<img src="./img/message.jpg" alt="" id="ck">
<p class="fenshu">0</p>
</div>
<!--管道-->
<ul>
<!--单根管道-->
<!-- <li> -->
<!--管道的上面部分-->
<!-- <div class="up_pipe"></div> -->
<!--管道的下面部分-->
<!-- <div class="down_pipe"></div> -->
<!-- </li> -->
</ul>
<!-- 飞翔的小鸟本鸟 -->
<img src="./img/bird1.png" id="bird">
<!-- 结束样式 -->
<img src="./img/game_over.jpg" alt="" id="game">
</body>
<style>
html,
body {
height: 100%;
}
body {
margin: 0;
background: url(./img/bg.jpg) left bottom repeat-x #6fc7cc;
}
/* 计分板 */
.jifenban {
position: absolute;
left: 50%;
width: 269px;
height: 135px;
transform: translateX(-50%);
z-index: 1;
display: none;
}
/* 分数 */
.jifenban>.fenshu {
width: 50px;
height: 50px;
position: absolute;
left: 32px;
top: 20px;
line-height: 50px;
text-align: center;
font-size: 30px;
font-weight: bold;
color: #fff;
}
.title,
.start {
position: absolute;
left: 50%;
z-index: 1;
}
.title {
top: 20%;
}
.start {
top: 50%;
cursor: pointer;
}
.title>img,
.start>img {
transform-origin: right;
transform: scale(2);
}
/* 管道样式 */
ul {
padding: 0;
margin: 0;
list-style: none;
width: 100vw;
height: calc(100vh - 57px);
position: relative;
top: 0;
left: 0;
/* display: flex; */
overflow: hidden;
}
ul>li {
width: 62px;
display: flex;
flex-wrap: wrap;
align-content: space-between;
/* transform: translateX(100vw); */
position: absolute;
top: 0;
bottom: 0;
left: 100vw;
}
ul>li>div {
width: 62px;
}
ul>li>.up_pipe {
background: url(./img/up_pipe.png) left bottom no-repeat, url(./img/up_mod.png) repeat-y;
}
ul>li>.down_pipe {
background: url(./img/down_pipe.png) left top no-repeat, url(./img/down_mod.png) repeat-y;
}
/* 本鸟 */
#bird {
position: absolute;
top: 15px;
left: 50px;
display: none;
-webkit-user-select: none;
-ms-user-select: none;
/* 设置用户不可选中:避免双击选中图片 */
user-select: none;
}
/* 结束样式 */
#game {
position: absolute;
left: 50%;
top: 50%;
transform: scale(2.5) translate(-20%, -120%);
animation: 2s linear mo;
display: none;
}
@keyframes mo {
from {
transform: scale(0) translate(-20%, -120%);
}
to {
transform: scale(2.5) translate(-20%, -120%);
}
}
</style>
<script>
//绑定点击事件开始游戏
document.querySelector("#ck").addEventListener("click", play);
var flyTimer = null; //小鸟飞翔的计时器
var pipeTimer = null; //管道生成的计时器
//飞翔的小鸟本鸟
var bird = document.querySelector("#bird");
//游戏界面高度
var h = document.querySelector("ul").clientHeight;
var bgMusic = document.createElement("audio"); //背景音乐
var djMusic = document.createElement("audio"); //点击背景音乐
var jfMusic = document.createElement("audio"); //加分背景音乐
//开始游戏
function play() {
//隐藏游戏开始界面
document.querySelector(".title").style.display = "none";
document.querySelector(".start").style.display = "none";
//开启计分板
document.querySelector(".jifenban").style.display = "block";
//开启背景音乐
bgMusic.src = "./music/game_music.mp3";
bgMusic.loop = true; //循环播放音乐
bgMusic.play();
bird.style.display = "block"; //显示小鸟本鸟
bird.speed = 0.5; //飞翔的速度
//小鸟飞翔
flyTimer = setInterval(function() {
bird.speed += 0.5;
bird.src = bird.speed > 0 ? "./img/down_bird0.png" : bird.speed < 0 ? "./img/up_bird1.png" : "./img/bird1.png"; //小鸟上下飞的图片
if (bird.offsetTop + bird.speed > 0 && (bird.offsetTop + bird.clientHeight + bird.speed) < h)
//speed为正数向下坠,负数向上飞
bird.style.top = bird.offsetTop + bird.speed + "px";
else if (bird.offsetTop + bird.speed < 0)
bird.style.top = 0;
else if ((bird.offsetTop + bird.clientHeight + bird.speed) > h)
gameover();
}, 30);
document.onclick = function() { //绑定点击事件,让小鸟能向上飞
bird.speed = -5;
}
//空格按键
document.onkeydown = function(e) {
if (e.keyCode = 32) {
bird.speed = -5;
djMusic.src = "./music/bullet.mp3";
djMusic.loop = false; //不循环播放
djMusic.play();
}
}
//生成管道
pipeTimer = setInterval(function() {
//随机管道高度 200:小鸟通过的高度 200:管道的最低高度
var randHeight = Math.floor(Math.random() * (h - 100 - 400 + 1) + 200);
var pipe = document.createElement("li");
pipe.innerHTML = `
<div class="up_pipe" style="height:${randHeight}px"></div>
<div class="down_pipe" style="height:${h-randHeight-100}px"></div>`
document.querySelector("ul").appendChild(pipe);
//每根管道最开始到左边的距离都是浏览器宽度
// pipe.left = document.documentElement.clientWidth;
//管道移动
pipe.timer = setInterval(function() {
// pipe.left -= 2; //每移动一次,管道到左边的距离就-2
// pipe.style.transform = `translateX(${pipe.left}px)`;
pipe.style.left = pipe.offsetLeft - 2 + "px";
if (bird.isDead) {
clearInterval(pipe.timer);
} else {
crash(pipe) //进行碰撞检测
}
}, 15);
}, 3000);
}
function gameover() { //游戏结束
bird.isDead = true; //判断小鸟变量
clearInterval(flyTimer); //小鸟停止飞翔
bird.style.top = h - bird.clientHeight + "px"; //小鸟落到地上
bgMusic.src = "./music/game_over.mp3";
bgMusic.loop = false;
bgMusic.play(); //游戏结束音效
//显示游戏结束界面
over();
//再玩一次
}
var i = 0;
var f = 0;
function crash(pipe) { //碰撞检测
//当管道与左边的距离<小鸟的右边到左边的距离 并且 管道的右边到左边的距离>小鸟到左边的距离时,开始碰撞检测
if (pipe.offsetLeft < (bird.offsetLeft + bird.clientWidth) && (pipe.offsetLeft + pipe.clientWidth) > bird.offsetLeft) {
//小鸟与顶部的距离<上边管道的高度 || 小鸟与底部的距离<下边管道的高度
if (bird.offsetTop < pipe.firstElementChild.clientHeight || (h - bird.offsetTop - bird.clientHeight) < pipe.lastElementChild.clientHeight) {
console.log("你死了~~")
//碰撞到了
gameover();
} else {
i++;
console.log(i)
if (i == 50) {
jfMusic.src = "./music/1.mp3";
jfMusic.loop = false; //不循环播放
jfMusic.play();
f++;
i = 0;
}
}
}
document.querySelector(".fenshu").innerText = f;
}
function over() {
clearInterval(pipeTimer); //结束生成管道
document.querySelector("#game").style.display = "block";
document.querySelector(".start").style.display = "block";
console.log(document.querySelector("#ck"))
document.querySelector("#ck").onclick = function() {
location.reload();
}
}
</script>
@keyframes
1.定义和创建动画
2.语法规则
@keyframes 动画名{ 0%/from{ //动画开始时,元素的样式 } 百分比{ //动画执行到某个时长,元素样式 } .... 100%/to{ //动画结束时,元素的样式 } }
animation
1.简写属性,用来调用动画并设置相关属性
animation: name duration timing-function delay iteration-count direction;
2.animation-name
:调用的动画名称
3.animation-duration
:动画执行的时间
4.animation-timing-function
:动画执行的速度曲线
linear:匀速 ease:慢 - 快 - 慢 ease-in:慢速开始的过渡效果 ease-out:慢速结束的过渡效果 ease-in-out:慢速开始和结束的过渡效果 cubic-bezier(n,n,n,n):贝塞尔曲线 steps(n[,end | start]):阶跃函数,用于把整个操作领域切分为相同大小的间隔,每个间隔都是相等的 n:指定了时间函数中的间隔数量(必须是正整数) 第二个参数是可选的,可设值:start和end,表示在每个间隔的起点或是终点发生阶跃变化,如果忽略,默认是end
5.animation-delay
:动画延迟执行的时间
6.animation-interation-count
:设置动画执行的次数
值:n
:具体播放的次数,默认值为1
infinite
:无限次
7.animation-direction
:是否应该轮流反向播放动画
值:normal
:默认值,动画正常播放
alternate
:动画应该轮流反向播放
8.animation-fill-mode
:规定动画在播放之前或之后,其动画效果是否可见
9.animation-play-state
:规定动画正在运行还是暂停
属性:paused
:规定动画已暂停
running
:规定动画正在播放
1.Element.style
:只能获取或设置内联样式
2.Element.offsetLeft/offsetTop
:获取element
相对于offsetParent
边界偏移位置 -- left/top
3.Element.style.width
:获取或设置元素的width
属性值 -- 带px
4.Element.offsetWidth
:获取元素的实际宽度(width
+padding
+border
+滚动条) -- 只读属性
5.Element.clientWidth
:获取元素的宽度(width
+padding
+滚动条)-- 只读属性