主题:  带碰撞的随机运动!!!

特立独行

职务:普通成员
等级:1
金币:1.0
发贴:263
#12002/11/11 17:31:28
下面是一位高手写的物体随机运动的行为代码,非常好用,如果我要让物体碰到舞台的四条边时,出现反弹的碰撞效果,该如何实现?
property oldLoc -- 前一次移动的最终位置
property nowTime -- 当前移动已经过的帧数
property subLocX -- 新旧位置的距离差
property myDirection -- 移动方向,1:水平,2:垂直
property changeTime -- 完成一次移动所需要经过的帧数
property minLocX -- 根据精灵最小边界计算出精灵的最小横/纵坐标
property maxLocX -- 根据精灵最大边界计算出精灵的最大横/纵坐标
property V0 -- 精灵的初始速度,仅当useAccelerate=false时有效
property A -- 根据accelerate换算后精灵的加速度
property moveDirection -- 移动方向,包括水平和垂直方向可以进行选择
property minEdge -- 精灵移动的最小边界,精灵移动时左边界或上边界的数值(水平为左边界数值,垂直为上边界数值)
property maxEdge -- 精灵移动的最大边界,精灵移动时右边界或下边界的数值(请确认最大边界比最小边界至少大 精灵的宽度或高度+30 以保证效果)
property speed -- 移动速度,数值越大,移动速度越快
property useAccelerate -- 是否使用加速度,true为使用,false为不使用
property accelerate -- 加速度

