A5下载 - 努力做内容最丰富最安全的下载站!

A5站长下载站

当前位置:A5下载 > 源码技巧 > 父类数据 > javascript实现10个球随机运动、碰撞实例详解

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

时间:2015-07-08 15:41作者:zhao人气:78

本文实例讲述了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,实现,10个,随机,运动,碰撞,实例

相关下载

查看所有评论+

网友评论

网友
您的评论需要经过审核才能显示

公众号