Показать сообщение отдельно
Старый 26.01.2012, 03:09   #14
LLI.T.A.L.K.E.R.
Мастер
 
Аватар для LLI.T.A.L.K.E.R.
 
Регистрация: 24.06.2009
Адрес: Набережные Челны
Сообщений: 930
Написано 292 полезных сообщений
(для 504 пользователей)
Ответ: Плавное движение по точкам.

;Project : WayPointSystem
;Version : 0.01
;Author : H@non ©

В примере кубик следует по расставленным точкам в пространстве.

Описание функций
AddVayPoint - добавление точки, до которой будет перемещаться ентити.
x#, y#, z# - координаты
radius#=1.0 - радиус точки, то есть как близко должен ентити подлететь к точке, чтобы ее активировать.
state=ST_FLY - состояние точки, типо что делает ентити. Есть ST_FLY - лететь, ST_STAY - ждать...

AddNextVP(handleVP1, handleVP2) - соединить точки. Служит для составления путей, то есть от какой точки к какой лететь. Также возможно установить несколько точек к которым может лететь ентити, тогда будет выбираться рандомно одна из этих точек. Первый параметр это точка к которой соединяют, а второй точка которую присоединяют.

AddEntityToVP(ent, spTurn#.1, spMove# = 0.1) - добавить ентити, который будет следовать по точкам. Там указываеться сам ентити, скорость его поворота, и скорость перемещения.

SetEntityVP(entVP, handleVP) - установить ентити текущую точку. Здесь мы задаем точку, к которой будет перемещаться ентити

GetEntityState(entVP) - возвращает текущее состояние ентити. Щас пока ентити может либо лететь, либо стоять... хотя если он достиг конечной точки, то его статус будет равен нулю.

UpdateVP() - упдейт системы, помещаем в главный цикл


Код:
;=================================
;
Project : WayPointSystem
;Version : 0.01
;Author : H@non ©
;Contact : hanon90@gmail.com
;Visit : http://demon-soul.at.ua
;=================================


Type VayPoint
    Field x
#, y#, z#
    
Field radius#
    
Field state%
    
Field cntVP, nextVP[10]
    
Field mesh
End Type
Const ST_FLY=1, ST_STAY=2

Type EntVP
    Field ent
    Field spTurn
#, spMove#
    
Field curVP
    Field state
    Field timeLeft
End Type

Graphics3D 800
, 600, 32, 2
SetBuffer BackBuffer
()
SeedRnd MilliSecs()

Global 
debug = True
Global debugMesh = CreateCube()
ScaleMesh debugMesh, 0.3, 0.3, 0.3
EntityColor debugMesh
, 0, 255, 0
HideEntity debugMesh

Local vp1 
= AddVayPoint(0, 0, 0)
Local vp2, n
For n = 1 To 5
    vp2 
= AddVayPoint(n*5, Rnd(-5, 0), Rnd(-15, 15))
    
AddNextVP(vp1, vp2)
    
vp1 = AddVayPoint((n+0.5)*5, Rnd(-5, 0), Rnd(-15, 15), 0.1, Rand(1,2))
    
AddNextVP(vp2, vp1)
Next

Local cube 
= CreateCube()
EntityColor cube, 255, 0, 0
Local ent 
= AddEntityToVP(cube)
Local vp.VayPoint = First VayPoint
AddNextVP
(vp1, Handle(vp))
SetEntityVP(ent, Handle(vp))

Local lit = CreateLight()
RotateEntity lit, 45, 45, 0

Local camera 
= CreateCamera()
CameraMove(camera, 0.5)
PositionEntity camera, -3, 3, 0
RotateEntity camera
, 10, -90, 0

While KeyDown(1)=0
    UpdateVP
()
    
CameraMove(camera, 0.5)
    
RenderWorld()
    
Text 10, 10, "entity State: "+GetEntityState(ent)
    
Flip 1
Wend
End

Function CameraMove(cam, sp#=0.1)
    
Local mxs# = MouseXSpeed()*0.5
    
Local mys# = MouseYSpeed()*0.5
    
MoveMouse 400, 300
    RotateEntity cam
, EntityPitch(cam,1)+mys, EntityYaw(cam,1)-mxs, 0, 1
    MoveEntity cam
, (KeyDown(32)-KeyDown(30))*sp, 0, (KeyDown(17)-KeyDown(31))*sp
End 
Function

Function 
AddVayPoint(x#, y#, z#, radius#=1.0, state=ST_FLY)
    
Local VP.VayPoint = New VayPoint
    VP
\x = x
    VP
\y = y
    VP
\z = z
    VP
\radius# = radius
    
VP\state = state
    
If debug = True Then
        VP
\mesh = CopyEntity(debugMesh)
        
PositionEntity VP\mesh, x, y, z
    
EndIf
    
    Return 
Handle(VP)
End Function

Function 
AddNextVP(handleVP1, handleVP2)
    
Local VP1.VayPoint = Object.VayPoint(handleVP1)
    
    
VP1\nextVP[VP1\cntVP] = handleVP2
    VP1
\cntVP = VP1\cntVP + 1
End 
Function

Function 
AddEntityToVP(ent, spTurn#=0.9, spMove# = 0.1)
    
Local e.EntVP = New EntVP
    e
\ent = ent
    e
\spTurn = spTurn
    e
\spMove = spMove
    
    
Return Handle(e)
End Function

Function 
SetEntityVP(entVP, handleVP)
    
Local e.EntVP = Object.EntVP(entVP)
    
e\curVP = handleVP
    Local VP
.VayPoint = Object.VayPoint(e\curVP)
    
e\state = VP\state
End 
Function

Function 
GetEntityState(entVP)
    
Local e.EntVP = Object.EntVP(entVP)
    ;If 
e = Null Then RuntimeError( "VP entity not found" )
    Return 
e\state
End 
Function

Function 
UpdateVP()
    
Local e.EntVP, VP.VayPoint
    Local dx
#, dy#, dz#, pit#, yaw#
    
For e.EntVP = Each EntVP
        
If e\state = ST_FLY Then
            VP
.VayPoint = Object.VayPoint(e\curVP)
            If 
VP <> Null Then
                dx
# = VP\x - EntityX(e\ent,1)
                
dy# = VP\y - EntityY(e\ent,1)
                
dz# = VP\z - EntityZ(e\ent,1)
                
If Abs(dx)<VP\radius And Abs(dy)<VP\radius And Abs(dz)<VP\radius Then
                    Select VP
\state
                        
Case ST_FLY
                            e
\curVP = VP\nextVP[Rand(0,VP\cntVP-1)]
                            
e\state = VP\state
                            
If e\curVP <= 0 Then e\state = 0
                        
Case ST_STAY
                            e
\timeLeft = MilliSecs() + Rand(3,15)*1000
                            e
\state = VP\state
                            e
\curVP = VP\nextVP[Rand(0,VP\cntVP-1)]
                            If 
e\curVP <= 0 Then e\state = 0
                    End Select
                
Else
                    
pit# = VectorPitch(dx, dy, dz)
                    
yaw# = VectorYaw(dx, dy, dz)
                    
pit = MergeAngles#(EntityPitch(e\ent,1),pit,e\spTurn)
                    
yaw = MergeAngles#(EntityYaw(e\ent,1),yaw,e\spTurn)
                    
RotateEntity e\ent, pit, yaw, EntityRoll(e\ent,1)
                    
MoveEntity e\ent, 0, 0, e\spMove
                
EndIf
            Else
                ;
RuntimeError( "Vaypoint not found" )
            EndIf
        ElseIf 
e\state = ST_STAY Then
            
If MilliSecs() > e\timeLeft Then
                e
\state = ST_FLY
            
EndIf
        EndIf
    
Next
End 
Function

;
/////////////////////////////////////////////////////////////
Function MergeAngles#(Angle1#,Angle2#,Morph#=.5)
    
If Abs(Angle1-Angle2)>180
        
If Angle1<Angle2
            
Return Angle1-((360-Angle2)+Angle1)*(.5-(Morph-.5))
        Else
            Return 
Angle2-((360-Angle1)+Angle2)*(.5+(Morph-.5))
        EndIf
    Else
        Return 
Angle1*(Morph)+Angle2*(1.0-Morph)
    EndIf
End Function
;~
IDEal Editor Parameters:
;~
C#Blitz3D 
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
CRASHER (26.01.2012)