首页 > 语言 > JavaScript > 正文

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

2024-05-06 16:22:46
字体:
来源:转载
供稿:网友

这篇文章主要介绍了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文件如下:

 

 
  1. <html> 
  2. <head> 
  3. <title></title> 
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
  5. <style type="text/css"
  6. body { 
  7. margin:0; 
  8. padding:0; 
  9. text-align: center; 
  10. #screen { width: 800px; height: 640px; position: relative; background: #ccccff;margin: 0 auto;vertical-align: bottom} 
  11. #inner { position: absolute; left:0px; top:0px; width:100%; height:100%; } 
  12. #screen p {color:white;font:bold 14px;} 
  13. .one { background-image:url('bubble.png'); background-position: -66px -58px; } 
  14. .two { background-image:url('bubble.png'); background-position: -66px -126px;} 
  15. .three { background-image:url('bubble.png'); background-position: -66px -194px; } 
  16. .four { background-image:url('bubble.png'); background-position: -66px -263px; } 
  17. .five { background-image:url('bubble.png'); background-position: -66px -331px; } 
  18. .six { background-image:url('bubble.png'); background-position: -66px -399px; } 
  19. .seven { background-image:url('bubble.png'); background-position: -66px -194px; } 
  20. .eight { background-image:url('bubble.png'); background-position: -66px -263px; } 
  21. .nine { background-image:url('bubble.png'); background-position: -66px -331px; } 
  22. .ten{ background-image:url('bubble.png'); background-position: -66px -399px; } 
  23. </style> 
  24. </head> 
  25. <body> 
  26. <div id="screen" > 
  27. <p>hi test it!</p> 
  28. <div id="inner"></div> 
  29. </div> 
  30. <input type="button" id="start" value="start" > 
  31. <input type="button" id="stop" value="stop"
  32. <br><br><br> 
  33. <script type="text/javascript" src="test.js"></script> 
  34. </body> 
  35. </html> 

test.js文件如下:

 

 
  1. var getFlag=function (id) { 
  2. return document.getElementByIdx_x(id); //获取元素引用 
  3. var extend=function(des, src) { 
  4. for (p in src) { 
  5. des[p]=src[p]; 
  6. return des; 
  7. var clss=['one','two','three','four','five','six','seven','eight','nine','ten']; 
  8. var Ball=function (diameter,classn) { 
  9. var ball=document.createElement_x("div"); 
  10. ball.className=classn; 
  11. with(ball.style) { 
  12. width=height=diameter+'px';position='absolute'
  13. return ball; 
  14. var Screen=function (cid,config) { 
  15. //先创建类的属性 
  16. var self=this
  17. if (!(self instanceof Screen)) { 
  18. return new Screen(cid,config) 
  19. config=extend(Screen.Config, config) //configj是extend类的实例 
  20. self.container=getFlag(cid); //窗口对象 
  21. self.ballsnum=config.ballsnum; 
  22. self.diameter=56; //球的直径 
  23. self.radius=self.diameter/2; 
  24. self.spring=config.spring; //球相碰后的反弹力 
  25. self.bounce=config.bounce; //球碰到窗口边界后的反弹力 
  26. self.gravity=config.gravity; //球的重力 
  27. self.balls=[]; //把创建的球置于该数组变量 
  28. self.timer=null//调用函数产生的时间id 
  29. self.L_bound=0; //container的边界 
  30. self.R_bound=self.container.clientWidth; 
  31. self.T_bound=0; 
  32. self.B_bound=self.container.clientHeight; 
  33. }; 
  34. Screen.Config={ //为属性赋初值 
  35. ballsnum:10, 
  36. spring:0.8, 
  37. bounce:-0.9, 
  38. gravity:0.05 
  39. }; 
  40. Screen.prototype={ 
  41. initialize:function () { 
  42. var self=this
  43. self.createBalls(); 
  44. self.timer=setInterval(function (){self.hitBalls()}, 30) 
  45. }, 
  46. createBalls:function () { 
  47. var self=this, num=self.ballsnum; 
  48. var frag=document.createDocumentFragment(); //创建文档碎片,避免多次刷新  
  49. for (i=0;i<num;i++) { 
  50. var ball=new Ball(self.diameter,clss[ Math.floor(Math.random()* num )]); 
  51. ball.diameter=self.diameter; 
  52. ball.radius=self.radius; 
  53. ball.style.left=(Math.random()*self.R_bound)+'px'//球的初始位置, 
  54. ball.style.top=(Math.random()*self.B_bound)+'px'
  55. ball.vx=Math.random() * 6 -3; 
  56. ball.vy=Math.random() * 6 -3; 
  57. frag.appendChild(ball); 
  58. self.balls[i]=ball; 
  59. self.container.appendChild(frag); 
  60. }, 
  61. hitBalls:function () { 
  62. var self=this, num=self.ballsnum,balls=self.balls; 
  63. for (i=0;i<num-1;i++) { 
  64. var ball1=self.balls[i]; 
  65. ball1.x=ball1.offsetLeft+ball1.radius; //小球圆心坐标 
  66. ball1.y=ball1.offsetTop+ball1.radius; 
  67. for (j=i+1;j<num;j++) { 
  68. var ball2=self.balls[j]; 
  69. ball2.x=ball2.offsetLeft+ball2.radius; 
  70. ball2.y=ball2.offsetTop+ball2.radius; 
  71. dx=ball2.x-ball1.x; //两小球圆心距对应的两条直角边 
  72. dy=ball2.y-ball1.y; 
  73. var dist=Math.sqrt(dx*dx + dy*dy); //两直角边求圆心距 
  74. var misDist=ball1.radius+ball2.radius; //圆心距最小值 
  75. if(dist < misDist) {  
  76. //假设碰撞后球会按原方向继续做一定的运动,将其定义为运动A  
  77. var angle=Math.atan2(dy,dx); 
  78. //当刚好相碰,即dist=misDist时,tx=ballb.x, ty=ballb.y 
  79. tx=balla.x+Math.cos(angle) * misDist;  
  80. ty=balla.y+Math.sin(angle) * misDist; 
  81. //产生运动A后,tx > ballb.x, ty > ballb.y,所以用ax、ay记录的是运动A的值 
  82. ax=(tx-ballb.x) * self.spring;  
  83. ay=(ty-ballb.y) * self.spring; 
  84. //一个球减去ax、ay,另一个加上它,则实现反弹 
  85. balla.vx-=ax;  
  86. balla.vy-=ay; 
  87. ballb.vx+=ax; 
  88. ballb.vy+=ay; 
  89. for (i=0;i<num;i++) { 
  90. self.moveBalls(balls[i]); 
  91. }, 
  92. moveBalls:function (ball) { 
  93. var self=this
  94. ball.vy+=self.gravity; 
  95. ball.style.left=(ball.offsetLeft+ball.vx)+'px'
  96. ball.style.top=(ball.offsetTop+ball.vy)+'px'
  97. //判断球与窗口边界相碰,把变量名简化一下 
  98. var L=self.L_bound, R=self.R_bound, T=self.T_bound, B=self.B_bound, BC=self.bounce;  
  99. if (ball.offsetLeft < L) { 
  100. ball.style.left=L; 
  101. ball.vx*=BC; 
  102. else if (ball.offsetLeft + ball.diameter > R) { 
  103. ball.style.left=(R-ball.diameter)+'px'
  104. ball.vx*=BC; 
  105. else if (ball.offsetTop < T) { 
  106. ball.style.top=T; 
  107. ball.vy*=BC; 
  108. if (ball.offsetTop + ball.diameter > B) { 
  109. ball.style.top=(B-ball.diameter)+'px'
  110. ball.vy*=BC; 
  111. window.onload=function() { 
  112. var sc=null
  113. getFlag('start').onclick=function () { 
  114. document.getElementByIdx_x("inner").innerHTML=''
  115. sc=new Screen('inner',{ballsnum:10, spring:0.8, bounce:-0.9, gravity:0.05}); 
  116. sc.initialize(); 
  117. getFlag('stop').onclick=function() { 
  118. clearInterval(sc.timer); 

测试后的效果还是很不错的,各位也许会觉得代码挺长,但是其思路还是蛮清晰的:

首先创建Screen类,并在Screen的构造函数中给出了球移动、碰撞所需的各种属性变量,如ballsnum、spring、bounce、gravity等等

然后用原型prototype给出相应的函数,如创建球,createBalls,球碰撞hitBalls,球移动moveBalls,给每个函数添加相应的功能、

最后用按钮点击事件调用函数,仅此而已。

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选