JS實現躲避粒子小遊戲
本文例項為大家分享了JS實現躲避粒子小遊戲的具體程式碼,供大家參考,具體內容如下
小專案的實戰操作可以幫助我們更好的掌握javascript
躲避例子游戲規則:拖拽紅球躲避綠球碰撞,拖拽過程不能觸碰容器內壁,以贏得遊戲持久度
頁面效果:
實現過程
不積小流,無以成江海。
將頁面效果的實現細分成小步實現:頁面結構的構建,樣式修飾,js中小綠球在容器頂部隨機位置生成、小綠球非水平非垂直方向的運動、小綠球碰撞容器內壁後彈性運動、生成多個小綠球、拖拽紅球、紅球的邊界判斷、紅球與綠球的碰撞檢測、“堅持n秒”的定時器實現、清除定時器
結構搭建
建立文字、容器和紅球,在此專案下小綠球是動態建立生成的;
樣式修飾
為建立的結構設定樣式修飾
動態行為Javascript
採用面向物件的程式設計思維
1.小綠球在容器頂部隨機位置生成
用random函式生成 [0,1)內的隨機小數再乘以小綠球在水平方向的運動範圍,最後floor求整並將整數作為初始時小綠球與容器左壁的距離
2.小綠球非水平非垂直方向的運動
設定X方向的速度值和Y方向的速度值,與(1)相同,採用random函式乘以初始化XY方向的速度值就可以得到隨機方向
建立定時器獲取並更新小綠球與容器的左壁和上壁的距離以實現小球運動
3.小綠球碰撞容器內壁後彈性運動
小綠球的邊界判斷,碰撞左壁和右壁時X方向的速度 * -1;碰撞上壁和下壁時Y方向的速度 * -1
4.生成多個小綠球
通過定時器不斷呼叫建構函式生成多個小綠球,並置於一個數組中
5.拖拽紅球
為紅球新增點選、拖動、鬆開事件。記住紅球上一頁面停留位置,與現在頁面停留位置做差得到紅球在XY方向的移動距離,分別加上上一停留位置紅球與容器左壁和上壁的距離得到現在紅球與容器左壁和上壁的距離,不斷迴圈更新上次停留位置和現在停留位置即可
6.紅球的邊界判斷
紅球和綠球的移動範圍都是容器的寬度高度減去自身球面的寬度和高度。觸碰邊界則過載頁面,為了避免頁面過載時出現持續觸碰邊界的情況加了鎖
7.紅球與綠球的碰撞檢測
判斷兩圓心之間的距離是否小於兩圓半徑之和
8.“堅持n秒”的定時器實現
定時器計時並修改span標籤的innerHTML
9.清除定時器
遊戲結束時清除定時器
下面展示程式碼:
/* 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(){ //建立定時器 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" + "遊戲結束"); self.flag = false;//加鎖 self.clearTimer(); window.location.reload(); }else if(self.redBall.offsetLeft>(obj.iWidth-self.redBall.offsetWidth) && self.flag){ alert("堅持了" + self.num + '秒' + "\n" + "遊戲結束"); self.flag = false; self.clearTimer(); window.location.reload();//重新整理頁面 遊戲重開 }else if(self.redBall.offsetTop<0 && self.flag){ alert("堅持了" + self.num + '秒' + "\n" + "遊戲結束"); self.flag = false; self.clearTimer(); window.location.reload(); }else if(self.redBall.offsetTop>(obj.iHeight-self.redBall.offsetHeight ) && self.flag){ alert("堅持了" + self.num + '秒' + "\n" + "遊戲結束"); 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" + "遊戲結束"); this.flag = false; this.clearTimer(); window.location.reload(); } },clearTimer:function(){ clearInterval(this.goTimer); clearInterval(this.creatTimer); clearInterval(this.Timer); } } game.init();//入口函式
請各位大佬指正
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。