javascript实现10个球随机运动、碰撞实例详解_javascript技巧

本文实例讲述了javascript实现10个球随机运动、碰撞的方法。分享给大家供大家参考。具体如下:

学了一段时间的javascript了,做过一些小案例,目前最有难度的就是10个小球随机碰撞效果,这不,把它上上来与大家分享一下,相信不少和我一样的菜鸟在开始上手编程时都会有不少的困惑,希望它能给一些人带来帮助。

效果要求:10个小球在页面随机移动,碰到窗口边界或其他小球都会反弹

思路:

1、10个小球是10个div;
2、碰窗口反弹,定义vx vy为小球的移动变量,以及一个弹力变量bounce(负值),小球碰窗口边界时,vx vy分别乘以bounce,则改变了小球移动方向
3、小球相碰反弹,说简单点,当两个小球的圆心距变量dist小于其最小值(半径之和)则改变球的移动方向,实现反弹

好了,代码如下:

html和js是分开的文件哟
 
test.html文件如下:

<html>
 <head>
  <title></title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   <style type="text/css">
body {
    margin:0;
    padding:0;
    text-align: center;
}
#screen { width: 800px; height: 640px; position: relative; background: #ccccff;margin: 0 auto;vertical-align: bottom}
#inner { position: absolute; left:0px; top:0px; width:100%; height:100%; }
#screen p {color:white;font:bold 14px;}
.one { background-image:url('bubble.png'); background-position: -66px -58px; }
.two { background-image:url('bubble.png'); background-position: -66px -126px;}
.three { background-image:url('bubble.png'); background-position: -66px -194px; }
.four { background-image:url('bubble.png'); background-position: -66px -263px; }
.five { background-image:url('bubble.png'); background-position: -66px -331px; }
.six { background-image:url('bubble.png'); background-position: -66px -399px; }
.seven { background-image:url('bubble.png'); background-position: -66px -194px; }
.eight { background-image:url('bubble.png'); background-position: -66px -263px; }
.nine { background-image:url('bubble.png'); background-position: -66px -331px; }
.ten{ background-image:url('bubble.png'); background-position: -66px -399px; }
  </style>
 </head>
 <body>
   <div id="screen" >
     <p>hi test it!</p>
     <div id="inner"></div>
   </div>
   <input type="button" id="start" value="start" >
   <input type="button" id="stop" value="stop">
   <br><br><br>
<script type="text/javascript" src="test.js"></script>
 </body>
</html>

test.js文件如下:

var getFlag=function (id) {
     return document.getElementByIdx_x(id);  //获取元素引用
}
var extend=function(des, src) {
     for (p in src) {
       des[p]=src[p];
   }
  return des;
 }