on getPropertyDescriptionList me
zxList = [:]
stageWidth = the stageRight - the stageLeft
zxList[#moveDirection] = [#comment:"移动方向", #format:#string, #range:["水平", "垂直"], #default:"水平"]
zxList[#minEdge] = [#comment:"精灵移动的最小边界(左边界或上边界)", #format:#integer, #default:0]
zxList[#maxEdge] = [#comment:"精灵移动的最大边界(右边界或下边界)", #format:#integer, #default:30]
zxList[#speed] = [#comment:"移动速度", #format:#integer, #range:[#min:1,#max:10], #default:1]
zxList[#useAccelerate] = [#comment:"是否使用加速度", #format:#boolean, #default:false]
zxList[#accelerate] = [#comment:"加速度:", #format:#integer, #range:[#min:1, #max:500], #default:1]
return zxList
end

on getBehaviorDescription
t=t&return&" 精灵的随机运动 "
t=t&return&" 设置精灵在舞台上做指定区域内的随机运动"
t=t&return&""
t=t&return&" 使用说明:"
t=t&return&" 将行为拖曳到一个精灵上,选择精灵做随机运动所沿的方向(水平或垂直)"
t=t&return&" 设定精灵移动时左边界或上边界的数值,和右边界或下边界的数值(注意最大边界比最小边界至少大 \
精灵的宽度或高度(根据运动方向而定)+30,否则会发生错误)"
t=t&return&" 然后设置精灵随机移动的移动速度,数值越大,移动速度越快"
t=t&return&" 最后可以设置精灵在做随机运动时是否使用加速度,true为使用,false为不使用"
t=t&return&" 使用加速度的时候,下面的加速度里设定的加速度值将有效,加速度值越大,加、减速的效果越明显"
return t
end getBehaviorDescription

on getbehaviortooltip
t=t&return&" 精灵的随机运动 "
t=t&return&" 设置精灵在舞台上做指定区域内的随机运动"
t=t&return&""
t=t&return&" 使用说明:"
t=t&return&" 将行为拖曳到一个精灵上,选择精灵做随机运动所沿的方向(水平或垂直)"
t=t&return&" 设定精灵移动时左边界或上边界的数值,和右边界或下边界的数值(注意最大边界比最小边界至少大 \
精灵的宽度或高度(根据运动方向而定)+30,否则会发生错误)"
t=t&return&" 然后设置精灵随机移动的移动速度,数值越大,移动速度越快"
t=t&return&" 最后可以设置精灵在做随机运动时是否使用加速度,true为使用,false为不使用"
t=t&return&" 使用加速度的时候,下面的加速度里设定的加速度值将有效,加速度值越大,加、减速的效果越明显"
return t
end

--------------------------------------------------------------------------------------

on beginSprite me
-- 将获得的speed数值换算成完成一次移动所需帧数
changeTime = (11- speed) * 10
myRect = [sprite(me.spriteNum).width, sprite(me.spriteNum).height]
-- 将移动方向换算为整形变量,用以获得横或纵坐标值。myDirection ---- 1:水平, 2:垂直
if moveDirection = "水平" then
myDirection = 1
else if moveDirection = "垂直" then
myDirection = 2
end if
-- 如果最大边界减最小边界 小于 精灵的宽或高+30,将给出提示信息并停止程序
if (maxEdge - minEdge) < (myRect[myDirection] + 30) then
alert "请确认最大边界比最小边界至少大"&(myRect[myDirection]+30)
halt
end if
-- 根据最小边界和精灵的member本身的注册点,确定最小坐标位置
if (the desktoprectlist)[1]=rect(0,0,1024,768) then
minLocX = minEdge + sprite(me.spriteNum).member.regPoint[myDirection]
-- 根据最大边界和精灵的member本身的注册点,确定最大坐标位置
maxLocX = maxEdge - myRect[myDirection] + sprite(me.spriteNum).member.regPoint[myDirection]
end if
if (the desktoprectlist)[1]=rect(0,0,800,600) then
minLocX = (minEdge + sprite(me.spriteNum).member.regPoint[myDirection])*0.9

maxLocX = (maxEdge - myRect[myDirection] + sprite(me.spriteNum).member.regPoint[myDirection])*0.9
end if
-- 初始化一些其他的变量
init me
end

on exitFrame me
if nowTime < changeTime then
-- 分别计算水平/垂直的移动
if moveDirection = "水平" then
-- 当nowTime < (changeTime/2) 时为加速过程, 否则为减速过程
if nowTime < (changeTime/2) then
-- 加速过程计算
sprite(me.spriteNum).locH = oldLoc.locH + nowTime * V0 + A * nowTime * nowtime / 2 * accelerate
else
-- 减速过程计算
sprite(me.spriteNum).locH = oldLoc.locH + nowTime * V0 + subLocX * useAccelerate\
- A * (changeTime-nowTime) * (changeTime-nowTime) / 2 * accelerate
end if
else if moveDirection = "垂直" then
-- 当nowTime < (changeTime/2) 时为加速过程, 否则为减速过程
if nowTime < (changeTime/2) then
-- 加速过程计算
sprite(me.spriteNum).locV = oldLoc.locV + nowTime * V0 + A * nowTime * nowtime / 2 * accelerate
else
-- 减速过程计算
sprite(me.spriteNum).locV = oldLoc.locV + nowTime * V0 + subLocX * useAccelerate\
- A * (changeTime-nowTime) * (changeTime-nowTime) / 2 * accelerate
end if
end if
nowTime = nowTime + 1
else
-- 本次移动结束,重新初始化
init me
end if
end

on init me
-- 记录前一次移动的位置
oldLoc = sprite(me.spriteNum).loc
-- 随机取得一个新的位置
newLocX = minLocX + random(maxLocX - minLocX)
--为了保证效果,不允许新旧两点之间的位置差<15,重复获得新的位置直到新旧两点之间的位置差>=15
repeat while abs(newLocX - oldLoc[myDirection]) < 15
newLocX = minLocX + random(maxLocX - minLocX)
end repeat
-- 将新旧位置差赋值给subLocX,方便其他变量的计算
subLocX = (newLocX - oldLoc[myDirection])
-- 初始速度,仅当无加速度时有效,有加速度时初始速度为0,使用not useAccelerate完成这个功能
V0 = subLocX / float(changeTime) * (not useAccelerate)
-- 加速度,按位置差半程计算加速度,当无加速度的时候,A = 0
A = subLocX / float(changeTime*changeTime) * 4 * useAccelerate / accelerate
nowTime = 1
end




特立独行

职务:普通成员
等级:1
金币:1.0
发贴:263
#22002/11/11 19:45:15
作者名叫张歆,谁有他的联系方式,qq,e-mail,msn均可?



草原风

职务:版主
等级:5
金币:13.0
发贴:3489
#32002/11/12 13:48:25
d8开发使用手册 上有关于撞到边的问题的答案,你可以 看看



特立独行

职务:普通成员
等级:1
金币:1.0
发贴:263
#42002/11/12 15:15:21
草原风在上个帖子中说
引用:
d8开发使用手册 上有关于撞到边的问题的答案,你可以 看看

那个我知道,它只是针对匀速运动的物体,我想知道的是变速运动的碰撞方法。