Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 729|回复: 0

小球在边框内随机碰撞运动过程

[复制链接]

该用户从未签到

发表于 2011-10-29 08:17:39 | 显示全部楼层 |阅读模式
面向对象的分析与设计:
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.假设小球不是水平或垂直运动,而是向任意方向运动的话,这个距离如何计算?
在面板中的坐标系,横轴是向右,纵轴是向下,原点在面板的左上角。这一点跟我们在中学数学中学习到的坐标系不同。在图中我以小球为中心原点,建立的这个坐标系,主要为了便于分析小球的运动过程,方便推理和计算。
另外,面板中只能进行横向运动和纵向运动,要产生斜向运动,必须将横向运动和纵向运动进行合成。
看图1:

在t1-t0的时间段内,小球向右上角运动一个speed的距离,这个运动过程无法直接在程序中表达,只能由横向运动和纵向运动合成而来。根据我们定义的小球的运动方向的概念,分别得到横向运动距离dx和纵向运动距离dy.在这个时间段内,只需要将小球的横坐标x加上这个dx,纵坐标减去这个dy,得到的新的坐标点,就是小球应该到达的位置。
注意这个时候alpha的值处于第一象限,根据正弦函数和余弦函数的图像可知,此时sina和cosa的值都为正数,即:
x+=dx;
y-=dy
之后,小球的位置正好处于原来位置的右上角,到达了既定位置.

看图2(上图中):
在第二象限内,根据正弦函数和余弦函数的图像,这次sina的值依然是正数,cosa的值却是一个负数,在:
x+=dx;
y-=dy
之后,小球也还是能正确运动到达正确位置。

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

3.边界碰撞检测:
根据光的反射定律,光的入射角等于反射角。在这里,将小球看成是一个光子,四周的边界看成是绝对光滑的镜面,那么小球对边界的碰撞也遵从反射定律。
看图3:
如果碰撞上边框,小球反射前的运动方向alpha在碰撞到边框的一瞬间,立即变成反射后的运动方向,才能让小球正确呈现反弹效果。即让反弹后的运动方向值,替代反射前的运动方向值,如果运动分析没有错,那么,小球的碰撞和反弹也会按照预期正确出现。画出法线,经过简单的几何证明:

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

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

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

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

如果边框宽600pix,高400pix,小球宽高都为20pix的话,核心代码为:
java code
public void 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)毫秒,不要约分,否则就失去了这个数值所表达的意义了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2024-5-4 09:49 , Processed in 0.415382 second(s), 47 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表