关于3D游戏中碰撞的问题,请教高手!!!!!

jsxzthf 2003-06-22 07:32:00
小弟最近看一个3d游戏中的碰撞,希望哪位大虾告诉小弟这是使用的什么算法。
Private Function GameKeyboard(yLookDir As D3DVECTOR) As Boolean
Dim KeybState As DIKEYBOARDSTATE
Dim yWalkDir As D3DVECTOR, yPosBef As D3DVECTOR, yCollDet As D3DVECTOR
Dim RotAngle!, cntEnable%

Mk3d.diDeviceKeyb.GetDeviceStateKeyboard KeybState
If Not KeybState.Key(1) = 0 Then
'ESC, go to the menu
Do
DoEvents
Mk3d.diDeviceKeyb.GetDeviceStateKeyboard KeybState
Loop While Not KeybState.Key(1) = 0 'wait until ESC is no longer pressed
GameKeyboard = True
Exit Function
End If
RotAngle = GetMoveAngle(KeybState)
If Not RotAngle = -1 Then
yWalkDir = yLookDir
yWalkDir.y = 0
Mk3d.dx.VectorNormalize yWalkDir
yWalkDir = Mk3d.VectorRotate(yWalkDir, Mk3d.VectorMake(0, RotAngle, 0))
Mk3d.dx.VectorScale yWalkDir, yWalkDir, WalkSpeed * FrameT

'碰撞检测
yPosBef = yPos
Mk3d.dx.VectorAdd yPos, yPos, yWalkDir
yCollDet = GetCollDet(yPosBef, yPos, 2, False, True)
If yCollDet.x = 0 Then
yWalkDir.x = 0
yPos = yPosBef
cntEnable = cntEnable + 1
End If
If yCollDet.z = 0 Then
yWalkDir.z = 0
yPos = yPosBef
cntEnable = cntEnable + 1
End If
If cntEnable = 1 Then
'only if of the two values is zero. if both are zero, you can't walk in ANY direction
Mk3d.dx.VectorNormalize yWalkDir
Mk3d.dx.VectorScale yWalkDir, yWalkDir, WalkSpeed * FrameT
Mk3d.dx.VectorAdd yPos, yPos, yWalkDir
End If
Mk3d.dx.VectorAdd yEyes, yEyes, yWalkDir
If Not cntEnable = 2 Then
'start playing the walk sound
dsWalkSound.Play DSBPLAY_LOOPING
Else
'stop playing the walk sound
dsWalkSound.Stop
dsWalkSound.SetCurrentPosition 0
End If

'move also MG
If Not MGHoldingState = MG_NONE Then
Mk3d.dx.VectorAdd MGHoldingPos, MGHoldingPos, yWalkDir
MGHolding.MoveTo MGHoldingPos
End If
Else
'stop playing the walk sound
dsWalkSound.Stop
dsWalkSound.SetCurrentPosition 0
End If
End Function


Private Sub GameMouse()
Dim MouseState As DIMOUSESTATE, yRot As D3DVECTOR

Mk3d.diDeviceMouse.GetDeviceStateMouse MouseState
yRot.x = MouseState.y * 6.283 / PixelPer360
yRot.y = MouseState.x * 6.283 / PixelPer360
yAngle.x = yAngle.x - yRot.x
yAngle.y = yAngle.y - yRot.y
If yAngle.x > 1 Then yAngle.x = 1
If yAngle.x < -1 Then yAngle.x = -1
If yAngle.y > 6.283 Then yAngle.y = yAngle.y - 6.283
If yAngle.y < 0 Then yAngle.y = yAngle.y + 6.283

If MGHoldingState = MG_NORMAL Or MGHoldingState = MG_FIRE Then
If Not MouseState.buttons(0) = 0 And MGHoldingState = MG_NORMAL Then
MGHoldingState = MG_FIRE
'start playing the MG sound
dsShootSound.SetCurrentPosition 0
dsShootSound.Play DSBPLAY_LOOPING
ElseIf MouseState.buttons(0) = 0 Then
MGHoldingState = MG_NORMAL
Mk3d.LightSetState MGHoldingLightIndex, False
yEyes.y = EyesHeight
'stop playing the MG sound
dsShootSound.Stop
End If
End If
End Sub
...全文
24 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jsxzthf 2003-06-23
  • 打赏
  • 举报