var clss=['one','two','three','four','five','six','seven','eight','nine','ten'];
var Ball=function (diameter,classn) {
  var ball=document.createElement_x("div");
  ball.className=classn;
  with(ball.style) {
    width=height=diameter+'px';position='absolute';
  }
  return ball;
}
var Screen=function (cid,config) {
  //先创建类的属性
  var self=this;
  if (!(self instanceof Screen)) {
    return new Screen(cid,config)
  }
  config=extend(Screen.Config, config)  //configj是extend类的实例
  self.container=getFlag(cid);      //窗口对象
  self.ballsnum=config.ballsnum;
  self.diameter=56;            //球的直径
  self.radius=self.diameter/2;
  self.spring=config.spring;       //球相碰后的反弹力
  self.bounce=config.bounce;       //球碰到窗口边界后的反弹力
  self.gravity=config.gravity;      //球的重力
  self.balls=[];             //把创建的球置于该数组变量
  self.timer=null;            //调用函数产生的时间id
  self.L_bound=0;            //container的边界
  self.R_bound=self.container.clientWidth;
  self.T_bound=0;
  self.B_bound=self.container.clientHeight;
};
Screen.Config={             //为属性赋初值
  ballsnum:10,
  spring:0.8,
  bounce:-0.9,
  gravity:0.05
};
Screen.prototype={
  initialize:function () {
    var self=this;
    self.createBalls();
    self.timer=setInterval(function (){self.hitBalls()}, 30)
  },
  createBalls:function () {
    var self=this, num=self.ballsnum;
    var frag=document.createDocumentFragment();  //创建文档碎片,避免多次刷新
     for (i=0;i<num;i++) {
      var ball=new Ball(self.diameter,clss[ Math.floor(Math.random()* num )]);
      ball.diameter=self.diameter;
      ball.radius=self.radius;
      ball.style.left=(Math.random()*self.R_bound)+'px'; //球的初始位置,
      ball.style.top=(Math.random()*self.B_bound)+'px';
      ball.vx=Math.random() * 6 -3;
      ball.vy=Math.random() * 6 -3;
      frag.appendChild(ball);
      self.balls[i]=ball;
    }
    self.container.appendChild(frag);
  },
  hitBalls:function () {
    var self=this, num=self.ballsnum,balls=self.balls;
    for (i=0;i<num-1;i++) {
      var ball1=self.balls[i];
      ball1.x=ball1.offsetLeft+ball1.radius;   //小球圆心坐标
      ball1.y=ball1.offsetTop+ball1.radius;
      for (j=i+1;j<num;j++) {
        var ball2=self.balls[j];
        ball2.x=ball2.offsetLeft+ball2.radius;
        ball2.y=ball2.offsetTop+ball2.radius;
        dx=ball2.x-ball1.x;           //两小球圆心距对应的两条直角边
        dy=ball2.y-ball1.y;
        var dist=Math.sqrt(dx*dx + dy*dy);    //两直角边求圆心距
        var misDist=ball1.radius+ball2.radius;  //圆心距最小值
       if(dist < misDist) {
          //假设碰撞后球会按原方向继续做一定的运动,将其定义为运动A
          var angle=Math.atan2(dy,dx);
         //当刚好相碰,即dist=misDist时,tx=ballb.x, ty=ballb.y
          tx=balla.x+Math.cos(angle) * misDist;
            ty=balla.y+Math.sin(angle) * misDist;
         //产生运动A后,tx > ballb.x, ty > ballb.y,所以用ax、ay记录的是运动A的值
            ax=(tx-ballb.x) * self.spring;
            ay=(ty-ballb.y) * self.spring;
         //一个球减去ax、ay,另一个加上它,则实现反弹
            balla.vx-=ax;
            balla.vy-=ay;
            ballb.vx+=ax;
            ballb.vy+=ay;
          }
      }
    }
    for (i=0;i<num;i++) {
      self.moveBalls(balls[i]);
    }
  },
  moveBalls:function (ball) {
    var self=this;
    ball.vy+=self.gravity;
    ball.style.left=(ball.offsetLeft+ball.vx)+'px';
    ball.style.top=(ball.offsetTop+ball.vy)+'px';
    //判断球与窗口边界相碰,把变量名简化一下
    var L=self.L_bound, R=self.R_bound, T=self.T_bound, B=self.B_bound, BC=self.bounce;
    if (ball.offsetLeft < L) {
      ball.style.left=L;
      ball.vx*=BC;
    }
    else if (ball.offsetLeft + ball.diameter > R) {
      ball.style.left=(R-ball.diameter)+'px';
      ball.vx*=BC;
    }
    else if (ball.offsetTop < T) {
      ball.style.top=T;
      ball.vy*=BC;
    }
    if (ball.offsetTop + ball.diameter > B) {
      ball.style.top=(B-ball.diameter)+'px';
      ball.vy*=BC;
    }
  }
}
window.onload=function() {
  var sc=null;
  getFlag('start').onclick=function () {
    document.getElementByIdx_x("inner").innerHTML='';
    sc=new Screen('inner',{ballsnum:10, spring:0.8, bounce:-0.9, gravity:0.05});
    sc.initialize();
  }
  getFlag('stop').onclick=function() {
    clearInterval(sc.timer);
  }
}

测试后的效果还是很不错的,各位也许会觉得代码挺长,但是其思路还是蛮清晰的:
首先创建Screen类,并在Screen的构造函数中给出了球移动、碰撞所需的各种属性变量,如ballsnum、spring、bounce、gravity等等
然后用原型prototype给出相应的函数,如创建球,createBalls,球碰撞hitBalls,球移动moveBalls,给每个函数添加相应的功能、
最后用按钮点击事件调用函数,仅此而已。

希望本文所述对大家的javascript程序设计有所帮助。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索javascript
, 球
, 碰撞
随机运动
javascript碰撞检测、javascript小球碰撞、abaqus碰撞分析实例、ansys碰撞分析实例、opengl碰撞检测实例,以便于您获取更多的相关知识。

