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

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

樣式修飾
為創(chuàng)建的結(jié)構(gòu)設(shè)置樣式修飾

動(dòng)態(tài)行為Javascript
采用面向?qū)ο蟮木幊趟季S
1.小綠球在容器頂部隨機(jī)位置生成
用random函數(shù)生成 [0,1)內(nèi)的隨機(jī)小數(shù)再乘以小綠球在水平方向的運(yùn)動(dòng)范圍,最后floor求整并將整數(shù)作為初始時(shí)小綠球與容器左壁的距離
2.小綠球非水平非垂直方向的運(yùn)動(dòng)
設(shè)置X方向的速度值和Y方向的速度值,與(1)相同,采用random函數(shù)乘以初始化XY方向的速度值就可以得到隨機(jī)方向
創(chuàng)建定時(shí)器獲取并更新小綠球與容器的左壁和上壁的距離以實(shí)現(xiàn)小球運(yùn)動(dòng)
3.小綠球碰撞容器內(nèi)壁后彈性運(yùn)動(dòng)
小綠球的邊界判斷,碰撞左壁和右壁時(shí)X方向的速度 * -1;碰撞上壁和下壁時(shí)Y方向的速度 * -1
4.生成多個(gè)小綠球
通過定時(shí)器不斷調(diào)用構(gòu)造函數(shù)生成多個(gè)小綠球,并置于一個(gè)數(shù)組中
5.拖拽紅球
為紅球添加點(diǎn)擊、拖動(dòng)、松開事件。記住紅球上一頁面停留位置,與現(xiàn)在頁面停留位置做差得到紅球在XY方向的移動(dòng)距離,分別加上上一停留位置紅球與容器左壁和上壁的距離得到現(xiàn)在紅球與容器左壁和上壁的距離,不斷循環(huán)更新上次停留位置和現(xiàn)在停留位置即可
6.紅球的邊界判斷
紅球和綠球的移動(dòng)范圍都是容器的寬度高度減去自身球面的寬度和高度。觸碰邊界則重載頁面,為了避免頁面重載時(shí)出現(xiàn)持續(xù)觸碰邊界的情況加了鎖
7.紅球與綠球的碰撞檢測
判斷兩圓心之間的距離是否小于兩圓半徑之和
8.“堅(jiān)持n秒”的定時(shí)器實(shí)現(xiàn)
定時(shí)器計(jì)時(shí)并修改span標(biāo)簽的innerHTML
9.清除定時(shí)器
游戲結(jié)束時(shí)清除定時(shí)器
下面展示代碼:
/*
1.隨機(jī)生成小綠球在頂部 位置隨機(jī)
3.小綠球自己運(yùn)動(dòng)
4.彈性運(yùn)動(dòng)
2.生成多個(gè)
5.紅球拖拽
6.紅球邊界判斷
7.紅球和綠球碰撞檢測
8.定時(shí)器清除
9.堅(jiān)持了多久
(但對象編程)
*/
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 = '堅(jiān)持了' + 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;
}
//先生出一個(gè)
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)建定時(shí)器
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("堅(jiān)持了" + 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("堅(jiān)持了" + self.num + '秒' + "\n" + "游戲結(jié)束");
self.flag = false;
self.clearTimer();
window.location.reload();//刷新頁面 游戲重開
}else if(self.redBall.offsetTop<0 && self.flag){
alert("堅(jiān)持了" + 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("堅(jiān)持了" + 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("堅(jiān)持了" + 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í)有所幫助,也希望大家多多支持腳本之家。
- js canvas實(shí)現(xiàn)隨機(jī)粒子特效
- js實(shí)現(xiàn)三角形粒子運(yùn)動(dòng)
- js實(shí)現(xiàn)3D粒子酷炫動(dòng)態(tài)旋轉(zhuǎn)特效
- JavaScript動(dòng)畫實(shí)例之粒子文本的實(shí)現(xiàn)方法詳解
- javascript Canvas動(dòng)態(tài)粒子連線
- JavaScript實(shí)現(xiàn)鼠標(biāo)移動(dòng)粒子跟隨效果
- 基于three.js實(shí)現(xiàn)的3D粒子動(dòng)效實(shí)例代碼
- 原生JS+HTML5實(shí)現(xiàn)跟隨鼠標(biāo)一起流動(dòng)的粒子動(dòng)畫效果
- 使用3D引擎threeJS實(shí)現(xiàn)星空粒子移動(dòng)效果
- ThingJS粒子特效一鍵實(shí)現(xiàn)雨雪效果
相關(guān)文章
JavaScript XML和string相互轉(zhuǎn)化實(shí)現(xiàn)代碼
兩個(gè)小function實(shí)現(xiàn)XML和string相互轉(zhuǎn)化,需要的朋友可以參考下。2011-07-07
如何利用原生JS實(shí)現(xiàn)觸摸滑動(dòng)監(jiān)聽事件
這篇文章主要給大家介紹了關(guān)于如何利用原生JS實(shí)現(xiàn)觸摸滑動(dòng)監(jiān)聽事件的相關(guān)資料,文中將實(shí)現(xiàn)的原理以及代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-06-06
js實(shí)現(xiàn)的在線調(diào)色板功能完整實(shí)例
這篇文章主要介紹了js實(shí)現(xiàn)的在線調(diào)色板功能,結(jié)合完整實(shí)例形式分析了調(diào)色板的完整實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下2016-12-12
Javascript highcharts 餅圖顯示數(shù)量和百分比實(shí)例代碼
這篇文章主要介紹了Javascript highcharts 餅圖顯示數(shù)量和百分比實(shí)例代碼的相關(guān)資料,這里附有實(shí)例代碼,需要的朋友可以參考下2016-12-12
JavaScript中call和apply方法的區(qū)別實(shí)例分析
這篇文章主要介紹了JavaScript中call和apply方法的區(qū)別,結(jié)合實(shí)例形式分析call和apply方法的功能、原理及相關(guān)使用操作區(qū)別,需要的朋友可以參考下2018-08-08
網(wǎng)站基于flash實(shí)現(xiàn)的Banner圖切換效果代碼
這篇文章主要介紹了網(wǎng)站基于flash實(shí)現(xiàn)的Banner圖切換效果代碼,是基于Flash與js實(shí)現(xiàn)的banner圖片自動(dòng)定時(shí)切換特效,并附有完整的示例源碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-10-10