回复
非常感谢各位大虾帮助小弟,下面是getcolldet,请大虾指教
谢谢~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Function GetCollDet(ActPos As D3DVECTOR, NewPos As D3DVECTOR, ByVal MaxDiff As Single, ByVal CheckYou As Boolean, ByVal CheckMan As Boolean) As D3DVECTOR
Dim i%, Diff As D3DVECTOR, ChPosX As D3DVECTOR, ChPosZ As D3DVECTOR


GetCollDet = Mk3d.VectorMake(1, 1, 1)


If NewPos.X < MapArea(0, 0) + MaxDiff Or NewPos.X > MapArea(0, 1) - MaxDiff Then
GetCollDet.X = 0
End If
If NewPos.z < MapArea(1, 0) + MaxDiff Or NewPos.z > MapArea(1, 1) - MaxDiff Then
GetCollDet.z = 0
End If
If GetCollDet.X = 0 And GetCollDet.z = 0 Then Exit Function


Mk3d.dx.VectorSubtract Diff, NewPos, ActPos
ChPosX = ActPos
ChPosX.X = ChPosX.X + Diff.X
ChPosZ = ActPos
ChPosZ.z = ChPosZ.z + Diff.z
For i = 0 To CollDetCount - 1
If InArea(NewPos, CollDet(i), MaxDiff) Then
If Not GetCollDet.X = 0 Then
If InArea(ChPosX, CollDet(i), MaxDiff) Then GetCollDet.X = 0
End If
If Not GetCollDet.z = 0 Then
If InArea(ChPosZ, CollDet(i), MaxDiff) Then GetCollDet.z = 0
End If
If GetCollDet.X = 0 And GetCollDet.z = 0 Then Exit Function
End If
Next i

If CheckYou Then
If InArea(ChPosX, yPos, MaxDiff) Then GetCollDet.X = 0
If InArea(ChPosZ, yPos, MaxDiff) Then GetCollDet.z = 0
End If
If GetCollDet.X = 0 And GetCollDet.z = 0 Then Exit Function


If CheckMan And Not ManState = MAN_BLENDOUT Then
If InArea(ChPosX, ManPos, MaxDiff) Then GetCollDet.X = 0
If InArea(ChPosZ, ManPos, MaxDiff) Then GetCollDet.z = 0
End If
End Function

Private Function GetPatronCollDet(PatronPos As D3DVECTOR, ByVal MaxDiff As Single) As MGPatronHitEnum
Dim i%
Dim HitNow As Boolean

If InArea(PatronPos, Mk3d.VectorMake(3.5, 0, 12.5), 1) And Not HitSpecialW(0) Then

HitSpecialW(0) = True
HitNow = True
End If
If InArea(PatronPos, Mk3d.VectorMake(3.5, 0, 57.5), 1) And Not HitSpecialW(1) Then

HitSpecialW(1) = True
HitNow = True
End If
If HitSpecialW(0) And HitSpecialW(1) And HitNow And ActPlayT < 10 Then
GamePoints = GamePoints + 100
TextBlendWaitT = 0
ShowText = True
TextToShow = "WINDOW SPECIAL: + 100"
End If

If InArea(PatronPos, ManPos, MaxDiff) And PatronPos.y < 3 Then
GetPatronCollDet = MGPATRON_HITMAN
Exit Function
End If
If PatronPos.X < MapArea(0, 0) Or PatronPos.X > MapArea(0, 1) Or PatronPos.y < 0 Or PatronPos.y > 3 Or PatronPos.z < MapArea(1, 0) Or PatronPos.z > MapArea(1, 1) Then
GetPatronCollDet = MGPATRON_HITLANDSCAPE
Exit Function
End If
For i = 0 To CollDetCount - 1
If InArea(PatronPos, CollDet(i), MaxDiff) And PatronPos.y < 6 Then
GetPatronCollDet = MGPATRON_HITLANDSCAPE
Exit Function
End If
Next i
GetPatronCollDet = MGPATRON_HITNOTHING
End Function
fastbit 2003-06-23
  • 打赏
  • 举报
回复
你给的程序是一个处理输入的子程序,没有算法部分。YangLin1ST说的GetCollDet里面的代码确实才包含碰撞检测。
fastbit 2003-06-23
  • 打赏
  • 举报
回复
MapArea函数和InArea函数请继续贴出,

发到我的email里面也行:fastbit@163.com
YangLin1ST 2003-06-22
  • 打赏
  • 举报
回复
看起来象是一个在平面上移动的问题,当碰到不同的物体的表面的时候,就计算改变移动的方向,这样可以沿着物体的表面滑动。
可不可以多帖点出来,比如那个GetCollDet,不知道是干什么的,只好瞎猜了

8,303

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