实现小球随机碰撞,最好分析

其实用flash actionscript实现地更快更好...

这个程序很锻炼新手能力哦~

面向对象的分析与设计:
1.把小球看成是一个对象,且自身就是一个线程,能控制自身的运动。

设计具有以下属性和(行为)方法,
属性:
  x:横坐标
  y:纵坐标
  speed:小球运动的直线速度
  alpha:小球运动的方向。记为小球运动方向和12点钟的顺时针的夹角
   

方法:
  move():根据小球当前的属性值来运动
  run():控制小球运动的线程

2.运动的分析:
设在某一时刻t0,小球处于屏幕中任意一点,即其位置为x和y,如果小球是

水平或垂直运动的话,那么在下一时刻t1,只需将小球的横或纵坐标加或减

一个值,并将这个加后或减后的值重新作为小球的x,y就能实现小球位置的

变化,只要t1-t0足够小,运动就能产生。
但这里有两个问题:
a:小球的坐标要加或减的值是多少?
这个值是t1-t0的一段时间,小球移动的一段距离,这个距离值实际上就是

小球的速度值,即speed,单位是pixel/(1/36)s,叫做"像素每36分之一秒"

,为什么是36分之一秒内移动speed个像素?因为这样一来,1秒钟就能显

示36幅小球在不同位置的画面,根据电影原理,人眼在每秒看到36幅画面

时,感觉最为流畅。

b.假设小球不是水平或垂直运动,而是向任意方向运动的话,这个距离如何

计算?
在面板中的坐标系,横轴是向右,纵轴是向下,原点在面板的左上角。这一

点跟我们在中学数学中学习到的坐标系不同。在图中我以小球为中心原点,

建立的这个坐标系,主要为了便于分析小球的运动过程,方便推理和计算。
另外,面板中只能进行横向运动和纵向运动,要产生斜向运动,必须将横向

运动和纵向运动进行合成。


在t1-t0的时间段内,小球向右上角运动一个speed的距离,这个运动过程

无法直接在程序中表达,只能由横向运动和纵向运动合成而来。根据我们定

义的小球的运动方向的概念,分别得到横向运动距离dx和纵向运动距离dy.

在这个时间段内,只需要将小球的横坐标x加上这个dx,纵坐标减去这个dy,

得到的新的坐标点,就是小球应该到达的位置。
注意这个时候alpha的值处于第一象限,根据正弦函数和余弦函数的图像可

知,此时sina和cosa的值都为正数,即:
x+=dx;
y-=dy
之后,小球的位置正好处于原来位置的右上角,到达了既定位置.

在第二象限内,根据正弦函数和余弦函数的图像,这次sina的值依然是正

数,cosa的值却是一个负数,在:
x+=dx;
y-=dy
之后,小球也还是能正确运动到达正确位置。

按照此种方式继续分析第三象限和第四象限的情况可知,方程组:
x+=speed*sina;
y-=speed*cosa;
是小球运动的一般规律,而水平和垂直方向的运动,也是这个方程组描述的

一种特殊情况.

3.边界碰撞检测:
根据光的反射定律,光的入射角等于反射角。在这里,将小球看成是一个光

子,四周的边界看成是绝对光滑的镜面,那么小球对边界的碰撞也遵从反射

定律。
看图:


如果碰撞上边框,小球反射前的运动方向alpha在碰撞到边框的一瞬间,立即变成反射后的运动方向,才能让小球正确呈现反弹效果。即让反弹后的运动方向值,替代反射前的运动方向值,如果运动分析没有错,那么,小球的碰撞和反弹也会按照预期正确出现。画出法线,经过简单的几何证明:

反射后的方向=180-反射前的方向,即对应的代码应该为:
alpha=180-alpha;(简单的不可思议!)

如果按照相反的方向入射和反射,或者碰撞到下边框,依然遵从该方程!你可以自己试着推理证明。

这次是碰撞左边框,经过一番简单的证明,得到结论是:
反射后的角度=360-反射前的角度,即对应的代码应该为:
alpha=360-alpha;(同样简单的不可思议!)

你也可以画图证明碰撞右边框的情形,也同样遵照上述方程。

如果边框宽600pix,高400pix,小球宽高都为20pix的话,核心代码为:

Java code

publicvoid move(){ x+=speed*Math.sin(alpha*Math.PI/180); y-=speed*Math.cos(alpha*Math.PI/180);if(x<0||x>580)alpha=360-alpha;if(y<0||y>480)alpha=180-alpha; setLocation(x,y); }


在线程体中使用死循环反复调用move()方法,线程的休眠间隔是(1000/36)毫秒,不要约分,否则就失去了这个数值所表达的意义了。




原文地址:https://www.cnblogs.com/xieyuan/p/3787450.html