265 lines
7.2 KiB
JavaScript
265 lines
7.2 KiB
JavaScript
class WaterPipeBird {
|
||
|
||
innerWidth = window.innerWidth;
|
||
innerHeight = window.innerHeight;
|
||
|
||
totalScore = 0;
|
||
|
||
// 地板的运动速度
|
||
dibanMotionSpeed = 10;
|
||
|
||
// 鸟的默认皮肤
|
||
birdTheme = "birdDefault"
|
||
|
||
// 游戏状态 true 开始, false 未开始
|
||
gameStatus = false;
|
||
|
||
// 每次点击鸟,鸟的上移动距离
|
||
birdClickTop = 40
|
||
|
||
// 下移距离
|
||
birdClickDown = 10
|
||
|
||
// 创建到第几个水管
|
||
PipeIndex = 0;
|
||
|
||
// 上下水管的通过间隙(距离)
|
||
PipeGap = 150;
|
||
|
||
// 水管左右的间距
|
||
XPipeWidth = 300
|
||
|
||
// 水管移动速度
|
||
PipeSpeed = 10
|
||
|
||
IntervalList = []
|
||
|
||
constructor() {
|
||
console.log("构造函数: ");
|
||
this.dibanMotion()
|
||
this.initBird()
|
||
this.startGame()
|
||
this.stopGame()
|
||
}
|
||
|
||
|
||
dibanMotion() {
|
||
$(".di_one").style.left = `0px`;
|
||
$(".di_two").style.left = `${this.innerWidth}px`;
|
||
|
||
// 定义变量提前保存this
|
||
// =>
|
||
// call bind apply
|
||
// 箭头函数因为没有关键词 function,所以this会被解绑
|
||
setInterval(() => {
|
||
$(".di_one").style.left = `${parseInt(($(".di_one").style.left)) - this.dibanMotionSpeed}px`;
|
||
|
||
$(".di_two").style.left = `${parseInt(($(".di_two").style.left)) - this.dibanMotionSpeed}px`;
|
||
|
||
if (parseInt(($(".di_one").style.left)) <= -this.innerWidth) {
|
||
$(".di_one").style.left = `${this.innerWidth}px`;
|
||
}
|
||
|
||
if (parseInt(($(".di_two").style.left)) <= -this.innerWidth) {
|
||
$(".di_two").style.left = `${this.innerWidth}px`;
|
||
}
|
||
}, 100)
|
||
}
|
||
|
||
|
||
// birdShake 0.4s linear infinite reverse
|
||
initBird() {
|
||
$(".bird").style.top = `${(this.innerHeight - 112) / 2 - 14}px`;
|
||
|
||
// 点击切换小鸟的主题
|
||
_(".bird_list img").forEach((v, i) => {
|
||
v.onclick = () => {
|
||
switch (i) {
|
||
case 0:
|
||
this.birdTheme = "birdDefault"
|
||
$(".bird").style.animationName = "birdDefault,birdShake"
|
||
break;
|
||
case 1:
|
||
this.birdTheme = "birdBlue"
|
||
$(".bird").style.animationName = "birdBlue,birdShake"
|
||
break;
|
||
case 2:
|
||
this.birdTheme = "birdRed"
|
||
$(".bird").style.animationName = "birdRed,birdShake"
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
startGame() {
|
||
e(".start", () => {
|
||
let clickTime = null;
|
||
this.gameStatus = true;
|
||
|
||
$(".pause").show();
|
||
$(".score").show();
|
||
|
||
$(".bird_title").none();
|
||
$(".bird").style.animationName = this.birdTheme
|
||
|
||
// 下落
|
||
this.IntervalList[0] = setInterval(() => {
|
||
if (this.gameStatus) {
|
||
$(".bird").style.top = `${parseInt($(".bird").style.top) + this.birdClickDown}px`
|
||
this.collision($(".bird"), $(".diban"))
|
||
}
|
||
}, 1000 / 16)
|
||
|
||
// 点击开始游戏和控制鸟的上移
|
||
e("body", (e) => {
|
||
if (this.gameStatus) {
|
||
clickTime = new Date().getTime();
|
||
$(".bird").style.top = `${parseInt($(".bird").style.top) - this.birdClickTop}px`
|
||
$(".bird").remove("down")
|
||
$(".bird").add("up")
|
||
}
|
||
})
|
||
|
||
|
||
// 下落的样式
|
||
this.IntervalList[1] = setInterval(() => {
|
||
let currentTime = new Date().getTime();
|
||
if (currentTime - clickTime > 300) {
|
||
$(".bird").remove("up")
|
||
$(".bird").add("down")
|
||
}
|
||
}, 300)
|
||
|
||
|
||
this.IntervalList[2] = setInterval(() => {
|
||
this.CreatedPipe()
|
||
}, 500)
|
||
|
||
|
||
})
|
||
}
|
||
|
||
stopGame() {
|
||
e(".pause", (e) => {
|
||
this.gameStatus = false;
|
||
|
||
e?.stopPropagation();
|
||
this.IntervalList.forEach(v => {
|
||
clearInterval(v)
|
||
})
|
||
_(".pipe").forEach(v => {
|
||
clearInterval(v.IntervalId)
|
||
})
|
||
|
||
$(".bird_list").none()
|
||
$(".start").none()
|
||
$(".bird_title").show()
|
||
$(".restart").show()
|
||
})
|
||
|
||
|
||
e(".restart", (e) => {
|
||
$(".start").onclick()
|
||
this.PipeMove(_(".pipe"))
|
||
})
|
||
|
||
|
||
}
|
||
|
||
|
||
CreatedPipe() {
|
||
let PipeTotalHeight = this.innerHeight - 112 - this.PipeGap;
|
||
let TopImgHeight = getRandom(60, PipeTotalHeight - 60)
|
||
let BottomImgHeight = PipeTotalHeight - TopImgHeight
|
||
|
||
let createdImg = (t) => {
|
||
let img = document.createElement("img")
|
||
img.type = t
|
||
img.src = `./img/sg_${t}.png`
|
||
img.className = "pipe"
|
||
img.style = `
|
||
${t == "b" ? 'bottom: 110px;' : 'top: 0px;'}
|
||
left: ${this.innerWidth + 55 + (this.PipeIndex * this.XPipeWidth)}px;
|
||
height: ${t == "t" ? TopImgHeight : BottomImgHeight}px;
|
||
`;
|
||
return img
|
||
}
|
||
|
||
let topImg = createdImg("t");
|
||
let bottomImg = createdImg("b");
|
||
|
||
$("body").appendChild(topImg)
|
||
$("body").appendChild(bottomImg)
|
||
|
||
|
||
this.PipeMove([topImg, bottomImg])
|
||
// this.PipeMove(bottomImg)
|
||
this.PipeIndex += 1
|
||
}
|
||
|
||
|
||
PipeMove(arr) {
|
||
arr.forEach(img => {
|
||
img.IntervalId = setInterval(() => {
|
||
if (this.gameStatus) {
|
||
img.style.left = `${parseInt(img.style.left) - this.PipeSpeed}px`
|
||
if (parseInt(img.style.left) <= -55) {
|
||
clearInterval(img.IntervalId)
|
||
$("body").removeChild(img)
|
||
} else {
|
||
this.collision($(".bird"), img)
|
||
}
|
||
}
|
||
}, 100)
|
||
})
|
||
|
||
}
|
||
|
||
|
||
|
||
collision(el1, el2) {
|
||
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
|
||
) {
|
||
$(".gameover").show()
|
||
$(".bird_logo").none();
|
||
$(".pause").onclick()
|
||
$(".restart").none();
|
||
|
||
$(".reload").show()
|
||
e(".reload", () => {
|
||
location.reload()
|
||
})
|
||
} else {
|
||
if (el2.type == "t") {
|
||
if (parseInt(el2.style.left) + el2.offsetWidth == 100) {
|
||
this.totalScore += 1
|
||
let sco = this.totalScore.toString().split("")
|
||
$(".score").innerHTML = ""
|
||
sco.forEach(v => {
|
||
$(".score").innerHTML += `<img src="./img/${v}.png" alt="">`
|
||
})
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
// var a = function (test) {
|
||
// console.log("1: ", test);
|
||
// }
|
||
|
||
// var a = test => console.log("1: ", test);
|
||
|
||
|
||
|
||
new WaterPipeBird() |