Bon voilà le code modifié avec l'astuce de G-Rom. Par contre, on perd la possibilité de "pousser"/"jouer" avec la brique virtuelle avant de la poser. En effet, quand on vient de poser une brique, la brique virtuelle s'affiche au même endroit, là où est la souris ; du coup, le moteur physique fait tout exploser (ce qui est logique puisqu'il y a deux objets au même endroit). Comment faire ? Déplacer la souris ? Désactiver le moteur physique le temps que le joueur se soit placé un peu plus loin ?
Code : Tout sélectionner
;*********************************
; Jenga's Nest
; by djes (djes@free.fr)
; 04/25/11 : First release
; 03/05/11 : Code update
; 26/09/12 : PB 5.0b3 new commands update
; Thanks to new PB 3D commands
; Feel free to enhance !
EnableExplicit
Enumeration
#INVISIBLEGROUND
#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, Physic.i = #True)
CreateEntity(#TILE + u, MeshID(#TILE), MaterialID(mat), x, y , z, 2)
ScaleEntity(#TILE + u, 9, 1.485, 3)
; EntityLocate(#TILE + u, x, y, z)
RotateEntity(#TILE + u, 0, Yaw, 0)
If Physic
EntityPhysicBody(#TILE + u, #PB_Entity_BoxBody, 250, 0, 2)
EndIf
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)
;ReleaseMouse(1)
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
CreatePlane(#INVISIBLEGROUND, 1000, 1000, 1, 1, 1, 1)
CreateCube(#GROUND, 1)
CreateCube(#TILE, 1)
;- Entities
CreateEntity(0,MeshID(#INVISIBLEGROUND), #PB_Material_None, 0, 0, 0, 1, 0) ; Le masque du plan invisible est défini sur 1
CreateEntity(#GROUND, MeshID(#GROUND), MaterialID(#GROUND), 0, -0.5, 0, 2)
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), 0, 0, 0, 2)
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)
Define YawMouse.d, XCam.i, ZCam.i, PieceNB.i, LevelCount.i, CurrentY.d,UserDrop.d,AvgMove.d, PosCam.d, Level.d, PlayerTurn.i, Event.i, Delay.i, i.f, u.i
;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
;PointPick(0, WindowMouseX(0), WindowMouseY(0))
MousePick(0, WindowMouseX(0), WindowMouseY(0), 1)
;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
;If RayPick(-30, 1.485 * 20, -30, PickX(), PickY(), PickZ(), 2) = 0
EntityLocate(#VIRTUALPIECE, PickX(), CurrentY + UserDrop, PickZ())
;EndIf
;EntityLocate(#VIRTUALPIECE, XMouse, CurrentY + UserDrop, ZMouse)
RotateEntity(#VIRTUALPIECE, 0, YawMouse, 0)
;- Tile Drop
If KeyboardReleased(#PB_Key_Space) Or MouseButton(#PB_MouseButton_Left)
EntityLocate(#VIRTUALPIECE, 200, 200, 0)
CreatePiece(PieceNB, #TILEPL1MAT + PlayerTurn, PickX(), CurrentY + UserDrop, PickZ(), YawMouse)
; 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
RenderWorld()
DisplaySprite(0, 0, 0)
; Render
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Event = #PB_Event_CloseWindow
End