主题:请教一个问题?
Zenper
[专家分:0] 发布于 2002-09-11 00:44:00
怎样用VB编写: 一个对象(如:一个球体的图片)在Form里不断的移动,当判断到它移动到Form窗体边缘的时候,让它反弹改变方向(就如一个球在一个四边形方框里碰撞的效果),这个对象移动的座标有公式计算吗?望能提供简单的程序说明?谢谢!
回复列表 (共15个回复)
沙发
bruce_gao [专家分:20] 发布于 2002-09-11 09:34:00
你可以用一个时间控间,控制球的移动效果.如果要有在四壁碰撞的效果你可以写一个函数.就用光的反射定律就可以了.
我想应该不是很难得吧!!~~~~~~~~~
板凳
eerfaone [专家分:490] 发布于 2002-09-11 17:25:00
正如bruce_gao兄所言,控制球的动态移动可以用时间控件,而四壁碰撞的效果的编程,技巧在于设置两个变量:xStep-X轴单位时间位移量,yStep-Y轴单位时间位移量。当与X轴方向的墙壁碰撞时:xStep=xStep,yStep=-yStep;当与Y轴方向的墙壁碰撞时:xStep=-xStep,yStep=yStep。可以参考下面例程:
Option Explicit
Private xStep As Integer
Private yStep As Integer
Private Sub Form_Load()
Randomize
Form1.ScaleMode = vbPixels
xStep = CInt(20 * Rnd())
yStep = CInt(20 * Rnd())
Image1.Left = (Form1.ScaleWidth - Image1.Width) / 2
Image1.Top = (Form1.ScaleHeight - Image1.Height) / 2
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
If Image1.Left <= 0 Or Image1.Left + Image1.Width >= Form1.ScaleWidth Then xStep = -xStep
If Image1.Top <= 0 Or Image1.Top + Image1.Height >= Form1.ScaleHeight Then yStep = -yStep
Image1.Left = Image1.Left + xStep
Image1.Top = Image1.Top + yStep
End Sub
3 楼
蓝色梦幻 [专家分:0] 发布于 2002-09-11 22:49:00
我有个想法
比如,先不断循环,如果说,球的left或者top大于或者小于一定数量的时候,原先的累加器(累减器)变成累减器(累加器),然后再付给球的left或top属性呀
不知道对不对,请教各位大虾!
4 楼
Zenper [专家分:0] 发布于 2002-09-11 23:13:00
先谢谢以上的朋友!
以上的方法我仔细想过~~不明白的只是怎样计算它反弹后的坐标?我需要一个计算公式!
我就是想达到弹砖块游戏里弹子碰撞到障碍后反弹的效果~~
移动图形对象,我将用BitBlt函数在form窗体上绘制,然后跟踪它的移动轨迹~~ 再次谢谢大家!
5 楼
eerfaone [专家分:490] 发布于 2002-09-12 14:15:00
致蓝色梦幻小妹妹:
你的想法也行,实际上我上面的程序跟你的想法类似,只不过将普通循环改为用TIMER事件循环。
致Zenper兄:
事实上,球移动过程遇到障碍发生碰撞效果的实现遵循的假设是:
1、球移动过程保持速度和方向不变;
2、遇到障碍发生碰撞时保持速度不变,而方向由折射定律求出。
因此,球在整个过程中运动的速度都不变,保持初始值,如果我们通过TIMER控制其移动,则TIMER事件的时间间隔一定,其运动的速度就转化为每个TIMER时间间隔运动的距离,将这个距离投影在X轴和Y轴,就转化为X轴位移量xStep和Y轴位移量yStep(可正可负),也就是蓝色梦幻小妹妹说的累加器(累减器),每个TIMER事件发生时球的坐标由上一个坐标加上位移量就实现了球的移动。故通过X轴位移量xStep和Y轴位移量yStep可控制球的移动速度和方向。
至于碰撞,设碰撞点障碍面与X轴夹角为alfa,则碰撞后的速度和方向为
xStep = xStep * cos( 2 * alfa ) + yStep * sin( 2 * alfa )
yStep = xStep * sin( 2 * alfa ) - yStep * cos( 2 * alfa )
特例:
当与X轴方向的障碍面碰撞,即alfa=0时:xStep = xStep:yStep = - yStep
当与X轴方向的障碍面碰撞,即alfa=90时:xStep = - xStep:yStep = yStep
所以整个TIMER事件的算法为:
Private Sub Timer1_Timer()
If 碰到障碍 then
xStep = xStep * cos( 2 * alfa ) + yStep * sin( 2 * alfa )
yStep = xStep * sin( 2 * alfa ) - yStep * cos( 2 * alfa )
End If
球的X坐标 = 球的X坐标 + xStep
球的Y坐标 = 球的Y坐标 + yStep
End Sub
最后想请教Zenper兄如何跟踪球的移动轨迹?谢谢
6 楼
蓝色梦幻 [专家分:0] 发布于 2002-09-12 22:15:00
但是用timer属性就没得结束啦~
难道Enabled= False ???
7 楼
Zenper [专家分:0] 发布于 2002-09-12 23:25:00
非常感谢eerfaone和蓝色梦幻两位朋友给我提供的帮助~~我问的问题实际上跟我想做的一款游戏有关系~~(谁让我以前数学没学好~~呜呜...)
我原也想过用TIMER控件来跟踪对象的移动轨迹~~但是觉得TIMER控件的弊端较多~~ 可视化的面对对象的编程固然方便、高效和快捷,同时也会束缚我们的思路,我现在尝试试验用按顺序执行代码,采用查询的方法来跟踪它的移动轨迹~~ 等我试验后才能告诉你结果!再一次感谢二位的帮助!
8 楼
蓝色梦幻 [专家分:0] 发布于 2002-09-13 06:12:00
是不是弹球的?
9 楼
eerfaone [专家分:490] 发布于 2002-09-13 12:23:00
我翘目以待!祝你早日成功!
10 楼
Zenper [专家分:0] 发布于 2002-09-15 22:43:00
谢谢大家了~~ 是一个LINEGIRL类似的游戏~~
我也不知道成功的希望有多大??? 尽力做吧?
我来回复