499 lines
15 KiB
JavaScript
499 lines
15 KiB
JavaScript
class bird {
|
||
// 游戏的默认状态 false 未开始 true 开始游戏
|
||
gameStatus = false;
|
||
innerHeight = window.innerHeight;
|
||
innerWidth = window.innerWidth;
|
||
|
||
// 总定义所有变量赋值为0
|
||
// 鸟的下落速度
|
||
birdDownSpeed = 0;
|
||
|
||
// 鸟的上升速度
|
||
birdUpSpeed = 0;
|
||
|
||
// 地板的移动速度
|
||
groundSpeed = 0;
|
||
|
||
// 上下水管的间隙
|
||
WaterPipeClearance = 0
|
||
|
||
// 水管的左右间隙
|
||
WaterPipeLeftRightClearance = 0
|
||
|
||
// 生成水管的X轴位置
|
||
WaterPipeX = 0
|
||
|
||
// 一秒创建多少个水管
|
||
createdWaterPipeXTime = 0
|
||
|
||
|
||
// 自己创建的
|
||
|
||
//选择小鸟颜色
|
||
birdColor = 'yellowMotion'
|
||
|
||
|
||
//分数统计
|
||
TotalScore = 9
|
||
|
||
play = true
|
||
wait = false
|
||
birdDown = null
|
||
backgroundmusic = false
|
||
|
||
|
||
constructor() {
|
||
this.easySpeed();
|
||
this.birdTheme()
|
||
this.bindEvent();
|
||
this.birdAction();
|
||
this.groundAction();
|
||
this.resultAction();
|
||
|
||
$('.speed').onchange = (e) => {
|
||
// console.log('asd', $('.speed').value);
|
||
if ($('.speed').value == 1) {
|
||
this.easySpeed()
|
||
} else {
|
||
this.difficultSpeed()
|
||
}
|
||
}
|
||
|
||
setInterval(() => {
|
||
if (this.gameStatus) {
|
||
this.createdWaterPipe();
|
||
}
|
||
}, this.createdWaterPipeXTime)
|
||
}
|
||
|
||
|
||
// easy模式变量赋值如下
|
||
easySpeed() {
|
||
// 鸟的下落速度
|
||
this.birdDownSpeed = 8;
|
||
|
||
// 鸟的上升速度
|
||
this.birdUpSpeed = 40;
|
||
|
||
// 地板的移动速度
|
||
this.groundSpeed = 5;
|
||
|
||
// 上下水管的间隙
|
||
this.WaterPipeClearance = 200
|
||
|
||
// 水管的左右间隙
|
||
this.WaterPipeLeftRightClearance = 300
|
||
|
||
// 生成水管的X轴位置
|
||
this.WaterPipeX = 0
|
||
|
||
// 一秒创建多少个水管
|
||
this.createdWaterPipeXTime = 500
|
||
}
|
||
|
||
|
||
// easy模式变量赋值如下
|
||
difficultSpeed() {
|
||
// 鸟的下落速度
|
||
this.birdDownSpeed = 12;
|
||
|
||
// 鸟的上升速度
|
||
this.birdUpSpeed = 50;
|
||
|
||
// 地板的移动速度
|
||
this.groundSpeed = 10;
|
||
|
||
// 上下水管的间隙
|
||
this.WaterPipeClearance = 150
|
||
|
||
// 水管的左右间隙
|
||
this.WaterPipeLeftRightClearance = 200
|
||
|
||
// 生成水管的X轴位置
|
||
this.WaterPipeX = 0
|
||
|
||
// 一秒创建多少个水管
|
||
this.createdWaterPipeXTime = 250
|
||
}
|
||
|
||
// 给鸟换主题色
|
||
birdTheme() {
|
||
// 先循环每一项得到每一项
|
||
$('.birdTheme .bird').forEach((value, index) => {
|
||
// console.log('11111', $('.birdTheme .bird'));
|
||
var that = this
|
||
// 为每一项绑定点击事件
|
||
value.onclick = function (e) {
|
||
// $('.birdTheme .bird').forEach(function (v, i) {
|
||
|
||
// if (v.className.indexOf('show')) {
|
||
// v.remove('show')
|
||
// }
|
||
// })
|
||
//先去除block
|
||
value.remove('show')
|
||
//再给点击到的每一项加block
|
||
|
||
|
||
// switch 语句用于基于不同的条件来执行不同的动作。
|
||
// 表达式的值会与结构中的每个 case 的值做比较。如果存在匹配,则与该 case 关联的代码块会被执行。
|
||
|
||
switch (index) {
|
||
case 0:
|
||
that.birdColor = 'redMotion'
|
||
break;
|
||
case 1:
|
||
that.birdColor = 'blueMotion'
|
||
break;
|
||
default:
|
||
that.birdColor = 'yellowMotion'
|
||
break;
|
||
}
|
||
$('.birdTheme .bird')[index + 1 == $('.birdTheme .bird').length ? 0 : index + 1].add('show')
|
||
// 定义一个变量保存修改后的鸟
|
||
var bg = $('.birdTheme .bird')[index + 1 == $('.birdTheme .bird').length ? 0 : index + 1]
|
||
// 获取它的图片地址,并加入startBird
|
||
$('.startBird').style.background = getComputedStyle(bg).background
|
||
// 修改startBird的动画属性
|
||
$('.startBird').style.animation = `${that.birdColor} 0.4s linear infinite,birdShake 0.4s linear infinite`
|
||
|
||
}
|
||
|
||
});
|
||
}
|
||
|
||
// 绑定事件开始和暂停的切换
|
||
bindEvent() {
|
||
click(".play", () => {
|
||
this.readyGO()
|
||
console.log('this.birdColor', this.birdColor);
|
||
|
||
})
|
||
|
||
click(".pause", () => {
|
||
this.changeGameStatus()
|
||
// 暂停的时候清理掉定时器
|
||
if ($('.sg')) {
|
||
$(".sg").forEach(v => clearInterval(v.time))
|
||
}
|
||
// 当暂停的时候清楚鸟下降的定时器
|
||
clearInterval(this.birdDown)
|
||
})
|
||
}
|
||
|
||
|
||
changeGameStatus() {
|
||
if (this.wait) return;
|
||
if (this.gameStatus) {
|
||
$(".backgroundmusic").pause()
|
||
$(".start").remove("hidden")
|
||
$(".pause").add("hidden")
|
||
$('.ready').add('hidden')
|
||
this.gameStatus = false
|
||
} else {
|
||
$(".backgroundmusic").play()
|
||
this.gameStatus = true
|
||
}
|
||
}
|
||
|
||
// 三秒倒计时以后游戏开始
|
||
readyGO() {
|
||
$(".start").add("hidden")
|
||
$(".pause").remove("hidden")
|
||
$('.birdTheme').add("hidden")
|
||
$('.choice').add('hidden')
|
||
$('.ready').remove('hidden')
|
||
$('.startBird').remove('hidden')
|
||
$('.result').remove('hidden')
|
||
|
||
this.wait = true
|
||
var num = 3
|
||
// 将this保存在that里面
|
||
var that = this
|
||
// 倒计时三秒,游戏开始,鸟往下落
|
||
function createNum() {
|
||
// 判断游戏是开始还是继续
|
||
var words = `${num}秒后游戏${that.play ? '开始' : '继续'}`
|
||
// 将倒计时文字放在html上
|
||
$('.readynum').innerText = words
|
||
// 当倒计时为0的时候,
|
||
if (num == 0) {
|
||
//去掉文字和倒计时定时器,
|
||
$('.readynum').innerText = ''
|
||
clearInterval(time)
|
||
$('.ready').add('hidden')
|
||
// 定时器:控制鸟下落
|
||
that.birdDown = setInterval(() => {
|
||
if (that.gameStatus) {
|
||
that.BumpGround("1")
|
||
$(".startBird").style.top = `${parseInt($(".startBird").style.top) + that.birdDownSpeed}px`;
|
||
}
|
||
}, 1000 / 16)
|
||
|
||
|
||
if (that.play) {
|
||
that.play = !that.play
|
||
}
|
||
// 游戏继续
|
||
that.wait = false
|
||
$('.startBird').style.animation = `${that.birdColor} 0.4s linear infinite`
|
||
|
||
//改变游戏状态为true
|
||
that.changeGameStatus()
|
||
// 游戏开始以后水管也开始生成
|
||
var PipeXTime = setInterval(() => {
|
||
if (that.gameStatus) {
|
||
that.createdWaterPipe();
|
||
} else {
|
||
clearInterval(PipeXTime)
|
||
}
|
||
}, that.createdWaterPipeXTime)
|
||
|
||
// 游戏开始以后水管继续移动
|
||
console.log(' $(".sg")', $(".sg"));
|
||
if ($('.sg')) {
|
||
$(".sg").forEach(v => {
|
||
that.WaterPipeMove(v)
|
||
})
|
||
}
|
||
}
|
||
}
|
||
// 三秒定时器
|
||
createNum()
|
||
var time = setInterval(() => {
|
||
num--
|
||
createNum()
|
||
}, 1000)
|
||
|
||
}
|
||
|
||
|
||
// 小鸟运动
|
||
birdAction() {
|
||
// 上一次点击 //下一次点击
|
||
var clcikTime = 0, currentTime = 0;
|
||
// 定义鸟的初始位置
|
||
$('.startBird').style.top = `${this.innerHeight / 2 - 12}px`
|
||
|
||
//给body绑定点击事件,点击屏幕鸟上升
|
||
click("body", () => {
|
||
if (this.gameStatus) {
|
||
|
||
this.BumpGround("2")
|
||
// (new Date()).getTime()时间戳获取鼠标的点击时间
|
||
clcikTime = (new Date()).getTime()
|
||
// 抬头
|
||
$(".startBird").add("up")
|
||
$(".startBird").remove("down")
|
||
// top距离
|
||
$(".startBird").style.top = `${parseInt($(".startBird").style.top) - this.birdUpSpeed}px`
|
||
}
|
||
})
|
||
|
||
// 下降的时候延迟300毫秒在执行
|
||
setInterval(() => {
|
||
|
||
if (this.gameStatus) {
|
||
// 下一次点击
|
||
currentTime = (new Date()).getTime();
|
||
// 当间距超过600的时候是下落状态,低头
|
||
if (currentTime - clcikTime > 200) {
|
||
$(".startBird").add("down")
|
||
$(".startBird").remove("up")
|
||
}
|
||
}
|
||
}, 300)
|
||
|
||
}
|
||
|
||
// 地板的运动
|
||
groundAction() {
|
||
// 定义两个地板的初始位置
|
||
$(".groundOne").style.left = '0px';
|
||
$(".groundTwo").style.left = `${this.innerWidth}px`;
|
||
|
||
setInterval(() => {
|
||
$(".groundOne").style.left = `${parseInt($(".groundOne").style.left) - this.groundSpeed}px`
|
||
$(".groundTwo").style.left = `${parseInt($(".groundTwo").style.left) - this.groundSpeed}px`
|
||
|
||
|
||
if (parseInt($(".groundOne").style.left) <= -this.innerWidth) {
|
||
$(".groundOne").style.left = `${this.innerWidth}px`
|
||
}
|
||
|
||
if (parseInt($(".groundTwo").style.left) <= -this.innerWidth) {
|
||
$(".groundTwo").style.left = `${this.innerWidth}px`
|
||
}
|
||
}, 1000 / 16)
|
||
}
|
||
|
||
// 创建水管
|
||
createdWaterPipe() {
|
||
//水管可占总高度
|
||
var totalWaterPipeHeight = this.innerHeight - 112 - this.WaterPipeClearance;
|
||
//1/3<=上水管高度<2/3
|
||
var TopWaterPipeHeight = (Math.random() * ((totalWaterPipeHeight * 2 / 3) - (totalWaterPipeHeight * 1 / 3))) + (totalWaterPipeHeight * 1 / 3)
|
||
// 下水管高度
|
||
var BottomWaterPipe = totalWaterPipeHeight - TopWaterPipeHeight;
|
||
|
||
// 判断生成位置
|
||
// 初始值为0时,在屏幕的外面
|
||
if (this.WaterPipeX == 0) {
|
||
this.WaterPipeX = this.innerWidth
|
||
} else {
|
||
// 加等于间隔
|
||
this.WaterPipeX += this.WaterPipeLeftRightClearance
|
||
}
|
||
|
||
var creatImg = (call) => {
|
||
var img = document.createElement('img')
|
||
//因为是放在html上的所以引入地址按的是html上的./
|
||
img.src = `./img/${call == 'top' ? 'sg_t' : 'sg_b'}.png`;
|
||
img.className = "sg"
|
||
|
||
|
||
img.style = `
|
||
${call}: ${call == 'top' ? 0 : 112}px;
|
||
height: ${call == 'top' ? TopWaterPipeHeight : BottomWaterPipe}px;
|
||
left: ${this.WaterPipeX}px
|
||
`;
|
||
|
||
return img
|
||
|
||
}
|
||
|
||
|
||
// ‘先赚钱在用钱’先写方法再var
|
||
var TopWaterPipe = creatImg('top')
|
||
var BottomWaterPipe = creatImg('bottom')
|
||
|
||
// 在body上添加子元素
|
||
$('body').appendChild(TopWaterPipe)
|
||
$('body').appendChild(BottomWaterPipe)
|
||
|
||
this.WaterPipeMove(TopWaterPipe)
|
||
this.WaterPipeMove(BottomWaterPipe)
|
||
}
|
||
|
||
// 水管运动
|
||
WaterPipeMove(img) {
|
||
|
||
var that = this
|
||
// img.time保存定时返回number值以便清理定时器
|
||
img.time = setInterval(() => {
|
||
|
||
// 管子运动速度
|
||
img.style.left = `${parseInt(img.style.left) - this.groundSpeed}px`
|
||
|
||
// 当水管自身宽度超出屏幕时清理定时器和元素
|
||
if (parseInt(img.style.left) <= -55) {
|
||
clearInterval(img.time)
|
||
console.log(img);
|
||
$("body").removeChild(img)
|
||
} else {
|
||
that.collision($(".startBird"), img)
|
||
}
|
||
|
||
}, 1000 / 30)
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
/**
|
||
* 碰撞检测
|
||
* @param {*} el1 鸟
|
||
* @param {*} el2 水管
|
||
*/
|
||
// 矩形和矩形的碰撞检测公式,修改参数就行
|
||
collision(el1, el2) {
|
||
// var that = this
|
||
if (el1.offsetLeft < el2.offsetLeft + el2.offsetWidth &&
|
||
el1.offsetLeft + el1.offsetWidth > el2.offsetLeft &&
|
||
el1.offsetTop < el2.offsetTop + el2.offsetHeight &&
|
||
el1.offsetHeight + el1.offsetTop > el2.offsetTop
|
||
) {
|
||
console.log('碰撞成功')
|
||
this.gameOver();
|
||
} else {
|
||
// 如果水管的右边刚好等于鸟的左边距,就说明过关成功,分数加1
|
||
// console.log('el2.offsetLeft + el2.offsetWidth',el2.offsetLeft + el2.offsetWidth);
|
||
|
||
// easy判断只是106,difficult判断是101
|
||
if ((el2.offsetLeft + el2.offsetWidth) == ($('.speed').value == 1 ? 106: 101)) {
|
||
this.TotalScore += 0.5
|
||
// 用String将(this.TotalScore)转化为字符串,判断它是否有小数
|
||
//取反即不包含小数四舍五入
|
||
if (!String(this.TotalScore).includes(".")) {
|
||
console.log("==========分数=======: ", this.TotalScore);
|
||
$(".point").play()
|
||
this.resultAction()
|
||
|
||
// 将分数除10取整,取到前面的数值判断奇偶
|
||
var nums = parseInt(this.TotalScore / 10)
|
||
// 等于0的时候拦截
|
||
if(nums == 0) return;
|
||
// 余数等于0的时候时,为偶数 白天
|
||
if(nums % 2 == 0){
|
||
$('body').style.backgroundImage = `url('./img/back.png')`
|
||
// console.log('123',$('body').background);
|
||
}else{
|
||
// 奇数的时候,黑夜
|
||
$('body').style.backgroundImage = `url('./img/dark.png')`
|
||
// console.log('123',$('body').background);
|
||
}
|
||
console.log('nums',nums);
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
// 得分运动,将得分数组转为字符串,字符串分割得到里面的具体数值,通过foreach循环给html添加分数图片
|
||
resultAction(){
|
||
var scoreArray = String(this.TotalScore).split('')
|
||
$('.result').innerHTML = ''
|
||
scoreArray.forEach(v => {
|
||
$('.result').innerHTML += `<img src="./img/${v}.png" alt="">`
|
||
})
|
||
}
|
||
|
||
// 鸟撞地板的运动,分为两种情况,垂直下落1和不小心碰到2
|
||
BumpGround(type) {
|
||
// 判断鸟的top距离是否和地板y值的top重合或大于它
|
||
var GroundYStart = this.innerHeight - 112;
|
||
if (type = 1) {
|
||
GroundYStart -= 34
|
||
}
|
||
|
||
var birdBTop = $(".startBird").offsetTop + $(".startBird").offsetHeight;
|
||
|
||
if (birdBTop >= GroundYStart) {
|
||
console.log("碰到地板了");
|
||
this.gameOver();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// 游戏结束
|
||
gameOver() {
|
||
$(".hit").play()
|
||
|
||
//改变游戏状态,清除水管定时器
|
||
this.changeGameStatus()
|
||
$(".sg").forEach(v => clearInterval(v.time))
|
||
|
||
//游戏结束,创建结束图片获取地址代替开始的图片
|
||
var gameOver = document.createElement("img")
|
||
gameOver.src = "./img/gameover.png"
|
||
|
||
$(".start").replaceChild(gameOver, $(".logo"))
|
||
//给play绑定另一个点击事件:刷新页面
|
||
click(".play", () => location.reload())
|
||
}
|
||
|
||
}
|
||
new bird() |