js 跳一跳小游戏
效果
流程分析
- 鼠标按下开始蓄力
- 鼠标松开,根据鼠标按下的时间让小球运动相应的距离
- 判断小球落点是否在平台内
- 如果在平台范围内,产生下一个平台,分数加10.如果不在游戏结束,判断分数是否大于历史最高分,更新历史最高分。
动画效果
- 鼠标按下小球所在平台要有蓄力效果,鼠标松开后慢慢恢复,
- 小球在空中的运动曲线要平滑
- 小球和平台要有3D效果
注意事项
- 运动涉及到计算器和延时器,要注意清除定时器以免扰乱动画效果
- 鼠标按下和松开为一个完整的流程,在小球运动完之前不能重复触发
- 确保小球运动的时间与鼠标按下的时间相关联
布局
<div class="wrap">
<h3 class="tit">鼠标按下蓄力,松开鼠标小球开始运动h3>
<h1>分数:h1>
<h2>历史最高:h2>
<div class="con">div>
<div class="blc1">div>
div>
样式
* {
margin: 0;
padding: 0;
}
.wrap {
height: 500px;
position: relative;
overflow: hidden;
}
.con {
background-color: hotpink;
background-image: radial-gradient(10px at 4px 4px,
rgba(0, 0, 0, 0),
rgba(2, 2, 2, 1));
width: 20px;
height: 20px;
border-radius: 50%;
position: absolute;
left: 30px;
bottom: 30px;
z-index: 2;
}
.blc1 {
box-shadow: 10px 10px 7px #000;
border-radius: 30%;
width: 40px;
height: 40px;
background-color: midnightblue;
position: absolute;
left: 20px;
bottom: 20px;
}
.tit {
text-align: center;
}
js
function randomInt(min, max) {
return Math.round(Math.random() * (max - min)) + min;
}
function randomColor() {
var map = [1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'];
var str = '#';
for (var i = 0; i < 6; i++) {
var index = randomInt(0, 15);
str += map[index];
}
return str;
}
var wrap = document.querySelector('.wrap');
var con = document.querySelector('.con');
var oldtime = 0;
var timer2 = null;
var timer3 = null;
var num = 0;
var mouseD = false;
var mouseUp = true;
var h1 = document.querySelector('h1');
var h2 = document.querySelector('h2');
var max = localStorage.getItem('max');
var div = document.createElement('div');
h2.innerText = '历史最高:' + localStorage.getItem('max');
div.style.left = 35 + randomInt(30, 60) + 'px';
var div_sex = randomInt(30, 70);
div.style.bottom = 40 - div_sex / 2 + 'px';
div.style.height = div_sex + 'px';
div.style.width = div_sex + 'px';
div.className = 'blc1';
div.style.backgroundColor = randomColor();
wrap.appendChild(div);
document.onmousedown = function () {
if (!mouseD) {
var blc = document.querySelectorAll('.blc1');
oldtime = Date.now();
var target = blc[blc.length - 2];
var down_c = 10;
var left = target.offsetLeft;
var bottom = 40 - target.offsetHeight / 2;
var con_l = con.offsetLeft;
var con_b = 30;
timer3 = setInterval(() => {
down_c -= 0.03;
if (down_c <= 0) {
down_c = 0.03;
}
target.style.boxShadow = down_c + 'px ' + down_c + 'px ' + down_c +
'px #000';
target.style.left = left + 10 - down_c + 'px';
target.style.bottom = bottom + -10 + down_c + 'px';
con.style.left = con_l + 10 - down_c + 'px';
con.style.bottom = con_b - 10 + down_c + 'px';
}, 1);
mouseD = true;
mouseUp = false;
}
}
document.onmouseup = function () {
if (!mouseUp) {
mouseUp = true;
clearInterval(timer3);
var timer4 = null;
var blc = document.querySelectorAll('.blc1');
var target = blc[blc.length - 2];
var left = target.offsetLeft;
var down_time = 0;
var down_c = 0;
var click_time = Date.now() - oldtime;
var bottom = 40 - target.offsetHeight / 2 - (click_time * 0.03 > 10 ? 10 : click_time *
0.03);
timer4 = setInterval(() => {
down_time++;
if (down_time > click_time) {
clearInterval(timer4);
}
down_c += 0.03;
if (down_c >= 10) {
down_c = 10;
}
target.style.boxShadow = down_c + 'px ' + down_c + 'px ' + down_c + 'px #000';
target.style.left = left - down_c + 'px';
target.style.bottom = bottom + down_c + 'px';
}, 1);
var clicktime = (Date.now() - oldtime) * 1.5;
var time2 = 0;
var y = 30;
var x = con.offsetLeft;
clearTimeout(tout);
timer2 = setInterval(() => {
time2 += 20;
y = 30 + clicktime / 50 * Math.sin(time2 * Math.PI /
clicktime);
con.style.left = x + time2 / 20 + 'px';
con.style.bottom = y + 'px';
}, 20);
var tout = setTimeout(function () {
clearInterval(timer2);
x = con.offsetLeft;
var blc = document.querySelectorAll('.blc1');
if (con.offsetLeft >= wrap.lastElementChild.offsetLeft && con.offsetLeft <= wrap
.lastElementChild.offsetLeft + wrap.lastElementChild.offsetHeight - 10
) {
num += 10;
h1.innerText = '分数:' + num;
var div_sex2 = randomInt(40, 60);
var newdiv = document.createElement('div');
newdiv.style.bottom = 40 - div_sex2 / 2 + 'px';
newdiv.style.height = div_sex2 + 'px';
newdiv.style.width = div_sex2 + 'px';
newdiv.style.left = x + randomInt(80, 120) + 'px';
newdiv.style.backgroundColor = randomColor();
newdiv.className = 'blc1';
wrap.appendChild(newdiv);
} else {
alert('游戏结束,分数:' + num);
max = max > num ? max : num;
localStorage.setItem('max', max)
location.reload();
}
wrap.scrollLeft = wrap.scrollWidth;
mouseD = false;
mouseUp = true;
}, clicktime)
}
}