时间: 2024-08-31 01:51:08

javascript实现10个球随机运动、碰撞实例详解_javascript技巧的相关文章

javascript中2个感叹号的用法实例详解_javascript技巧

在javascript代码中经常会见到!!的情况,本文即以实例形式较为深入的分析javascript中2个感叹号的用法.分享给大家供大家参考之用.具体分析如下: javascript中的!!是逻辑"非非",即是在逻辑"非"的基础上再"非"一次.通过!或!!可以将很多类型转换成bool类型,再做其它判断. 一.应用场景:判断一个对象是否存在 假设有这样一个json对象: { color: "#E3E3E3", "fon

JavaScript函数内部属性和函数方法实例详解_javascript技巧

函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块. 函数是对象,有自己的属性和方法 .首先通过console下输出的函数属性方法来直观的看一下: 函数内部属性只要包括两个特殊的对象:arguments和this. 函数属性包括:length和prototype 函数方法(非继承)包括:apply()和call() 继承而来的函数方法:bind().toString().toLocaleString().valueOf() 其他的目前不熟,后面再补充 1. 函数内部属性 在函数内部,有两

javascript定义类和类的实现实例详解_javascript技巧

本文实例讲述了javascript定义类和类的实现.分享给大家供大家参考,具体如下: 最近在几个群上经常看到有人问在一个类里的一个 function 怎么调用 this. 定义后公开的方法.现发一篇类实现的随笔. 首先说说类,在一个类里我们会有以下的几个特征: 1. 公有方法 2. 私有方法 3. 属性 4. 私有变量 5. 析构函数 我们直接看一个例子: /***定义类***/ var Class = function(){ var _self = this;//把本身引用负值到一变量上 va

javascript动态创建表格及添加数据实例详解_javascript技巧

本文实例讲述了javascript动态创建表格及添加数据的方法.分享给大家供大家参考.具体分析如下: 1. 动态创建表格(代码不兼容IE6) <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>动态

Javascript中的方法和匿名方法实例详解_javascript技巧

本文实例讲述了Javascript中的方法和匿名方法.分享给大家供大家参考.具体分析如下: Javascript方法(函数) 声明函数 以function开头,后跟函数名,与C#.java不同,Javascript不需要声明返回值类型.参数类型.没有返回值就是undefined. 举个例子更清楚:  无参数无返回值的方法: function f1(){ alert('这是一个方法'); } f1();//调用方法 无参数有返回值的方法: function f2(){ return 100; }

javascript设置和获取cookie的方法实例详解_javascript技巧

本文实例讲述了javascript设置和获取cookie的方法.分享给大家供大家参考,具体如下: 1. 设置cookie function setCookie(cookieName,cookieValue,cookieExpires,cookiePath) { cookieValue = escape(cookieValue);//编码latin-1 if(cookieExpires=="") { var nowDate = new Date(); nowDate.setMonth(n

JavaScript学习小结之被嫌弃的eval函数和with语句实例详解_javascript技巧

前面的话 eval和with经常被嫌弃,好像它们的存在就是错误.在CSS中,表格被嫌弃,在网页中只是用表格来展示数据,而不是做布局,都可能被斥为不规范,矫枉过正.那关于eval和with到底是什么情况呢?本文将详细介绍eval()函数和with语句 eval 定义 eval()是一个全局函数,javascript通过eval()来解释运行由javascript源代码组成的字符串 var result = eval('3+2'); console.log(result,typeof result)

javascript常用经典算法实例详解_javascript技巧

本文实例讲述了javascript常用算法.分享给大家供大家参考,具体如下: 入门级算法-线性查找-时间复杂度O(n)--相当于算法界中的HelloWorld //线性搜索(入门HelloWorld) //A为数组,x为要搜索的值 function linearSearch(A, x) { for (var i = 0; i < A.length; i++) { if (A[i] == x) { return i; } } return -1; } 二分查找(又称折半查找) - 适用于已排好序的

Javascript复制实例详解_javascript技巧

在做项目时有一个需求,是需要复制内容到剪切板,因为有众多浏览器,所以要兼容性很重要. 1.最简单的copy,只能在IE下使用 使用clipboardData方法 <script type="text/javascript"> function copy(){ window.clipboardData.setData("text",document.getElementById("name").value); alert("T