Page 1 sur 1

RayCollide() : Détection d'une entité physique dans un rayon

Publié : sam. 18/nov./2017 23:09
par falsam
la fonction RayCollide() crée un rayon entre deux points et vérifie si une entité physique (avec un corps body) croise ce rayon.

Pour illustrer cette fonctionnalité, Je vous propose un code avec comme objectif.
- Bouger le cube avec les flèches gauche et droite du curseur.
- Descendre quatre plateformes en partant sur la droite.
- Arrivée sur la dernière plateforme, une impulsion vous renverra le cube sur la première plateforme.

Code : Tout sélectionner

;RayCollide


EnableExplicit

;Scene
Global Camera, Light

;Summary
Declare GameLoad()
Declare RenderGame3D()
Declare RenderGame2D() 
Declare Exit()

GameLoad()

Procedure GameLoad()
  Protected Window 
  
  If InitEngine3D() And  InitKeyboard() And InitSprite() And InitMouse() And InitSound()
    Window = OpenWindow(#PB_Any, 0, 0, 0, 0, "", #PB_Window_Maximize | #PB_Window_BorderLess)
    SetWindowColor(Window, 0)
    
    ;-[Screen]
    OpenWindowedScreen(WindowID(Window),0, 0, WindowWidth(Window) , WindowHeight(Window))    
    KeyboardMode(#PB_Keyboard_International)  
        
    ;-[3D]
    Add3DArchive(#PB_Compiler_Home + "Examples\3D\Data\Textures", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Packs/waterworld.zip", #PB_3DArchive_Zip)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
    
    SkyBox("desert07.jpg")
    
    ;-Camera
    CreateCamera(0, 0, 0, 100, 100)
    CameraBackColor(0, RGB(0, 0, 0))

    ; Light
    CreateLight(#PB_Any, RGB(151, 251, 151), -200, 100, -500)
    WorldShadows(#PB_Shadow_Additive)
    
    ; Materials
    CreateMaterial(0, TextureID(LoadTexture(-1, "Dirt.jpg")))
    ScaleMaterial(0, 0.2, 0.2)
    CreateMaterial(1, TextureID(LoadTexture(-1, "Floor02.jpg")))
    
    ; Platform
    CreateCube(0, 10)
    
    CreateEntity(1, MeshID(0), MaterialID(0), 0, 10, 0)
    CreateEntityBody(1, #PB_Entity_StaticBody)
    
    CreateEntity(2, MeshID(0), MaterialID(0), 5, 0, 0)
    CreateEntityBody(2, #PB_Entity_StaticBody)
    
    CreateEntity(3, MeshID(0), MaterialID(0), 10, -10, 0)
    CreateEntityBody(3, #PB_Entity_StaticBody)
    
    CreateEntity(4, MeshID(0), MaterialID(0), 15, -20, 0)
    CreateEntityBody(4, #PB_Entity_StaticBody)
    
    ;Player 
    CreateEntity(5, MeshID(CreateCube(-1, 1)), MaterialID(1), 0, 20, 0)
    CreateEntityBody(5, #PB_Entity_BoxBody, 1, 0.5, 0.5) 
    EntityAngularFactor(5, 0, 90, 0)   
    
    ;-Loop
    While #True
      Repeat : Until WindowEvent() = 0
      FlipBuffers()  
      RenderGame3D()
      RenderWorld()
    Wend
  Else
    
  EndIf 
EndProcedure

Procedure RenderGame3D()    
  Protected Target, Speed.f, x1.f, y1.f, z1.f, x2.f, y2.f, z2.f   
  
  If ExamineKeyboard()  
    If KeyboardReleased(#PB_Key_Escape)
      Exit()
    EndIf    
    If KeyboardPushed(#PB_Key_Right)
      Speed = 2
    ElseIf KeyboardPushed(#PB_Key_Left)
      Speed = -2
    Else
      Speed = 0
    EndIf    
  EndIf
  
  CameraFollow(0, EntityID(5), 0, EntityY(5) + 1.5, 20, 0.1, 0.1)
  
  ;RayCollide : Casts a ray between the first point and the second point, and checks if an entity is colliding the ray. 
  x1 = EntityX(5)
  y1 = EntityY(5) - 0.4
  z1 = EntityZ(5)
  x2 = x1
  y2 = y1 - 0.2
  z2 = z1  
  Target = RayCollide(x1, y1, z1, x2, y2, z2)
  
  ;We reached the last platform (Entity 4).
  If Target = 4 
    Target = -1
    ;An impulse To reach the first platform
    ApplyEntityImpulse(5, -4, 42, 0)
    
  ;An entity crosses the ray  
  ElseIf Target <> -1    
    MoveEntity(5, Speed, 0, 0, #PB_Absolute|#PB_Local)   
  EndIf     
EndProcedure

Procedure Exit()
  End
EndProcedure
Remarque : Parfois l'impulsion renvoie le cube trop haut.

Re: RayCollide() : Détection d'une entité physique dans un r

Publié : sam. 18/nov./2017 23:39
par venom
:P Super, chez moi ça fonctionne niquel. Merci pour ce "petit" code très efficace.






@++