Le nid du Jenga - La tour infernale

Généralités sur la programmation 3D
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Le nid du Jenga - La tour infernale

Message par Le Soldat Inconnu »

Avec l'explication, c'est mieux :)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Le nid du Jenga - La tour infernale

Message par djes »

G-Rom, tu pourrais regarder ? Quand je veux poser une nouvelle brique, parfois la collision fonctionne, parfois non (ça aide à pousser un peu les autres briques). C'est totalement aléatoire... :/

Code : Tout sélectionner

;*********************************
; Jenga's Nest
; by djes (djes@free.fr)
; 04/25/11 : First release
; 03/05/11 : Code update
; Thanks to new PB 4.6 3D commands
; Feel free to enhance !

Enumeration 
  #GROUND
  #VIRTUALPIECE
  #TILEPL1MAT
  #TILEPL2MAT
EndEnumeration
;Need to be at the last position
Enumeration #PB_Compiler_EnumerationValue
  #TILE
EndEnumeration

; Window size
#SCREENWIDTH = 600
#SCREENHEIGHT = 600

Structure Piece
  EntityNB.i
  x.d
  y.d
  z.d
  Yaw.d
EndStructure

Global NewList Pieces.Piece()
Global InGame = #True

Procedure CreatePiece(u, mat, x.d, y.d, z.d, Yaw.d)
  CreateEntity(#TILE + u, MeshID(#TILE), MaterialID(mat))
  ScaleEntity(#TILE + u, 9, 1.485, 3)
  EntityLocate(#TILE + u, x, y, z)
  RotateEntity(#TILE + u, 0, Yaw, 0)
  EntityPhysicBody(#TILE + u, #PB_Entity_BoxBody, 250, 0, 2)
  AddElement(Pieces())
  Pieces()\EntityNb = #TILE + u
  ;   Pieces()\x = x
  ;   Pieces()\y = y
  ;   Pieces()\z = z
  ;   Pieces()\Yaw = Yaw
EndProcedure

Procedure TheEnd(msg.s)
  EntityLocate(#VIRTUALPIECE, 200, 200, 0)
  EntityPhysicBody(#VIRTUALPIECE, #PB_Entity_None, 250, 0, 2)   
  ReleaseMouse(#True)
  MessageRequester("Infos", Msg)
  InGame = #False  
EndProcedure

;- Initialization
InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()

;- Window
OpenWindow(0, 0, 0, #SCREENWIDTH, #SCREENHEIGHT, "Jenga's Nest by djes (http://djes.free.fr)", #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget)
OpenWindowedScreen(WindowID(0), 0, 0, #SCREENWIDTH,#SCREENHEIGHT, 0, 0, 0,#PB_Screen_SmartSynchronization)

EnableWorldPhysics(#True)
EnableWorldCollisions(#True)

;-Textures
CreateTexture(0, 128, 128) 
StartDrawing(TextureOutput(0)) 
Box(0, 0, 128, 128, $FFFFFF)
StopDrawing()

;-Material
CreateMaterial(#GROUND, TextureID(0))
MaterialAmbientColor(#GROUND, RGB($FF, $FF, $FF))
CreateMaterial(#TILEPL1MAT, TextureID(0))
MaterialAmbientColor(#TILEPL1MAT, RGB(0, $FF, $55))
CreateMaterial(#TILEPL2MAT, TextureID(0))
MaterialAmbientColor(#TILEPL2MAT, RGB($FF, $55, 0))
CreateMaterial(#VIRTUALPIECE, TextureID(0))
MaterialAmbientColor(#VIRTUALPIECE, RGB(0, 0, $FF))
MaterialBlendingMode(#VIRTUALPIECE, #PB_Material_Add)
CreateMaterial(#GROUND, TextureID(0))
MaterialAmbientColor(#GROUND, RGB($FF, $FF, $FF))

;- Meshes
CreateCube(#GROUND, 1)
CreateCube(#TILE, 1)

;- Entities
CreateEntity(#GROUND, MeshID(#GROUND), MaterialID(#GROUND))
ScaleEntity(#GROUND, 20, 1, 20)
EntityLocate(#GROUND, 0, -0.5, 0)
EntityPhysicBody(#GROUND, #PB_Entity_StaticBody, 250, 0, 2)   

CreateEntity(#VIRTUALPIECE, MeshID(#TILE), MaterialID(#VIRTUALPIECE))
ScaleEntity(#VIRTUALPIECE, 9, 1.485, 3)
EntityPhysicBody(#VIRTUALPIECE, #PB_Entity_BoxBody, 250, 0, 2)   

;- Camera
CreateCamera(0, 0, 0, 100, 100)
CameraLocate(0, -30, 1.485 * 20, -30)
CameraLookAt(0, 0, 1.485 * 5, 0)

;-Light 
AmbientColor(RGB(155, 105, 105)) 
CreateLight(0, RGB(155, 155, 105), -200, 300, 0) 
;CreateLight(1,RGB(255, 127, 0), -200, -200, 200)
;WorldShadows(#PB_Shadow_Additive)

XMouse.d = 0
ZMouse.d = 0
YawMouse.d = 0

XCam = 160 * Sin(PosCam)
ZCam = 160 * Sin(PosCam)

PieceNB = 0
LevelCount = 0
Level.d = 0
CurrentY.d = Level * 1.485 + 0.7425 ; Level * 1.485 + 0.7425
UserDrop.d = 0
AvgMove.d = 0

PlayerTurn = 0
CreateSprite(0, 256, 48, #PB_Sprite_Texture|#PB_Sprite_AlphaBlending)

;- Main loop
Repeat
  
  Event = WindowEvent() 
  
  ExamineKeyboard()
  ExamineMouse()
  
  ;- Camera Move
  If KeyboardPushed(#PB_Key_Up)       : MoveCamera(0,  0,    0,   -0.1) : EndIf 
  If KeyboardPushed(#PB_Key_Down)     : MoveCamera(0,  0,    0,    0.1) : EndIf 
  If KeyboardPushed(#PB_Key_Left)     : MoveCamera(0, -0.1,  0,    0)   : EndIf 
  If KeyboardPushed(#PB_Key_Right)    : MoveCamera(0,  0.1,  0,    0)   : EndIf 
  If KeyboardPushed(#PB_Key_PageUp)   : MoveCamera(0,  0,   -0.1,  0)   : EndIf 
  If KeyboardPushed(#PB_Key_PageDown) : MoveCamera(0,  0,    0.1,  0)   : EndIf 
  
  CameraLookAt(0, 0, CurrentY, 0)
  
  If InGame
    
    XMouse - MouseDeltaX() / 50
    ZMouse - MouseDeltaY() / 50 
    YawMouse + MouseWheel() * 10 
    
    If XMouse < -20 : XMouse = -20 : EndIf
    If XMouse >  20 : XMouse =  20 : EndIf
    If ZMouse < -20 : ZMouse = -20 : EndIf
    If ZMouse >  20 : ZMouse =  20 : EndIf
    
    If MouseButton(#PB_MouseButton_Right ) : UserDrop = 1 : Else : UserDrop = 0 : EndIf
    
    EntityLocate(#VIRTUALPIECE, XMouse, CurrentY + UserDrop, ZMouse)
    RotateEntity(#VIRTUALPIECE, 0, YawMouse, 0)
    
    ;- Tile Drop
    If MouseButton(#PB_MouseButton_Left )
      
      EntityLocate(#VIRTUALPIECE, 200, 200, 0)
      
      CreatePiece(PieceNB, #TILEPL1MAT +  PlayerTurn, XMouse, CurrentY + UserDrop, ZMouse, YawMouse)
      
      XMouse = 200
      ZMouse = 200
      
      ;User is dropping the tile
      If UserDrop <> 0
        Delay = 120
        Repeat
          Event = WindowEvent()
          RenderWorld()
          FlipBuffers()
          Delay - 1
        Until (Abs(EntityY(#TILE + PieceNB) - CurrentY) < 0.05) Or (Delay <= 0)
        ;Pieces()\y = EntityY(#TILE + PieceNB) 
      EndIf
      
      ;Next level
      LevelCount + 1     
      If LevelCount > 2
        LevelCount = 0
        
        ;Little camera slide
        i.f = 0
        Repeat
          i + 0.05
          Event = WindowEvent()
          RenderWorld()
          FlipBuffers()
          CameraLookAt(0, 0, Level * 1.485 + 0.7425 + i, 0)
        Until i >= 1.485
        
        ;Average position for the next level
        CurrentY = (EntityY(#TILE + PieceNB) + EntityY(#TILE + PieceNB - 1) + EntityY(#TILE + PieceNB - 2)) / 3 + 1.515  ;Level * 1.485 + 0.7425 ;       
        
        Level + 1
      EndIf
      
      PieceNB + 1  
      PlayerTurn = 1 - PlayerTurn
      
      Repeat
        Event = WindowEvent()
        ExamineMouse()
      Until MouseButton(#PB_MouseButton_Left) = #False
      
    EndIf
    
    ;-Fall Check

    ForEach Pieces() 
      ;Check if tile has felt from the socle
      If (EntityY(Pieces()\EntityNB) < 0)
        TheEnd("Player " + Str(PlayerTurn + 1) + " has won. Level : " + Str(Level))
        Break ;To exit the loop and let the move continue (better feeling)
      EndIf
    Next
    
    
    If level > 0
      ;Check if tiles>3 are touching the ground
      For u = 3  To PieceNB - 1
        If EntityCollide(#GROUND, #TILE + u)
          TheEnd("Player " + Str(PlayerTurn + 1) + " has won. Level : " + Str(Level))
          Break
        EndIf        
      Next
    EndIf
    
    ;---
    
    StartDrawing(SpriteOutput(0))
    DrawText(0,0, "Level " + Str(Level))
    DrawText(0,16, "Player " + Str(PlayerTurn + 1) + " turn")
    StopDrawing()      
    
  Else
    
    StartDrawing(SpriteOutput(0))
    DrawText(0,16, "Player " + Str(PlayerTurn + 1) + " has won")
    StopDrawing()      
    
  EndIf
  
  DisplaySprite(0, 0, 0)
  
  ; Render 
  FlipBuffers()
  RenderWorld()
  
Until KeyboardPushed(#PB_Key_Escape) Or Event = #PB_Event_CloseWindow

End
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Le nid du Jenga - La tour infernale

Message par G-Rom »

revois ton code. on ne déplace pas ces entité comme cela , préfère MoveEntity() à LocateEntity() pour les body. ( regarde la démo du bowling , je supprime toujours la boule entre chaque tir )
n'ai pas peur de supprimer à la volée ton entité qui te sert de pièce virtuelle , puis de la recréer, en interne les positions et rotation seront mis à jours.
Les masses , friction , restitution , vont de 0 à 1 vois la masse comme un rapport au volume.
c'est à dire que si j'ai un cube de 1 en taille qui fait 0.1 en masse , et que j'ai un cube de 2 qui fait 0.2 en masse , alors il auront le même poids dans le moteur physique.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Le nid du Jenga - La tour infernale

Message par djes »

Ok, merci, je vais essayer. :)
Je ne m'étais pas interrogé puisque des fois ça fonctionne ! (à la base, je ne voulais même pas qu'il y ait cette interaction, mais c'est très pratique et très réaliste...)
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Le nid du Jenga - La tour infernale

Message par G-Rom »

il faudrait pour plus de facilité dans le déplacement que tu créer un plan invisible avec un masque de picking particulier et que tu fasses les déplacement d'objet via pickx() & pickz(). comme cela , ce que tu pointe à l'écran avec ta souris , la pièce se là ou se trouve le pointeur, c'est plus intuitif.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Le nid du Jenga - La tour infernale

Message par djes »

Pas compris... Mais ne t'embête pas, c'est juste un test...
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Le nid du Jenga - La tour infernale

Message par G-Rom »

djes a écrit :Pas compris... Mais ne t'embête pas, c'est juste un test...
c'est pourtant simple :

Code : Tout sélectionner

InitEngine3D()
InitSprite()



OpenWindow(0,0,0,1024,768,"Mouse picking")
OpenWindowedScreen(WindowID(0),0,0,1024,768,1,0,0)


CreateCamera(0,0,0,100,100)
CameraLocate(0,100,100,100)
CameraLookAt(0,0,0,0)


PickingMask.l = $0000FFFF

CreatePlane(0,1000,1000,1,1,1,1)
CreateEntity(0,MeshID(0),#PB_Material_None,0,0,0,PickingMask) ; <- Créer un material invisible ici !

CreateCube(1,10)
CreateEntity(1,MeshID(1),#PB_Material_None,0,5,0,$FFFF0000)

CreateLight(0,$FFFFFF,0,100,0)
WorldShadows(#PB_Shadow_Modulative)

Repeat
  event = WindowEvent()
  
  PointPick(0,WindowMouseX(0), WindowMouseY(0))
  
  If RayPick(100,100,100,PickX(),PickY(),PickZ(),PickingMask) = 0
    EntityLocate(1,PickX(),5,PickZ())
  EndIf 
  
  
  ClearScreen(0)
  RenderWorld()
  FlipBuffers()
Until event = #PB_Event_CloseWindow
  
Avatar de l’utilisateur
venom
Messages : 3136
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Le nid du Jenga - La tour infernale

Message par venom »

Pas mal ton code G-Rom si court pour un tel rendu sympa.







@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Le nid du Jenga - La tour infernale

Message par Ar-S »

G-Rom a écrit :
djes a écrit :Pas compris... Mais ne t'embête pas, c'est juste un test...
c'est pourtant simple :

Code : Tout sélectionner

InitEngine3D()
InitSprite()



OpenWindow(0,0,0,1024,768,"Mouse picking")
OpenWindowedScreen(WindowID(0),0,0,1024,768,1,0,0)


CreateCamera(0,0,0,100,100)
CameraLocate(0,100,100,100)
CameraLookAt(0,0,0,0)


PickingMask.l = $0000FFFF

CreatePlane(0,1000,1000,1,1,1,1)
CreateEntity(0,MeshID(0),#PB_Material_None,0,0,0,PickingMask) ; <- Créer un material invisible ici !

CreateCube(1,10)
CreateEntity(1,MeshID(1),#PB_Material_None,0,5,0,$FFFF0000)

CreateLight(0,$FFFFFF,0,100,0)
WorldShadows(#PB_Shadow_Modulative)

Repeat
  event = WindowEvent()
  
  PointPick(0,WindowMouseX(0), WindowMouseY(0))
  
  If RayPick(100,100,100,PickX(),PickY(),PickZ(),PickingMask) = 0
    EntityLocate(1,PickX(),5,PickZ())
  EndIf 
  
  
  ClearScreen(0)
  RenderWorld()
  FlipBuffers()
Until event = #PB_Event_CloseWindow
  
il est censé marcher en PB 4.61 ou c'est du PB5 ?
Car j'ai un nombre de paramètre incorrect pour le createEntity() ligne 18 en pb 4.61
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Le nid du Jenga - La tour infernale

Message par G-Rom »

la 5
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Le nid du Jenga - La tour infernale

Message par Ar-S »

hum.. je retourne à mes IP et WMi alors.. Je reviendrai à la 3D lorsque j'aurai installé la 5.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Le nid du Jenga - La tour infernale

Message par djes »

Ah oui OK, merci pour l'exemple ! Bien pratique cette fonction :) J'espère que je vais trouver le temps d'explorer tout ça...

J'ai fait un petit test. Tu parles du rapport masse/taille. Pourrais-tu nous dire ce qu'attends en gros le moteur, des grammes, des newtons, etc. pour qu'on se rapproche de la réalité ?

Code : Tout sélectionner

InitEngine3D()
InitSprite()



OpenWindow(0,0,0,1024,768,"Mouse picking")
OpenWindowedScreen(WindowID(0),0,0,1024,768,1,0,0)

EnableWorldPhysics(#True)
EnableWorldCollisions(#True)

CreateCamera(0,0,0,100,100)
CameraLocate(0,100,100,100)
CameraLookAt(0,0,0,0)


PickingMask.l = $0000FFFF

CreatePlane(0,1000,1000,1,1,1,1)
CreateEntity(0,MeshID(0),#PB_Material_None,0,0,0,PickingMask) ; <- Créer un material invisible ici !
EntityPhysicBody(0, #PB_Entity_StaticBody, 1, 0, 1)   

CreateCube(1,10)
CreateEntity(1,MeshID(1),#PB_Material_None,0,5,0,$FFFF0000)
EntityPhysicBody(1, #PB_Entity_BoxBody, 0.9, 0, 1)   

CreateCube(2,10)
CreateEntity(2,MeshID(2),#PB_Material_None,0,5,0,$FFFF0000)
EntityPhysicBody(2, #PB_Entity_BoxBody, 0.9, 0, 1)   

CreateLight(0,$FFFFFF,0,100,0)
WorldShadows(#PB_Shadow_Modulative)

Repeat
  event = WindowEvent()
  
  PointPick(0,WindowMouseX(0), WindowMouseY(0))
  
  If RayPick(100,100,100,PickX(),PickY(),PickZ(),PickingMask) = 0
    EntityLocate(1,PickX(),5,PickZ())
  EndIf 
  
  
  ClearScreen(0)
  RenderWorld()
  FlipBuffers()
Until event = #PB_Event_CloseWindow
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Le nid du Jenga - La tour infernale

Message par G-Rom »

Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Le nid du Jenga - La tour infernale

Message par Thyphoon »

Sympa ton code Djes ...
ça donne envie de se mettre a la 3D ! :oP
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Le nid du Jenga - La tour infernale

Message par djes »

G-Rom> Merci :)

Typhoon> Merci :mrgreen:
Répondre