js實(shí)現(xiàn)跳一跳小游戲
本文實(shí)例為大家分享了js實(shí)現(xiàn)跳一跳小游戲的具體代碼,供大家參考,具體內(nèi)容如下
效果
流程分析
1、鼠標(biāo)按下開(kāi)始蓄力
2、鼠標(biāo)松開(kāi),根據(jù)鼠標(biāo)按下的時(shí)間讓小球運(yùn)動(dòng)相應(yīng)的距離
3、判斷小球落點(diǎn)是否在平臺(tái)內(nèi)
4、如果在平臺(tái)范圍內(nèi),產(chǎn)生下一個(gè)平臺(tái),分?jǐn)?shù)加10.如果不在游戲結(jié)束,判斷分?jǐn)?shù)是否大于歷史最高分,更新歷史最高分。
動(dòng)畫(huà)效果
5、鼠標(biāo)按下小球所在平臺(tái)要有蓄力效果,鼠標(biāo)松開(kāi)后慢慢恢復(fù),
6、小球在空中的運(yùn)動(dòng)曲線要平滑
7、小球和平臺(tái)要有3D效果
注意事項(xiàng)
8、運(yùn)動(dòng)涉及到計(jì)算器和延時(shí)器,要注意清除定時(shí)器以免擾亂動(dòng)畫(huà)效果
9、鼠標(biāo)按下和松開(kāi)為一個(gè)完整的流程,在小球運(yùn)動(dòng)完之前不能重復(fù)觸發(fā)
10、確保小球運(yùn)動(dòng)的時(shí)間與鼠標(biāo)按下的時(shí)間相關(guān)聯(lián)
布局
<div class="wrap"> <h3 class="tit">鼠標(biāo)按下蓄力,松開(kāi)鼠標(biāo)小球開(kāi)始運(yùn)動(dòng)</h3> <h1>分?jǐn)?shù):</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; /*左邊的沒(méi)有背景色,右邊的加了背景色*/ 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) { //產(chǎn)生[min,max]范圍內(nèi)的整數(shù) return Math.round(Math.random() * (max - min)) + min; } function randomColor() { //產(chǎn)生隨機(jī)的顏色 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; //記錄鼠標(biāo)按下的時(shí)間 var timer2 = null; //小球平拋運(yùn)動(dòng)定時(shí)器 var timer3 = null; //鼠標(biāo)按下變形定時(shí)器 var num = 0; //游戲成績(jī) var mouseD = false; //記錄鼠標(biāo)是否按下 var mouseUp = true; //記錄鼠標(biāo)是否松開(kāi) var h1 = document.querySelector('h1'); var h2 = document.querySelector('h2'); var max = localStorage.getItem('max'); var div = document.createElement('div'); //創(chuàng)建下一個(gè)平臺(tái) h2.innerText = '歷史最高:' + localStorage.getItem('max'); //從瀏覽器數(shù)據(jù)庫(kù)獲取最高分 div.style.left = 35 + randomInt(30, 60) + 'px'; //初始化平臺(tái)距離左邊的值 var div_sex = randomInt(30, 70); //初始化平臺(tái)大小,范圍 div.style.bottom = 40 - div_sex / 2 + 'px'; //平臺(tái)距離底部為小球底部減去平臺(tái) div.style.height = div_sex + 'px'; div.style.width = div_sex + 'px'; div.className = 'blc1'; //添加初始化樣式 div.style.backgroundColor = randomColor(); //隨機(jī)顏色 wrap.appendChild(div); //存入平臺(tái) document.onmousedown = function () { //監(jiān)聽(tīng)頁(yè)面點(diǎn)擊事件 if (!mouseD) { //如果鼠標(biāo)按下沒(méi)有抬起 var blc = document.querySelectorAll('.blc1'); //獲取所有平臺(tái) oldtime = Date.now(); //記錄鼠標(biāo)按下的時(shí)間 var target = blc[blc.length - 2]; //小球所在的平臺(tái) var down_c = 10; //平臺(tái)最大下沉距離 var left = target.offsetLeft; //記錄鼠標(biāo)按下后下沉效果之前平臺(tái)的left值 var bottom = 40 - target.offsetHeight / 2; //記錄鼠標(biāo)按下后下沉效果之前平臺(tái)的bottom值 var con_l = con.offsetLeft; //記錄鼠標(biāo)按下后下沉效果之前小球的left值 var con_b = 30; //記錄鼠標(biāo)按下后下沉效果之前小球的bottom值 timer3 = setInterval(() => { //下沉效果定時(shí)器 down_c -= 0.03; //每一次變化0.03px if (down_c <= 0) { //最小值為0 down_c = 0.03; } target.style.boxShadow = down_c + 'px ' + down_c + 'px ' + down_c + 'px #000'; //邊框陰影向里縮,實(shí)現(xiàn)3D效果 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'; //小球和平臺(tái)一起向右下角移動(dòng),配合陰影達(dá)到3D效果 }, 1); mouseD = true; //鼠標(biāo)已經(jīng)按下 mouseUp = false; //鼠標(biāo)即將松開(kāi) } } document.onmouseup = function () { if (!mouseUp) { //如果沒(méi)有觸發(fā)mousedown事件不會(huì)執(zhí)行以下代碼 mouseUp = true; //鎖定事件,小球運(yùn)動(dòng)結(jié)束前不能執(zhí)行以下代碼 clearInterval(timer3); //清除下沉動(dòng)畫(huà) var timer4 = null; //上升動(dòng)畫(huà) var blc = document.querySelectorAll('.blc1'); //獲取所有平臺(tái) var target = blc[blc.length - 2]; //同下沉動(dòng)畫(huà) var left = target.offsetLeft; var down_time = 0; var down_c = 0; var click_time = Date.now() - oldtime; //鼠標(biāo)按下的時(shí)間 var bottom = 40 - target.offsetHeight / 2 - (click_time * 0.03 > 10 ? 10 : click_time * 0.03); //原來(lái)的bottom-下沉的距離,最大為10 timer4 = setInterval(() => { //恢復(fù)原來(lái)的狀態(tài) 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; //小球運(yùn)動(dòng)時(shí)間為鼠標(biāo)按下的1.5倍,減少蓄力時(shí)間 var time2 = 0; //小球跳一跳計(jì)時(shí)器 var y = 30; //小球初始bottom值 var x = con.offsetLeft; //小球初始left值 clearTimeout(tout); //清除延時(shí)器 timer2 = setInterval(() => { //小球彈跳計(jì)時(shí)器 time2 += 20; y = 30 + clicktime / 50 * Math.sin(time2 * Math.PI / clicktime); //將總的時(shí)間分成180份通過(guò)sin(0,180)從0到0的特性完成一個(gè)圓滑的拋物線 con.style.left = x + time2 / 20 + 'px'; con.style.bottom = y + 'px'; }, 20); var tout = setTimeout(function () { //控制小球運(yùn)動(dòng)的時(shí)間與鼠標(biāo)按下的時(shí)間*1.5相等,控制小球運(yùn)動(dòng)的時(shí)間 clearInterval(timer2); //結(jié)束小球運(yùn)動(dòng) x = con.offsetLeft; //獲取運(yùn)動(dòng)結(jié)束后小球的left值 var blc = document.querySelectorAll('.blc1'); //獲取所有的平臺(tái) if (con.offsetLeft >= wrap.lastElementChild.offsetLeft && con.offsetLeft <= wrap .lastElementChild.offsetLeft + wrap.lastElementChild.offsetHeight - 10 ) { //判斷小球是否位于平臺(tái)里面 num += 10; //每跳一次加10分 h1.innerText = '分?jǐn)?shù):' + num; //動(dòng)態(tài)展示分?jǐn)?shù) //生成下一個(gè)平臺(tái) 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('游戲結(jié)束,分?jǐn)?shù):' + num); max = max > num ? max : num; localStorage.setItem('max', max) //更新最高分 location.reload(); //刷新當(dāng)前頁(yè)面 } wrap.scrollLeft = wrap.scrollWidth; //控制滾動(dòng)條位于最右邊 mouseD = false; //完成一次事件,重新開(kāi)啟 mouseUp = true; // }, clicktime) } }
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
前后端常見(jiàn)的幾種鑒權(quán)方式(小結(jié))
這篇文章主要介紹了前后端常見(jiàn)的幾種鑒權(quán)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08JavaScript中的console.group()函數(shù)詳細(xì)介紹
這篇文章主要介紹了JavaScript中的console.group()函數(shù)詳細(xì)介紹,當(dāng)程序調(diào)試日志過(guò)多時(shí)會(huì)有些雜亂,此時(shí)可以使用console.group()函數(shù)調(diào)來(lái)分組顯示,需要的朋友可以參考下2014-12-12JavaScript整除運(yùn)算函數(shù)ceil和floor的區(qū)別分析
這篇文章主要介紹了JavaScript整除運(yùn)算函數(shù)ceil和floor的區(qū)別分析,實(shí)例分析了ceil和floor函數(shù)的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04js動(dòng)態(tài)創(chuàng)建表格,刪除行列的小例子
這篇文章介紹了js動(dòng)態(tài)創(chuàng)建表格,刪除行列的實(shí)例代碼,有需要的朋友可以參考一下2013-07-07TypeScript之調(diào)用棧的實(shí)現(xiàn)
這篇文章主要介紹了TypeScript之調(diào)用棧的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12