JS實現(xiàn)躲避粒子小游戲
本文實例為大家分享了JS實現(xiàn)躲避粒子小游戲的具體代碼,供大家參考,具體內(nèi)容如下
小項目的實戰(zhàn)操作可以幫助我們更好的掌握javascript
躲避例子游戲規(guī)則:拖拽紅球躲避綠球碰撞,拖拽過程不能觸碰容器內(nèi)壁,以贏得游戲持久度
頁面效果:

實現(xiàn)過程
不積小流,無以成江海。
將頁面效果的實現(xiàn)細分成小步實現(xiàn):頁面結構的構建,樣式修飾,js中小綠球在容器頂部隨機位置生成、小綠球非水平非垂直方向的運動、小綠球碰撞容器內(nèi)壁后彈性運動、生成多個小綠球、拖拽紅球、紅球的邊界判斷、紅球與綠球的碰撞檢測、“堅持n秒”的定時器實現(xiàn)、清除定時器
結構搭建
創(chuàng)建文本、容器和紅球,在此項目下小綠球是動態(tài)創(chuàng)建生成的;

樣式修飾
為創(chuàng)建的結構設置樣式修飾

動態(tài)行為Javascript
采用面向對象的編程思維
1.小綠球在容器頂部隨機位置生成
用random函數(shù)生成 [0,1)內(nèi)的隨機小數(shù)再乘以小綠球在水平方向的運動范圍,最后floor求整并將整數(shù)作為初始時小綠球與容器左壁的距離
2.小綠球非水平非垂直方向的運動
設置X方向的速度值和Y方向的速度值,與(1)相同,采用random函數(shù)乘以初始化XY方向的速度值就可以得到隨機方向
創(chuàng)建定時器獲取并更新小綠球與容器的左壁和上壁的距離以實現(xiàn)小球運動
3.小綠球碰撞容器內(nèi)壁后彈性運動
小綠球的邊界判斷,碰撞左壁和右壁時X方向的速度 * -1;碰撞上壁和下壁時Y方向的速度 * -1
4.生成多個小綠球
通過定時器不斷調(diào)用構造函數(shù)生成多個小綠球,并置于一個數(shù)組中
5.拖拽紅球
為紅球添加點擊、拖動、松開事件。記住紅球上一頁面停留位置,與現(xiàn)在頁面停留位置做差得到紅球在XY方向的移動距離,分別加上上一停留位置紅球與容器左壁和上壁的距離得到現(xiàn)在紅球與容器左壁和上壁的距離,不斷循環(huán)更新上次停留位置和現(xiàn)在停留位置即可
6.紅球的邊界判斷
紅球和綠球的移動范圍都是容器的寬度高度減去自身球面的寬度和高度。觸碰邊界則重載頁面,為了避免頁面重載時出現(xiàn)持續(xù)觸碰邊界的情況加了鎖
7.紅球與綠球的碰撞檢測
判斷兩圓心之間的距離是否小于兩圓半徑之和
8.“堅持n秒”的定時器實現(xià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(){
//創(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" + "游戲結束");
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();//入口函數(shù)
請各位大佬指正
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
JavaScript使用DeviceOne開發(fā)實戰(zhàn)(三)仿微信應用
這篇文章主要介紹了JavaScript使用DeviceOne開發(fā)實戰(zhàn)(三)仿微信應用的相關資料,需要的朋友可以參考下2015-12-12
JS實現(xiàn)unicode和UTF-8之間的互相轉換互轉
需要將PC送過來的UTF-8轉換成UNICODE才能將內(nèi)容通過短信發(fā)送出去,同樣,接收到的短信為unicode編碼,也許轉換成UTF-8才能在PC端軟件顯示出來2017-07-07
教你修改element-ui源碼給el-dialog添加全屏功能
el-dialog組件提供了fullscreen功能,但是無法滿足業(yè)務需求。系統(tǒng)使用了許多dialog,不方便重新封裝dialog組件,故直接對源碼進行修改,這篇文章主要介紹了修改element-ui源碼給el-dialog添加全屏功能,需要的朋友可以參考下2022-11-11
Bootstrap企業(yè)網(wǎng)站實戰(zhàn)項目4
這篇文章主要為大家分享了Bootstrap企業(yè)網(wǎng)站實戰(zhàn)項目,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-10-10
解決在Bootstrap模糊框中使用WebUploader的問題
這篇文章主要介紹了在Bootstrap模糊框中使用WebUploader的問題及解決方法,,需要的朋友可以參考下2018-03-03

