持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
国庆假期余额不足50%,更文也来到第五天,绞尽了脑汁,咬破了笔头,不知道该水,阿不是,写点什么内容,上午出门做核酸的时候看到前面排队的小朋友在玩儿cosplay,一个扮演奥特曼,一个扮演黑猫警长,两个人在玩儿吃饭睡觉打豆豆的游戏,于是灵机一动,回来写了一篇,海底掘金背景的打豆豆【嗐,不要怪我标题党,其实就是打字消除~】
游戏玩法
游戏倒计时60秒,点击屏幕上的开始游戏后,倒计时开始,一次性会出现7个带有字符的豆豆,玩家需要正确敲击豆豆上对应的字母进行消除,消除一个记1分,如果乱敲不存在的字母则扣除1生命值,倒计时结束或生命值清零,游戏结束。
游戏实现
- 背景 背景很简单,宽度500 高度100%居中的div即可,背景图采用海底掘金的背景图
<div class="bg">
</div>
.bg{
width: 500px;
height: 100%;
margin: 0 auto;
background: #2a5fbd;
position: relative;
}
- 计分板 计分板主要记录倒计时、生命值、得分,绝对定位在屏幕顶部居中即可,倒计时,生命值、得分、都是变量
<div class="score"></div>
.score{
width: 500px;
height: 40px;
margin: 0 auto;
color: #fff;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
z-index: 2;
}
let score = 0
let time = 60
let hp = 3
$('.score').html(`倒计时: ${time} 秒, 生命值: ${hp} 得分: ${score}`)
- 开始游戏按钮 开始游戏按钮需要完成开始游戏与重新开始两项功能,因与游戏核心实现重合,在下面讲实现,这里仅仅讲样式的实现,样式采用了透明背景+内阴影的方式实现,模拟卡通按钮效果
<div class="btn">开始游戏</div>
.btn{
width: 120px;
height: 40px;
background: transparent;
box-shadow: inset 0 0 15px 3px #fff;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
color: #fff;
font-size: 16px;
line-height: 40px;
text-align: center;
cursor: pointer;
border-radius: 8px;
}
- 豆豆的实现,豆豆采用随机的方式进行生成,为了避免重复,通过KEY_MAP变量来记录是否重复,并绑定对应的jquery对象,方便进行操作,这里采用的原理是chatCode与String.fromCharCode , 通过随机生成ascii码来对应不同的字母,ascii码65是A,26个字母,所以区间就是
Math.floor(Math.random() * 26) + 65,通过对document添加点击事件,判断事件对象的key是否存在于KEY_MAP内,存在则加分并消除生成新的字符,不存在则扣除生命值。
// 随机字符算法
function randomLetter () {
let div = $('<div>')
let randomNum, randomLetter;
do {
randomNum=Math.floor(Math.random() * 26) + 65;
randomLetter=String.fromCharCode(randomNum);
} while (KEY_MAP[randomLetter]);
div.html(randomLetter);
KEY_MAP[randomLetter]=div;
div.addClass('pao')
$('.bg').prepend(div)
}
// 初始化
function init () {
document.onkeydown = null
if(t) {
clearInterval(t)
t = null
}
time = 60
score = 0
KEY_MAP = {}
$('.bg').empty()
$('.score').html(`倒计时: ${time} 秒, 生命值: ${hp}得分: ${score}`)
}
// 按钮的play方法
function play () {
init()
document.onkeydown=function (e) {
let key=e.key.toUpperCase();
if (KEY_MAP[key]) {
score++
// 添加命中样式,延迟500毫秒消除
KEY_MAP[key].addClass('shine')
let tt = setTimeout(function () {
clearTimeout(tt)
KEY_MAP[key].remove()
delete KEY_MAP[key]
randomLetter()
}, 500)
} else {
hp--
if (hp <=0) {
document.onkeydown = null
clearInterval(t)
t = null
KEY_MAP = {}
$('.bg').empty()
$('.btn').show()
$('.score').html(`倒计时截止, 游戏结束, 生命值: ${hp} 得分: ${score}`)
}
}
}
$('.btn').hide()
for (let i=0;i<7;i++) {
randomLetter()
}
t = setInterval(function () {
if (time<=0) {
document.onkeydown = null
clearInterval(t)
t = null
KEY_MAP = {}
$('.bg').empty()
$('.btn').show()
$('.score').html(`倒计时截止, 游戏结束, 生命值: ${hp} 得分: ${score}`)
return false
}
time--
$('.score').html(`倒计时: ${time} 秒, 生命值: ${hp} 得分: ${score}`)
}, 1000)
}
$('.btn').click(play)