Page 1 sur 3

Le nid du Jenga - La tour infernale

Publié : lun. 25/avr./2011 15:11
par djes
Un petit jeu basé sur le principe de Jenga et du nid de la cigogne.
Pour deux joueurs, utilisez chacun votre tour la souris pour déposer une brique. Vous pouvez en poser trois par niveau. Le but est de faire la plus grande tour possible sans que celle-ci ne tombe. Pour tourner la brique, utilisez la molette. Touches du clavier + PageUp/PageDown pour bouger la caméra.

Amusez-vous bien :)

Code : Tout sélectionner

;*********************************
; Jenga's Nest
; by djes (djes@free.fr)
; 04/25/2011 : First release
; 03/05/2012 : 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
          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
          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
        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
    
    ExamineWorldCollisions()
    
    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é : lun. 25/avr./2011 20:11
par G-Rom
Sympa, je l'ai améliorer pour Linux :

Code : Tout sélectionner

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

Enumeration
  #GROUND
  #VIRTUALPIECE
  #PIECEPL1MAT
  #PIECEPL2MAT
EndEnumeration
Enumeration #PB_Compiler_EnumerationValue Step 600
  #PIECE
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
Global Quit   = #False

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

Procedure TheEnd(msg.s)
  ReleaseMouse(#True)
  FreeEntity(#VIRTUALPIECE)
  CloseScreen()
  CloseWindow(0)
  MessageRequester("Infos", Msg)
  
  InGame = #False 
  Quit=#True 
EndProcedure

;- Initialization
InitSprite()
InitEngine3D()
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)

;-Texture (I hate to have to do that!!!!!)
Add3DArchive(".",#PB_3DArchive_FileSystem)
CreateImage(0, 128, 128)
StartDrawing(ImageOutput(0))
Boolean.b=0
For ii = 0 To 7
  For jj = 0 To 7
    
    Boolean+1
    Boolean%2
    
    Select Boolean
      Case 0:Color = $FFFFFF
      Case 1:Color = $000000
    EndSelect
    
    Box(ii*16, jj*16, 16, 16, Color)
    
  Next
  Boolean+1
Next
StopDrawing()
SaveImage(0,"temp.bmp")
FreeImage(0)
LoadTexture(0,"temp.bmp")
DeleteFile("temp.bmp")

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

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

CreateCube(#PIECE, 1)

CreateEntity(#VIRTUALPIECE, MeshID(#PIECE), MaterialID(#VIRTUALPIECE))
ScaleEntity(#VIRTUALPIECE, 9, 1.485, 3)
;EntityPhysicBody(#VIRTUALPIECE, #PB_Entity_BoxBody)   

;- 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

PlayerTurn = 0

KeyboardMode(#PB_Keyboard_International)

;- Main loop
Repeat
 If InGame
  Event = WindowEvent()
 
  ExamineMouse()
  ExamineKeyboard()
  
 
  ;- 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, Level * 1.485 + 0.7425, 0)
 
 
       
    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
   
    EntityLocate(#VIRTUALPIECE, XMouse, Level * 1.485 + 0.7425, ZMouse)
    RotateEntity(#VIRTUALPIECE, 0, YawMouse, 0)
       
    ;- Drop Tile
    If MouseButton(#PB_MouseButton_Left )
     
      CreatePiece(PieceNB, #PIECEPL1MAT +  PlayerTurn, XMouse, Level * 1.485 + 0.7425, ZMouse, YawMouse)
      PieceNB + 1
     
      LevelCount + 1     
      If LevelCount > 2
        LevelCount = 0
        i.f = 0
        Repeat
          i + 0.05
          RenderWorld()
          FlipBuffers()
          CameraLookAt(0, 0, Level * 1.485 + 0.7425 + i, 0)
        Until i >= 1.485
        Level + 1
      EndIf
     
      PlayerTurn = 1 - PlayerTurn
     
      Repeat
        ExamineMouse()
      Until MouseButton(#PB_MouseButton_Left) = #False
     
    EndIf
   
    ;-Fall Check
    AvgMove.d = 0
    ForEach Pieces()
       
      ;felt from the socle
      If EntityY(Pieces()\EntityNB) < 0
        TheEnd("Player " + Str(PlayerTurn + 1) + " has won. Level : " + Str(Level))
        Break
      EndIf
     
      ;of the tile has an invalid rotation
      If EntityPitch(Pieces()\EntityNB) > 5 Or EntityYaw(Pieces()\EntityNB) > 5  Or EntityRoll(Pieces()\EntityNB) > 5
        TheEnd("Player " + Str(PlayerTurn + 1) + " has won. Level : " + Str(Level))
      EndIf
   
      ;if the tile ensemble felt from its original position
      AvgMove + (Pieces()\y - EntityY(Pieces()\EntityNB))
     
    Next
   
    If AvgMove > 0.1
      TheEnd("Player " + Str(PlayerTurn + 1) + " has won. Level : " + Str(Level))
    EndIf
    ;---
   
  EndIf
   
  ; Render
  If InGame=#True 
    RenderWorld()
    FlipBuffers()
    
    If  KeyboardPushed(#PB_Key_Escape) Or Event = #PB_Event_CloseWindow
      Quit = #True
    EndIf 
    
  EndIf 
  
Until Quit = #True 

End

Re: Le nid du Jenga - La tour infernale

Publié : lun. 25/avr./2011 21:25
par djes
T'as surtout rajouté des bugs! :mrgreen:

Re: Le nid du Jenga - La tour infernale

Publié : lun. 25/avr./2011 21:34
par G-Rom
justement , chez moi ca les corriges :D

Re: Le nid du Jenga - La tour infernale

Publié : mer. 27/avr./2011 21:23
par gildev
Amusez-vous à cliquer en rafale toujours au même endroit, l'effet est sympa. :D
En tout cas bon prog djes car c'est amusant. :D

Re: Le nid du Jenga - La tour infernale

Publié : mer. 27/avr./2011 21:40
par djes
Merci! J'ai commencé une version avec un curseur "solide". Mais le test de chute ne fonctionne pas, et je suis complètement bloqué en attendant la prochaine beta. Sinon, on peut faire très facilement des trucs très chouettes; un billard ne prendrait pas plus de lignes!

Re: Le nid du Jenga - La tour infernale

Publié : jeu. 28/avr./2011 0:43
par Ar-S
j'arrive pas à faire un tas de 3 :mrgreen:

Re: Le nid du Jenga - La tour infernale

Publié : jeu. 28/avr./2011 6:56
par Cool Dji
Comme Ar-S, j'ai l'impression d'être un boulet avec ma souris :mrgreen: :mrgreen:

Re: Le nid du Jenga - La tour infernale

Publié : jeu. 28/avr./2011 7:55
par djes
Essayez cette version là. J'ai laissé un petit frottement à partir de la deuxième ligne, il faut y aller tout doux. Il est toujours possible (et souhaitable!) d'utiliser la molette pour tourner la brique ; le deuxième bouton sert à la soulever temporairement, histoire de la faire "tomber" comme dans le vrai jeu.
A part ça, le test de chute ne fonctionne pas, sauf à tomber du plateau.

Code : Tout sélectionner

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

Enumeration 
  #GROUND
  #VIRTUALPIECE
  #PIECEPL1MAT
  #PIECEPL2MAT
EndEnumeration
Enumeration #PB_Compiler_EnumerationValue Step 600
  #PIECE
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(#PIECE + u, MeshID(#PIECE), MaterialID(mat))
  ScaleEntity(#PIECE + u, 9, 1.485, 3)
  EntityLocate(#PIECE + u, x, y, z)
  RotateEntity(#PIECE + u, 0, Yaw, 0)
  EntityPhysicBody(#PIECE + u, #PB_Entity_BoxBody, 25, 0, 100)
  AddElement(Pieces())
  Pieces()\EntityNb = #PIECE + 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, 5, 0, 100)   
  ReleaseMouse(#True)
  MessageRequester("Infos", Msg)
  InGame = #False  
EndProcedure

;- Initialization
InitSprite()
InitEngine3D()
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)
  
  ;-Texture (I hate to have to do that!!!!!)
Add3DArchive(".",#PB_3DArchive_FileSystem)
CreateImage(0, 128, 128) 
StartDrawing(ImageOutput(0)) 
  Box(0, 0, 128, 128, $FFFFFF)
StopDrawing()
SaveImage(0,"temp.bmp")
FreeImage(0)
LoadTexture(0,"temp.bmp")
DeleteFile("temp.bmp")

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

;- Entities
CreateCube(#GROUND, 1)
CreateEntity(#GROUND, MeshID(#GROUND), MaterialID(#GROUND))
ScaleEntity(#GROUND, 20, 1, 20)
EntityLocate(#GROUND, 0, -0.5, 0)
EntityPhysicBody(#GROUND, #PB_Entity_StaticBody, 25, 0, 100)   

CreateCube(#PIECE, 1)

CreateEntity(#VIRTUALPIECE, MeshID(#PIECE), MaterialID(#VIRTUALPIECE))
ScaleEntity(#VIRTUALPIECE, 9, 1.485, 3)
EntityPhysicBody(#VIRTUALPIECE, #PB_Entity_BoxBody, 5, 0, 100)   

;- 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

;- Main loop
Repeat
  
  FlipBuffers()
  ; Render
  RenderWorld()
  
  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)
    
    ;- Drop Tile
    If MouseButton(#PB_MouseButton_Left )

      EntityLocate(#VIRTUALPIECE, 200, 200, 0)

      CreatePiece(PieceNB, #PIECEPL1MAT +  PlayerTurn, XMouse, CurrentY + UserDrop, ZMouse, YawMouse)

      XMouse = 200
      ZMouse = 200
      
      ;User drop the tile
      If UserDrop <> 0
        delay = 120
        Repeat
          RenderWorld()
          FlipBuffers()
          delay - 1
        Until (Abs(EntityY(#PIECE + PieceNB) - CurrentY) < 0.05) Or (delay <= 0)
        ;Pieces()\y = EntityY(#PIECE + PieceNB) 
      EndIf
      
      LevelCount + 1     
      If LevelCount > 2
        LevelCount = 0
        
        ;Little camera slide
        i.f = CurrentY
        ;Average position for the next level
        CurrentY = (EntityY(#PIECE + PieceNB) + EntityY(#PIECE + PieceNB - 1) + EntityY(#PIECE + PieceNB - 2)) / 3 + 1.505  ;Level * 1.485 + 0.7425 ;

        Repeat
          i + 0.05
          RenderWorld()
          FlipBuffers()
          CameraLookAt(0, 0, i, 0)
        Until i >= CurrentY
             
        Level + 1
      EndIf
      
      PieceNB + 1 
      PlayerTurn = 1 - PlayerTurn
      
      Repeat
        ExamineMouse()
      Until MouseButton(#PB_MouseButton_Left) = #False
      
    EndIf
    
    ;-Fall Check
    If level > 0
      
      ExamineWorldCollisions()
      
      ForEach Pieces()
        ; Debug Pieces()\EntityNB
        ; Debug StrD(EntityPitch(Pieces()\EntityNB)) + " - " + StrD(EntityYaw(Pieces()\EntityNB)) + " - " + StrD(EntityRoll(Pieces()\EntityNB))
        
        ;felt from the socle 
        If (EntityY(Pieces()\EntityNB) < 0)
          TheEnd("Player " + Str(PlayerTurn + 1) + " has won. Level : " + Str(Level))
          Break
        EndIf
        
        ;the tile has an invalid rotation
        ;-Doesn't work : EntityPitch()...
;         If (Abs(EntityPitch(Pieces()\EntityNB)) > 5) Or (Abs(EntityYaw(Pieces()\EntityNB)) > 5) Or (Abs(EntityRoll(Pieces()\EntityNB)) > 5) 
;           TheEnd("Player " + Str(PlayerTurn + 1) + " has won. Level : " + Str(Level))
;           Break
;         EndIf
        
        ;-Doesn't work : CheckEntityCollision()
;         If CheckEntityCollision(Pieces()\EntityNB, #GROUND)
;           TheEnd("Player " + Str(PlayerTurn + 1) + " has won. Level : " + Str(Level))
;         EndIf
        
      Next
    EndIf
    ;---
    
  EndIf

Until KeyboardPushed(#PB_Key_Escape) Or Event = #PB_Event_CloseWindow

End

Re: Le nid du Jenga - La tour infernale

Publié : lun. 05/mars/2012 16:40
par djes
Petite mise à jour (voir 1er post). Détecté les bugs suivants dans le moteur 3D :
  • Parfois la collision ne fonctionne pas (quand on place une nouvelle brique, parfois il y a collision, parfois non).
  • Il y a incohérence entre le fait d'utiliser CheckEntityCollision(entity1, entity2) et le couple FirstWorldCollisionEntity()/SecondWorldCollisionEntity(). Qu'est-ce qu'il faut utiliser au juste ? Du coup je me suis replié sur EntityCollide() qui m'oblige à tout passer en revue.
  • L'ombre ne fonctionne toujours pas sur l'une de mes machines. Ca plante, c'est tout.

Re: Le nid du Jenga - La tour infernale

Publié : lun. 05/mars/2012 17:31
par Ar-S
De déplacement à la souris est laborieux ! (ça rame).
Il doit y avoir une couille dans l'gigot. Comment lève-t-on la seconde brique au dessus de la 1ere ? (la hauteur ?)

Re: Le nid du Jenga - La tour infernale

Publié : lun. 05/mars/2012 19:25
par djes
Ca rame? Sinon c'est simple, tu poses trois briques, et ça se lève tout seul pour le niveau suivant.

Re: Le nid du Jenga - La tour infernale

Publié : lun. 05/mars/2012 21:58
par Ar-S
djes a écrit :Ca rame? Sinon c'est simple, tu poses trois briques, et ça se lève tout seul pour le niveau suivant.
Ahhhhh !!!!! :P

le coté ramage concerne le déplacement de la brique avec la souris. Autant la rotation va bien que pour la déplacer "a plat" c'est une peu miséreux.

Re: Le nid du Jenga - La tour infernale

Publié : lun. 05/mars/2012 23:17
par Le Soldat Inconnu
j'ai la brique en cours d'ajout qui pousse les autres briques, et je n'arrive pas à ajouter de brique par dessus une autre :mrgreen:

Re: Le nid du Jenga - La tour infernale

Publié : mar. 06/mars/2012 9:39
par djes
C'est comme le vrai Jenga (personne n'a joué?) : chacun joue à son tour, on fait des étages de trois briques. Donc inutile de vouloir mettre au dessus ! Pour mettre de l'autre côté, on tourne avec la molette. Quand trois briques sont posées, ça monte d'un étage automatiquement.
Ar-S a écrit :le coté ramage concerne le déplacement de la brique avec la souris. Autant la rotation va bien que pour la déplacer "a plat" c'est une peu miséreux.
Ce n'est pas la bonne définition de "ramer" : ramer, c'est quand le temps pris pour créer une frame (une image) dépasse de beaucoup la fréquence d'affichage, par exemple quand au lieu de pouvoir afficher 60 imgs/seconde, tu ne peux en faire que 10 (voir mon post sur le benchmark VBL pour mieux comprendre). Ici, le jeu est toujours à 60imgs/secs !

Bref, si c'est "lent", c'est parce que le déplacement doit être hyper précis et minutieux : ce n'est pas un jeu de tennis, tu dois pouvoir poser tes briques au millimètre.