Page 2 sur 3

Re: Le nid du Jenga - La tour infernale

Publié : mar. 06/mars/2012 19:36
par Le Soldat Inconnu
Avec l'explication, c'est mieux :)

Re: Le nid du Jenga - La tour infernale

Publié : ven. 21/sept./2012 15:48
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

Re: Le nid du Jenga - La tour infernale

Publié : ven. 21/sept./2012 18:44
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.

Re: Le nid du Jenga - La tour infernale

Publié : sam. 22/sept./2012 11:36
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...)

Re: Le nid du Jenga - La tour infernale

Publié : sam. 22/sept./2012 19:32
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.

Re: Le nid du Jenga - La tour infernale

Publié : sam. 22/sept./2012 19:50
par djes
Pas compris... Mais ne t'embête pas, c'est juste un test...

Re: Le nid du Jenga - La tour infernale

Publié : sam. 22/sept./2012 23:37
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
  

Re: Le nid du Jenga - La tour infernale

Publié : dim. 23/sept./2012 10:26
par venom
Pas mal ton code G-Rom si court pour un tel rendu sympa.







@++

Re: Le nid du Jenga - La tour infernale

Publié : dim. 23/sept./2012 12:02
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

Re: Le nid du Jenga - La tour infernale

Publié : dim. 23/sept./2012 12:06
par G-Rom
la 5

Re: Le nid du Jenga - La tour infernale

Publié : dim. 23/sept./2012 12:20
par Ar-S
hum.. je retourne à mes IP et WMi alors.. Je reviendrai à la 3D lorsque j'aurai installé la 5.

Re: Le nid du Jenga - La tour infernale

Publié : dim. 23/sept./2012 12:22
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

Re: Le nid du Jenga - La tour infernale

Publié : dim. 23/sept./2012 12:32
par G-Rom

Re: Le nid du Jenga - La tour infernale

Publié : dim. 23/sept./2012 14:02
par Thyphoon
Sympa ton code Djes ...
ça donne envie de se mettre a la 3D ! :oP

Re: Le nid du Jenga - La tour infernale

Publié : dim. 23/sept./2012 18:26
par djes
G-Rom> Merci :)

Typhoon> Merci :mrgreen: