JS實現(xiàn)躲避粒子小游戲
本文實例為大家分享了JS實現(xiàn)躲避粒子小游戲的具體代碼,供大家參考,具體內(nèi)容如下
小項目的實戰(zhàn)操作可以幫助我們更好的掌握javascript
躲避例子游戲規(guī)則:拖拽紅球躲避綠球碰撞,拖拽過程不能觸碰容器內(nèi)壁,以贏得游戲持久度
頁面效果:
實現(xiàn)過程
不積小流,無以成江海。
將頁面效果的實現(xiàn)細分成小步實現(xiàn):頁面結(jié)構(gòu)的構(gòu)建,樣式修飾,js中小綠球在容器頂部隨機位置生成、小綠球非水平非垂直方向的運動、小綠球碰撞容器內(nèi)壁后彈性運動、生成多個小綠球、拖拽紅球、紅球的邊界判斷、紅球與綠球的碰撞檢測、“堅持n秒”的定時器實現(xiàn)、清除定時器
結(jié)構(gòu)搭建
創(chuàng)建文本、容器和紅球,在此項目下小綠球是動態(tài)創(chuàng)建生成的;
樣式修飾
為創(chuàng)建的結(jié)構(gòu)設(shè)置樣式修飾
動態(tài)行為Javascript
采用面向?qū)ο蟮木幊趟季S
1.小綠球在容器頂部隨機位置生成
用random函數(shù)生成 [0,1)內(nèi)的隨機小數(shù)再乘以小綠球在水平方向的運動范圍,最后floor求整并將整數(shù)作為初始時小綠球與容器左壁的距離
2.小綠球非水平非垂直方向的運動
設(shè)置X方向的速度值和Y方向的速度值,與(1)相同,采用random函數(shù)乘以初始化XY方向的速度值就可以得到隨機方向
創(chuàng)建定時器獲取并更新小綠球與容器的左壁和上壁的距離以實現(xiàn)小球運動
3.小綠球碰撞容器內(nèi)壁后彈性運動
小綠球的邊界判斷,碰撞左壁和右壁時X方向的速度 * -1;碰撞上壁和下壁時Y方向的速度 * -1
4.生成多個小綠球
通過定時器不斷調(diào)用構(gòu)造函數(shù)生成多個小綠球,并置于一個數(shù)組中
5.拖拽紅球
為紅球添加點擊、拖動、松開事件。記住紅球上一頁面停留位置,與現(xiàn)在頁面停留位置做差得到紅球在XY方向的移動距離,分別加上上一停留位置紅球與容器左壁和上壁的距離得到現(xiàn)在紅球與容器左壁和上壁的距離,不斷循環(huán)更新上次停留位置和現(xiàn)在停留位置即可
6.紅球的邊界判斷
紅球和綠球的移動范圍都是容器的寬度高度減去自身球面的寬度和高度。觸碰邊界則重載頁面,為了避免頁面重載時出現(xiàn)持續(xù)觸碰邊界的情況加了鎖
7.紅球與綠球的碰撞檢測
判斷兩圓心之間的距離是否小于兩圓半徑之和
8.“堅持n秒”的定時器實現(xiàn)
定時器計時并修改span標簽的innerHTML
9.清除定時器
游戲結(jié)束時清除定時器
下面展示代碼:
/* 1.隨機生成小綠球在頂部 位置隨機 3.小綠球自己運動 4.彈性運動 2.生成多個 5.紅球拖拽 6.紅球邊界判斷 7.紅球和綠球碰撞檢測 8.定時器清除 9.堅持了多久 (但對象編程) */ var game = { name:'游戲開始', redBall:document.getElementsByClassName('red')[0], RunTime:document.getElementsByTagName('span')[0], num:0, greenArr:[], flag:true, movePlus:{ outer:document.getElementsByClassName('outer')[0], iWidth:document.getElementsByClassName('outer')[0].offsetWidth, iHeight:document.getElementsByClassName('outer')[0].offsetHeight, ispeedY:10,//小綠球的速度 ispeedX:10 }, init:function(){ console.log(this.name); // console.log(this.movePlus.iHeight); this.createBall(this.movePlus); this.dragRedBall(this.movePlus); this.runTime(); }, runTime:function(){ var self = this; this.Timer = setInterval(function(){ self.num++; self.RunTime.innerHTML = '堅持了' + self.num + '秒'; },1000); }, createBall:function(obj){ var self = this; var plus = obj; function Green(plus){ this.ball = document.createElement('div'); this.ball.className = 'green'; plus.outer.appendChild(this.ball); this.subWidth = Math.floor(Math.random()*(plus.iWidth - this.ball.offsetWidth)); this.ball.style.left = this.subWidth + 'px'; // this.subHeight = Math.floor(Math.random()*(plus.iHeight - this.ball.offsetHeight)); // this.ball.style.top = this.subHeight + 'px'; this.ispeedX = Math.floor(Math.random()*plus.ispeedX) + 1; this.ispeedY = Math.floor(Math.random()*plus.ispeedY) + 1; // 自定義屬性 this.iWidth = plus.iWidth; this.iHeight = plus.iHeight; } //先生出一個 var greenBall = new Green(plus); this.greenArr.push(greenBall); this.creatTimer = setInterval(function(){ var greenBall = new Green(plus); self.greenArr.push(greenBall) }, 2000); this.moveBall(); }, moveBall:function(){ //創(chuàng)建定時器 var self = this; // 保存window的this this.goTimer = setInterval(function(){ for(var i = 0;i < self.greenArr.length;i ++){ self.crashCheck(self.greenArr[i]); var newLeft = self.greenArr[i].ball.offsetLeft + self.greenArr[i].ispeedX ; var newTop = self.greenArr[i].ball.offsetTop + self.greenArr[i].ispeedY ; if(newLeft<0){ self.greenArr[i].ispeedX *= -1; } else if(newLeft > (self.greenArr[i].iWidth - self.greenArr[i].ball.offsetWidth)){ self.greenArr[i].ispeedX *= -1; } else if(newTop<0){ self.greenArr[i].ispeedY *= -1; // self.greenArr[i].ispeedX *= -1; } else if(newTop > (self.greenArr[i].iHeight - self.greenArr[i].ball.offsetHeight)){ self.greenArr[i].ispeedY *= -1; // self.greenArr[i].ispeedX *= -1; } // console.log((self.greenArr[i].iWidth - self.greenArr[i].ball.offsetWidth),(greenBall.iHeight - greenBall.ball.offsetHeight),greenBall.ispeedX,greenBall.ispeedY); self.greenArr[i].ball.style.left = newLeft + 'px'; self.greenArr[i].ball.style.top = newTop + 'px'; } },50) }, dragRedBall:function(obj){ var self = this; this.redBall.onmousedown = function(e){ var lastX = e.pageX, lastY = e.pageY; // self.redBall.style.left = lastX; // self.redBall.style.top = lastY; document.onmousemove = function(e){ var newX = e.pageX, newY = e.pageY; self.redBall.style.left = (newX - lastX) + self.redBall.offsetLeft + 'px'; self.redBall.style.top = (newY - lastY) + self.redBall.offsetTop + 'px'; // this.redBall.style.top = newY; lastX = newX; lastY = newY; //判斷邊界 if(self.redBall.offsetLeft<0 && self.flag){ alert("堅持了" + self.num + '秒' + "\n" + "游戲結(jié)束"); self.flag = false;//加鎖 self.clearTimer(); window.location.reload(); }else if(self.redBall.offsetLeft>(obj.iWidth-self.redBall.offsetWidth) && self.flag){ alert("堅持了" + self.num + '秒' + "\n" + "游戲結(jié)束"); self.flag = false; self.clearTimer(); window.location.reload();//刷新頁面 游戲重開 }else if(self.redBall.offsetTop<0 && self.flag){ alert("堅持了" + self.num + '秒' + "\n" + "游戲結(jié)束"); self.flag = false; self.clearTimer(); window.location.reload(); }else if(self.redBall.offsetTop>(obj.iHeight-self.redBall.offsetHeight ) && self.flag){ alert("堅持了" + self.num + '秒' + "\n" + "游戲結(jié)束"); self.flag = false; self.clearTimer(); window.location.reload(); } } this.onmouseup = function(){ document.onmousemove = null; } } }, crashCheck:function(greenBall){ // var self = this; //效率球的圓心 var greenX1 = greenBall.ball.offsetLeft + Math.floor(greenBall.ball.offsetWidth / 2), greenY1 = greenBall.ball.offsetTop + Math.floor(greenBall.ball.offsetHeight / 2), //小紅求的圓心 redX1 = this.redBall.offsetLeft + Math.floor(this.redBall.offsetWidth / 2), redY1 = this.redBall.offsetTop + Math.floor(this.redBall.offsetHeight / 2); // console.log(greenX1,greenY1,redX1,redY1); // debug成功 //x1 - x2,y1 - y2 的絕對值 var dx = Math.abs(greenX1 - redX1), dy = Math.abs(greenY1 - redY1); // console.log(dx,dy); var dis = Math.floor(Math.sqrt(Math.pow(dx,2) + Math.pow(dy,2))); // console.log(dis); var R = greenBall.ball.offsetWidth/2 + this.redBall.offsetWidth/2; if(dis < R && this.flag){ alert("堅持了" + this.num + '秒' + "\n" + "游戲結(jié)束"); this.flag = false; this.clearTimer(); window.location.reload(); } }, clearTimer:function(){ clearInterval(this.goTimer); clearInterval(this.creatTimer); clearInterval(this.Timer); } } game.init();//入口函數(shù)
請各位大佬指正
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript XML和string相互轉(zhuǎn)化實現(xiàn)代碼
兩個小function實現(xiàn)XML和string相互轉(zhuǎn)化,需要的朋友可以參考下。2011-07-07如何利用原生JS實現(xiàn)觸摸滑動監(jiān)聽事件
這篇文章主要給大家介紹了關(guān)于如何利用原生JS實現(xiàn)觸摸滑動監(jiān)聽事件的相關(guān)資料,文中將實現(xiàn)的原理以及代碼介紹的非常詳細,需要的朋友可以參考下2021-06-06Javascript highcharts 餅圖顯示數(shù)量和百分比實例代碼
這篇文章主要介紹了Javascript highcharts 餅圖顯示數(shù)量和百分比實例代碼的相關(guān)資料,這里附有實例代碼,需要的朋友可以參考下2016-12-12JavaScript中call和apply方法的區(qū)別實例分析
這篇文章主要介紹了JavaScript中call和apply方法的區(qū)別,結(jié)合實例形式分析call和apply方法的功能、原理及相關(guān)使用操作區(qū)別,需要的朋友可以參考下2018-08-08網(wǎng)站基于flash實現(xiàn)的Banner圖切換效果代碼
這篇文章主要介紹了網(wǎng)站基于flash實現(xiàn)的Banner圖切換效果代碼,是基于Flash與js實現(xiàn)的banner圖片自動定時切換特效,并附有完整的示例源碼,非常具有實用價值,需要的朋友可以參考下2014-10-10