J'ai codé un pseudo-décor en 3D de manière simple et aléatoire :
J'ai une grille de 30x30 cubes texturés.
Un certain nombre d'entre-eux sont rehaussés pour créer un espèce de labyrinthe.
On peut déplacer la caméra avec les touches keyUP & KeyDown pour avancer et reculer + la souris (gauche-droite) pour changer de direction.
Je suis dans les collisions et l'objectif étant de stopper la progression de la camera quand elle rencontre un mur.
Pour cela, je fais un test sur les coordonnées des cubes et de la caméra.
Ce test marche bien, c'est à dire que l'on ne peut pas faire avancer la camera quand les positions x,y se chevauchent avec un cube à tester.
Mais, je rencontre un problème : en effet,si par exemple (en considérant un déplacement sur les X) la caméra est en position 80 et qu'un mur est à la position 90, le mur ne devient plus visible et la camera film a à travers le mur. Un peu comme si le caméraman était bien posté à la position 80 mais que l'objectif est à la position 130...
Pour pallier à ça, j'ai prévu un ajustement (decacam) qui anticipe ce décalage mais ça empeche d'aller partout car le décalage crée une zone tampon qui empeche la camera de progresser dans des espaces trop réduits...
Je cherche à comprendre d'où vient ce décalage, est-il réglable ?
J'ai l'impression que ce décalage est "presque" relatif. Au début, j'avais fait des cubes de 10x10 (ScaleEntity(j, 10, 10, 10) et le décalage était d'environ 7 ou 8. En passant à (ScaleEntity(j, 100, 100, 100), j'ai un décalage de 60...
Il est possible, que comme Jean-Claude Duss, ce soit mes yeux qui déconnent mais des fois sur un malentendu, je poste quand même !!
Merci à vous!
Pour tester : 2 fichiers graphiques + le code
http://xdji.free.fr/Telechargement/police.bmp
http://xdji.free.fr/Telechargement/TextureDVP3.jpg
Code : Tout sélectionner
; Cool Dji, Février 2011, PB 4.51
#CameraSpeed = 10
#Hauteur = 100
test.i =0
decacam.i=1
InitSprite() : InitKeyboard() :InitEngine3D() : InitMouse() : InitSprite3D()
AntialiasingMode(#PB_AntialiasingMode_x6)
OpenScreen(1024, 768, 32, "Circuit")
Add3DArchive("\", #PB_3DArchive_FileSystem)
;- Génération de la police de caractère
LoadImage(0,"police.bmp")
For j =0 To 46:GrabImage(0,1,j*6,0,6,7)
CreateSprite(j,6,7,#PB_Sprite_Texture):TransparentSpriteColor(j, 0)
StartDrawing(SpriteOutput(j)):DrawImage(ImageID(1),0,0): StopDrawing()
CreateSprite3D(j, j):Next
;- code Création d'un cube de 3d - Comtois
#Tiers = 1.0/3.0
;-Mesh
#Mesh = 0
CreateMesh(#Mesh, 100)
Options = #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Color
SetMeshData(#Mesh, Options , ?Sommets, 24)
SetMeshData(#Mesh, #PB_Mesh_Face, ?Triangles, 12)
;-Textures
#Texture = 10
Fichier$="TextureDVP3.jpg"
;Maintenant on peut charger notre texture
LoadTexture(#Texture, Fichier$)
;-Matière
#Matiere = 0
CreateMaterial(#Matiere, TextureID(#Texture))
;-Entity
#Entity = 0
For j=0 To 899
CreateEntity(j, MeshID(#Mesh), MaterialID(#Matiere))
ScaleEntity(j, 100, #Hauteur, 100) ; Agrandi l'entity
Next
CreateCamera(0, 0, 0, 100, 100)
CameraLocate(0,0,0,0)
CameraLookAt(0,10,0,10)
;CameraRange(0,-100,1000)
;-
;-- Tableau pour les cases du labyrinthe
Dim hauteur.f(900)
Dim posx.f(900)
Dim posy.f(900)
current = 0
Restore Labyrinthe
Repeat
Read.w hauteur(current)
current+1
Until current = 900
;---- place chque cas en X et Y
j=0
For i=1 To 3000 Step 100
For k=1 To 3000 Step 100
posx(j)=k
posy(j)=i
j=j+1
Next
Next
;-
;-- Gestion des textes
;Chaine qui indique l'ordre des lettres contenues dans l'image "Gaga Punch.bmp"
Global Strig$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789-"
; Déclaration de la procédre qui affiche les textes
; (Texte à afficher, position Y, taille, n° de sprite, max aléatoire pour faire trembler la lettre)
Declare AffT(TextMenu01$,y.i,sz.i,sprite.i,rnd.i)
; le texte est automatiquement centré
; Text$ = TExt à afficher
; y =position y du text
; sz =Taille de la police (sert pour le zomm des lettres et de l'espacement)
; sp =Pointe sur le sprite A de la bonne police
; rnd =valeur de tremblement des lettres
Procedure AffT(Text$,y.i,sz.i,sp.i,rnd.i)
sx=0:For i=1 To Len(Text$):For j=1 To Len(Strig$)
If Mid(Text$,i,1)=Mid(Strig$,j,1):a=sz+2
DisplaySprite3D(sp+j-1,sx+Random(rnd)+400-(Len(Text$)*a)/2,y+Random(rnd),200)
sx=sx+sz+2:j=Len(Strig$):EndIf :Next:Next
EndProcedure
;-
;- BIG LOOP
Repeat
; --
For j=0 To 899
If (hauteur(j)=0) Or (hauteur(j))>#Hauteur-10
EntityLocate(j,posx(j),hauteur(j),posy(j))
Else
EntityLocate(j,posx(j),hauteur(j),posy(j))
hauteur(j)=hauteur(j)+10
EndIf
Next
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up)
KeyY = -#CameraSpeed
ElseIf KeyboardPushed(#PB_Key_Down)
KeyY = #CameraSpeed
Else
KeyY = 0
EndIf
EndIf
If ExamineMouse()
MouseX.f = -(MouseDeltaX()/10)*#CameraSpeed/2
MouseY.f = -(MouseDeltaY()/10)*#CameraSpeed/2
EndIf
;- Position de la Camera
Height.f = 11 ; TerrainHeight(CameraX(0), CameraZ(0))
RotateCamera(0, MouseY, MouseX, RollZ, #PB_Relative)
;-- Test des collisions
;--- Sauvegarde l'ancienne position
olkdkeyX=CameraX(0)
olkdkeyY=CameraY(0)
olkdkeyZ=CameraZ(0)
;--- Déplace la camera
MoveCamera (0, KeyX, -CameraY(0)+#Hauteur+#Hauteur/2, KeyY)
;CameraLocate(0,CameraX(0),20,CameraZ(0)+KeyY)
;--- Regarde si la camera est dans le décor
test=0
For j=0 To 899
If hauteur(j)>0
If ((CameraX(0)+decacam>=posx(j)) And (CameraX(0)-decacam=<posx(j)+100) And (CameraZ(0)+decacam>=posy(j)) And (CameraZ(0)-decacam=<posy(j)+100))
test=1
EndIf
EndIf
Next
; test=0
; If ((CameraX(0)>10) And (CameraX(0)<10+10) And (CameraZ(0)>10) And (CameraZ(0)<10+10))
; test=1
; EndIf
If test= 1
;---- Si oui, replace-là à son ancienne position
CameraLocate(0,olkdkeyX, olkdkeyY, olkdkeyZ)
EndIf
RenderWorld()
Start3D()
AffT("KEY UP AND DOWN MOUSE TO MOVE AND TURN",80,6,0,0)
AffT("X "+Str(CameraX(0)),100,6,0,0)
AffT("Y "+Str(CameraY(0)),110,6,0,0)
AffT("Z "+Str(CameraZ(0)),120,6,0,0)
AffT(Str(CountRenderedTriangles())+" TRIANGLES",200,6,0,0)
AffT(Str(Engine3DFrameRate(#PB_Engine3D_Current))+" FPS",210,6,0,0)
Stop3D()
FlipBuffers()
ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape):
End
;{ Définition du cube
DataSection
Sommets:
;Dessus 0 à 3
Data.f 0,1,0
Data.f 0,1,0
Data.l 0
Data.f 0, 0
Data.f 1,1,0
Data.f 0,1,0
Data.l 0
Data.f #Tiers, 0
Data.f 1,1,1
Data.f 0,1,0
Data.l 0
Data.f #Tiers, #Tiers
Data.f 0,1,1
Data.f 0,1,0
Data.l 0
Data.f 0, #Tiers
;Dessous 4 à 7
Data.f 0,0,1
Data.f 0,-1,0
Data.l 0
Data.f #Tiers, #Tiers
Data.f 1,0,1
Data.f 0,-1,0
Data.l 0
Data.f #Tiers*2,#Tiers
Data.f 1,0,0
Data.f 0,-1,0
Data.l 0
Data.f #Tiers*2,#Tiers*2
Data.f 0,0,0
Data.f 0,-1,0
Data.l 0
Data.f #Tiers,#Tiers*2
;Devant 8 à 11
Data.f 0,1,1
Data.f 0,0,1
Data.l 0
Data.f #Tiers, 0
Data.f 1,1,1
Data.f 0,0,1
Data.l 0
Data.f #Tiers*2,0
Data.f 1,0,1
Data.f 0,0,1
Data.l 0
Data.f #Tiers*2,#Tiers
Data.f 0,0,1
Data.f 0,0,1
Data.l 0
Data.f #Tiers,#Tiers
;Derrière 12 à 15
Data.f 1,1,0
Data.f 0,0,-1
Data.l 0
Data.f #Tiers,#Tiers*2
Data.f 0,1,0
Data.f 0,0,-1
Data.l 0
Data.f #Tiers*2,#Tiers*2
Data.f 0,0,0
Data.f 0,0,-1
Data.l 0
Data.f #Tiers*2,1
Data.f 1,0,0
Data.f 0,0,-1
Data.l 0
Data.f #Tiers,1
;Cote gauche 16 à 19
Data.f 0,1,0
Data.f -1,0,0
Data.l 0
Data.f 0,#Tiers
Data.f 0,1,1
Data.f -1,0,0
Data.l 0
Data.f #Tiers,#Tiers
Data.f 0,0,1
Data.f -1,0,0
Data.l 0
Data.f #Tiers,#Tiers*2
Data.f 0,0,0
Data.f -1,0,0
Data.l 0
Data.f 0,#Tiers*2
;Cote droit 20 à 23
Data.f 1,1,1
Data.f 1,0,0
Data.l 0
Data.f #Tiers*2,#Tiers
Data.f 1,1,0
Data.f 1,0,0
Data.l 0
Data.f 1,#Tiers
Data.f 1,0,0
Data.f 1,0,0
Data.l 0
Data.f 1,#Tiers*2
Data.f 1,0,1
Data.f 1,0,0
Data.l 0
Data.f #Tiers*2,#Tiers*2
Triangles:
;Bas
;Face en Haut
Data.w 2,1,0
Data.w 0,3,2
;Face en Bas
Data.w 6,5,4
Data.w 4,7,6
;Face Avant
Data.w 10,9,8
Data.w 8,11,10
;Face Arrière
Data.w 14,13,12
Data.w 12,15,14
;Face Gauche
Data.w 18,17,16
Data.w 16,19,18
;Face Droite
Data.w 22,21,20
Data.w 20,23,22
Labyrinthe:
Data.w 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.w 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
Data.w 0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,1,1,0,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,0
Data.w 0,1,1,1,1,1,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,0,0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data.w 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0
Data.w 0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0
Data.w 0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,1,0,0,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0
Data.w 0,1,1,1,0,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data.w 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
Data.w 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
EndDataSection
;}
EDIT : 8 février midi
EDIT : 9 février minuit
EDIT : 13 février - en soirée