JS实现躲避粒子小游戏


Posted in Javascript onJune 18, 2020

本文实例为大家分享了JS实现躲避粒子小游戏的具体代码,供大家参考,具体内容如下

小项目的实战操作可以帮助我们更好的掌握javascript

躲避例子游戏规则:拖拽红球躲避绿球碰撞,拖拽过程不能触碰容器内壁,以赢得游戏持久度

页面效果:

JS实现躲避粒子小游戏

实现过程

不积小流,无以成江海。
将页面效果的实现细分成小步实现:页面结构的构建,样式修饰,js中小绿球在容器顶部随机位置生成、小绿球非水平非垂直方向的运动、小绿球碰撞容器内壁后弹性运动、生成多个小绿球、拖拽红球、红球的边界判断、红球与绿球的碰撞检测、“坚持n秒”的定时器实现、清除定时器

结构搭建

创建文本、容器和红球,在此项目下小绿球是动态创建生成的;

JS实现躲避粒子小游戏

样式修饰

为创建的结构设置样式修饰

JS实现躲避粒子小游戏

动态行为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();//入口函数

请各位大佬指正

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript this 的一些学习总结
Aug 02 Javascript
jquery的相对父元素和相对文档定位示例代码
Aug 02 Javascript
jQuery实现类似老虎机滚动抽奖效果
Aug 06 Javascript
基于JavaScript实现简单的随机抽奖小程序
Jan 05 Javascript
JavaScript的MVVM库Vue.js入门学习笔记
May 03 Javascript
js判断checkbox是否选中个数的方法(超简单)
Aug 19 Javascript
纯JS代码实现隔行变色鼠标移入高亮
Nov 23 Javascript
原生js实现放大镜
Feb 20 Javascript
AngularJS实现的base64编码与解码功能示例
May 17 Javascript
vue 封装 Adminlte3组件的实现
Mar 18 Javascript
浅谈vue的第一个commit分析
Jun 08 Javascript
html-webpack-plugin修改页面的title的方法
Jun 18 #Javascript
vue实现购物车结算功能
Jun 18 #Javascript
vue-cli4.x创建企业级项目的方法步骤
Jun 18 #Javascript
javascript实现文字跑马灯效果
Jun 18 #Javascript
node.js +mongdb实现登录功能
Jun 18 #Javascript
VSCode launch.json配置详细教程
Jun 18 #Javascript
JavaScript中使用Spread运算符的八种方法总结
Jun 18 #Javascript
You might like
PHP 加密与解密的斗争
2009/04/17 PHP
php mssql 分页SQL语句优化 持续影响
2009/04/26 PHP
PHP+Mysql+jQuery实现动态展示信息
2011/10/08 PHP
PHP命名空间(namespace)的动态访问及使用技巧
2014/08/18 PHP
跨浏览器PHP下载文件名中的中文乱码问题解决方法
2015/03/05 PHP
php 实现进制相互转换
2016/04/07 PHP
PHP读取大文件的几种方法介绍
2016/10/27 PHP
phpmyadmin在宝塔面板里进不去的解决方案
2020/07/06 PHP
PHP实现文件上传与下载
2020/08/28 PHP
PHP编程一定要改掉的5个不良习惯
2020/09/18 PHP
学习YUI.Ext基础第一天
2007/03/10 Javascript
关于jquery ajax 调用带参数的webservice返回XML数据一个小细节
2012/07/31 Javascript
JQuery中form验证出错信息的查看方法
2013/10/08 Javascript
网站接入QQ登录的两种方法
2014/07/22 Javascript
Bootstrap项目实战之子栏目资讯内容
2016/04/25 Javascript
老生常谈jquery id选择器和class选择器的区别
2017/02/12 Javascript
vue 路由页面之间实现用手指进行滑动的方法
2018/02/23 Javascript
Node批量爬取头条视频并保存方法
2018/09/20 Javascript
在vue中使用v-bind:class的选项卡方法
2018/09/27 Javascript
使用jQuery实现掷骰子游戏
2019/10/24 jQuery
浅析Vue 防抖与节流的使用
2019/11/14 Javascript
Vue包大小优化的实现(从1.72M到94K)
2021/02/18 Vue.js
[02:04]完美世界城市挑战赛秋季赛报名开始 谁是solo路人王?
2019/10/10 DOTA
Python遍历目录并批量更换文件名和目录名的方法
2016/09/19 Python
Python中的字符串操作和编码Unicode详解
2017/01/18 Python
深入解答关于Python的11道基本面试题
2017/04/01 Python
python email smtplib模块发送邮件代码实例
2018/04/26 Python
Python3.6连接Oracle数据库的方法详解
2018/05/18 Python
使用Django连接Mysql数据库步骤
2019/01/15 Python
浅谈python的输入输出,注释,基本数据类型
2019/04/02 Python
python程序变成软件的实操方法
2019/06/24 Python
python顺序执行多个py文件的方法
2019/06/29 Python
django-crontab实现服务端的定时任务的示例代码
2020/02/17 Python
在python中使用pymysql往mysql数据库中插入(insert)数据实例
2020/03/02 Python
爱与责任演讲稿
2014/05/20 职场文书
社区党的群众路线教育实践活动总结材料
2014/10/31 职场文书