Jeu 2D avec ogre

Généralités sur la programmation 3D
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Jeu 2D avec ogre

Message par blendman »

salut

En discutant avec G-rom, il m'a suggéré de tester ogre pour faire de la 2D.
J'ai donc réalisé un petit test, mais je rencontre quelques soucis :
- lorsqu'on se déplace sur la droite, les arbres disparaissent et parfois, le player disparait aussi.
- Comment puis-je faire pour changer le "zoom" de la camera (qui est orthogonale). Dans Blender, il me suffit de changer la focale, mais ici, ça ne marche pas. (Je ne veux pas devoir changer la taille des sprites ou la taille de la fenêtre).


Voici le code :

Code : Tout sélectionner

; pb 5.31 +
; 08/10/2015
; blendman : test 3Diso, use 3D for sprite and 2D game

Global G_width,G_height
G_Width = 1024
G_height = 768
Global Zoom = 100000

If InitEngine3D()  
  If InitSprite() : EndIf
  If InitKeyboard(): EndIf
  If InitMouse(): EndIf
  UseJPEGImageDecoder()
  UsePNGImageDecoder() 
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
  End
EndIf

; the structure for the sprite
Structure sSprite  
  sprite.i
  image.i
  w.i
  h.i  
  ; neede to create the sprite
  material.i
  mesh.i
  texture.i  
  ; parameters for the sprite
  x.f
  y.f
  depth.i
  visible.a
  Typ.a
  OffsetX.i
  OffsetY.i  
  ; texture
  u.i ; repetition in X
  v.i ; repetition in y  
  ; material / texture
  selfillum.a  
EndStructure
Global NewMap Sprite.sSprite()


; The sprite lib
Procedure LoadImage2(image,file$)
  
  If FileSize(file$) <> 0
    img = LoadImage(image,file$)
    If img
      
      If image =#PB_Any
        image=img
      EndIf
            
      ProcedureReturn image
    Else
      MessageRequester("Error","Your image "+file$+" doesn't exists")
    EndIf
    
  Else
    MessageRequester("Error","Your image "+file$+" doesn't exists")
  EndIf
  ProcedureReturn -1
EndProcedure

Procedure CreateSprite3D(sprite, image, repetition=1, depth=0, selfillum=0)
  
  Shared SpriteTyp
  ; SpriteTyp  : to define the type of sprite. 0 = sprite_image, 1 = text.
  ;{ *** Infos
  ; Procedure to create a sprite
  ; repetition : to change the "repetition" of the texture drawned on the sprite (the repeated Tile count.
  ; depth = the Z-order or depth for the sprite.
  ; selfillum = selfillumination : 0 = off, 1 = on
  ;}
    
   R = repetition
    
  ;- Check if image exists
  If IsImage(image)
    w = ImageWidth(image)
    h = ImageHeight(image)
  Else
    MessageRequester("Info", "Your image "+Str(image)+"doesn't exist, a blank image will be created for the sprite "+Str(sprite))
    w = 64 
    h = 64
    img = CreateImage(#PB_Any,w,h,32,#PB_Image_Transparent)
    If img
      If StartDrawing(ImageOutput(img))
        Box(0,0,w,h,RGB(255,255,255))
        StopDrawing()
      EndIf
      image = img
    Else
      MessageRequester("Error","No image created")
      End
    EndIf
   
  EndIf
    
  ; create the texture
  texture= CreateTexture(#PB_Any,w,h) 
  If texture
    If StartDrawing(TextureOutput(texture))
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      DrawAlphaImage(ImageID(image),0,0)
      StopDrawing()
    EndIf
        
    ; Création the material
    material =  CreateMaterial(#PB_Any, TextureID(texture))
    If material 
      If SelfIllum = 1
        SetMaterialColor(material, #PB_Material_SelfIlluminationColor, RGB(255, 255, 255))
      EndIf
      MaterialBlendingMode(material, #PB_Material_AlphaBlend)
      MaterialFilteringMode(material, #PB_Material_Bilinear)
      MaterialCullingMode(material, #PB_Material_NoCulling)
      
      mesh = CreateMesh(#PB_Any)
      If mesh
        
        ; to define the TileCountX and TileCountY
        count = r
        If r <> 1
          count = r*3        
        EndIf
        
        If CreatePlane(mesh,w*r,h*r,count,count,r,r)             
          UpdateMeshBoundingBox(mesh)
          SetMeshMaterial(mesh, MaterialID(material))
          
          ;-Entity
          NewSprite = CreateEntity(sprite, MeshID(mesh), #PB_Material_None,-w/2, depth, -h/2)
          If sprite = #PB_Any
            sprite = NewSprite
          EndIf
          
          ; for the isometric view
          RotateEntity(sprite,90,180,0, #PB_Relative)
          ; ScaleEntity(0, 1, 1, 1)
          
        EndIf
        
        ; than, we add the newsprite in the map of the sprite
        key$ =Str(sprite)
        AddMapElement(Sprite(),key$)
        With sprite()
          \sprite = sprite
          \image = image 
          \w = ImageWidth(image) * r
          \h = ImageHeight(image) * r
          ; if needed
          \material = material
          \mesh = mesh
          \texture = texture
          ; other parameters
          \u = r
          \v = r
          \depth = depth
          \selfillum = selfillum
          \Typ = SpriteTyp
        EndWith
        ProcedureReturn  Sprite
      EndIf
      
    EndIf
    
  EndIf
  
  ProcedureReturn  -1
EndProcedure

Procedure SetSpriteSize(sprite,w,h)
  Key$ = Str(sprite)
  If FindMapElement(sprite(),key$)
    zw.d = w/sprite(key$)\w  
    zh.d = h/sprite(key$)\h
    ScaleEntity(sprite, zw, zh, #PB_Ignore)
  EndIf  
EndProcedure
Procedure GetSpriteWidth(sprite)
   Key$ = Str(sprite)
  If FindMapElement(sprite(),key$)
    ProcedureReturn  sprite(key$)\w 
  EndIf
EndProcedure
Procedure GetSpriteHeight(sprite)
  Key$ = Str(sprite)
  If FindMapElement(sprite(),key$)
    ProcedureReturn  sprite(key$)\h 
  EndIf
EndProcedure
Procedure SetSpriteDepth(sprite,depth)
  Key$ = Str(sprite)
  If FindMapElement(sprite(),key$)
    sprite(key$)\depth = depth
    MoveEntity(sprite,#PB_Ignore,depth,#PB_Ignore,#PB_Absolute)
  EndIf 
EndProcedure

Procedure SetSpritePosition(sprite,x,y)
   Key$ = Str(sprite)
  If FindMapElement(sprite(),key$)
    sprite(key$)\x = x
    sprite(key$)\y = y
    z = sprite(key$)\depth
    MoveEntity(sprite,x,y,z,#PB_Absolute)
  EndIf 
EndProcedure


; general events
Procedure Events()

  Shared px, py, ShowStats, zoom
  speed= 4  
  z = 500
    
  Repeat
    Event = WindowEvent()    
    Select Event            
      Case #PB_Event_CloseWindow
        Quit = 1        
    EndSelect    
    If Quit = 1 : End : EndIf 
  Until Event = 0
  
   ; Keyboard events 
  If ExamineKeyboard()
    If KeyboardReleased(#PB_Key_F1)
      ShowStats = 1 - ShowStats
      WorldDebug(ShowStats)       
    EndIf
        
    ;{ Keyboard
    ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Right)
      px+speed   
      SetSpritePosition(0,px,py)
    EndIf
    If KeyboardPushed(#PB_Key_Left)
      px-speed
      SetSpritePosition(0,px,py)
    EndIf
    If KeyboardPushed(#PB_Key_Up)
      py+speed        
      SetSpritePosition(0,px,py)
    EndIf
    If KeyboardPushed(#PB_Key_Down)
      py-speed
      SetSpritePosition(0,px,py)
    EndIf
    
    cx = px
    If cx < 0
      cx = 0
    EndIf
    cy = py
    If cy < 0
      cy = 0
    EndIf    
    MoveCamera(0,cx,cy,zoom,#PB_Absolute)
    MoveLight(1,px,py,1,#PB_Absolute)
    
    If KeyboardPushed(#PB_Key_Add)
      If zoom > 10
        Zoom - 10
      ElseIf zoom > 1
        zoom -1
      EndIf
      MoveCamera(0, px, py, zoom,#PB_Absolute)
    EndIf
    If KeyboardPushed(#PB_Key_Subtract)
      zoom +10        
      MoveCamera(0, px, py, zoom, #PB_Absolute)
    EndIf
    ;}
    
  EndIf  
  Debug zoom
  
EndProcedure

Enumeration
  #iplayer 
  #iGround 
  #iTree 
  #iButon 
EndEnumeration
LoadImage2(#iplayer,"Media/player.png") 
LoadImage2(#iGround,"Media/ground.jpg")
LoadImage2(#iButon,"Media/btn.png")
LoadImage2(#iTree,"Media/tree.png")


  If OpenWindow(0, 0, 0, G_Width, G_height, "Sprite3D", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    If OpenWindowedScreen(WindowID(0), 0, 0, G_Width, G_Height, 0, 0, 0) = 0
      MessageRequester("Error","Unable to open a screen")
      End
    EndIf    
  EndIf
  
  AntialiasingMode(#PB_AntialiasingMode_x4)
  
  ; MaterialFilteringMode(#PB_Default, #PB_Material_Anisotropic, 8)
 
   ; create the "sprite3D"
  CreateSprite3D(1,#iGround,30,-12) ; the background
  CreateSprite3D(0,#iPlayer)       ; the player
  Debug "ground et player créé"
  
  ; a dim for the tree
  nbTree = 10
  Dim Tree(nbTree)
  w = GetSpriteWidth(1)
  h = GetSpriteHeight(1)
  Debug "taille du ground "+Str(w)+"/"+Str(h)
  For i = 0 To NbTree
    Tree(i) = CreateSprite3D(#PB_Any,#iTree) 
    SetSpritePosition(Tree(i), Random(w),Random(h))
    Debug "arbre "+Str(i)+" créé"
  Next i
  
  CreateSprite3D(2,#iButon,1,0,1) ; a simple btn
  SetSpriteDepth(2,500)
  SetSpritePosition(2,G_width/2-20,G_height/2-10)
  
  ;{ create the camera
  CreateCamera(0,0,0,100,100)
  CameraRange(0, 0, 500000000)
  ;RotateCamera(0,-90,-180,0,#PB_Absolute|#PB_Local)
  MoveCamera(0, 0, zoom, 0, #PB_Absolute|#PB_Local)
  CameraProjectionMode(0, #PB_Camera_Orthographic)
  CameraFOV(0, 200) ; pas de change avec le mode orthographic ?
  ;}
  
  ;{ Create 2 lights and the ambiant light of the scene
  AmbientColor(RGB(155,80,20)) ; orange day
  ; AmbientColor(RGB(80,80,255)) ; blue night
  CreateLight(0,RGB(0,255,255),10,1,10)
  LightAttenuation(0,5000,0.000000000000001)
  CreateLight(1,RGB(200,100,255),1000,1,10)
  LightAttenuation(1,10000,0.0000001)
  ;}
  
  Repeat    
    Events()
    RenderWorld()    
    FlipBuffers()    
  Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
Les images :
http://blendman.free.fr/dev/pb/Games/images_2d.zip

Merci
Dernière modification par blendman le ven. 09/oct./2015 13:57, modifié 1 fois.
Mesa
Messages : 1093
Inscription : mer. 14/sept./2011 16:59

Re: Jeu 2D avec ogre

Message par Mesa »

J'ai une erreur mémoire invalide ligne 134 à la création de l'arbre n°0, avec XP32.

M.
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: Jeu 2D avec ogre

Message par G-Rom »

La camera orto déconne , je l'ai déjà signalé à Fred & Comtois. utilise une camera normale ;)
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Jeu 2D avec ogre

Message par comtois »

G-Rom a écrit :La camera orto déconne , je l'ai déjà signalé à Fred & Comtois. utilise une camera normale ;)
Ouais mais je ne sais pas comment le corriger.
T-Myke avait fait des modifs sans résultat probant. J"ai fait des recherches sur le forum d'ogre, j'ai vu des avis divers et variés sur le sujet , j'ai peut-être même fait quelques tests ? je ne sais plus.

Bref si tu trouves un début de solution je veux bien l'expérimenter pour la prochaine version.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Jeu 2D avec ogre

Message par blendman »

G-Rom a écrit :La camera orto déconne , je l'ai déjà signalé à Fred & Comtois. utilise une camera normale ;)
rah dommage.

J'avais testé avec une caméra normale pour le zoom ça marchait, mais je préférai la caméra ortho pour la 2D, c'est plus logique. En plus, pour la 3D iso c'est indispensable (bon, là c'est de la 2D donc ça pourrait passer ^^).

Mais même avec une caméra normale, j'ai toujours les mêmes problèmes de personnages et arbres qui disparaissent quand je bouge ma caméra vers le bas :(

@MEsa : là, je ne peux rien pour toi, car je n'utilise plus xp depuis qu'il est périmé ^^.
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Jeu 2D avec ogre

Message par comtois »

Je ne suis pas chez moi pour tester, mais tu as essayé de modifier le cameraRange() ?
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Jeu 2D avec ogre

Message par blendman »

comtois a écrit :Je ne suis pas chez moi pour tester, mais tu as essayé de modifier le cameraRange() ?
oui, j'ai déjà essayé, mais ça ne résout pas le soucis ^^.
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: Jeu 2D avec ogre

Message par G-Rom »

règle pour chaque couche une profondeur z. je suis sur mobile, je regarderai ce soir.
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Jeu 2D avec ogre

Message par comtois »

je suis chez moi et je viens de tester en ajoutant

Code : Tout sélectionner

  WorldDebug(#PB_World_DebugEntity)
les arbres sont bien présents (on voit la box), par contre j'ai l'impression que c'est un problème soit de gestion d'éclairage, soit de gestion de profondeur de tes entity.
dans ta procédure

Code : Tout sélectionner

Procedure CreateSprite3D(sprite, image, repetition=1, depth=0, selfillum=0) 
tu fais un
NewSprite = CreateEntity(sprite, MeshID(mesh), #PB_Material_None,-w/2, d, -h/2)
mais je ne vois pas d'où sort le d ???
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Jeu 2D avec ogre

Message par blendman »

Code : Tout sélectionner

mais je ne vois pas d'où sort le d ???
C'est une erreur (j'ai modifié le code sans modifier ça), c'était le depth dans les paramètres de la procedure.
Mais le problème ne venait pas de là, j'ai trouvé.
En fait, (et je ne me l'explique pas), on dirait que la caméra change légèrement de Z lorsqu'on la déplace en X et Y.

Du coup, pour corriger ça, j'ai dû mettre sa hauteur de + de 100000 (au lieu de 1000).
C'est vraiment bizarre, car sa hauteur change (très légèrement) alors que je ne modifie que le X et le Y de la caméra.

J'ai mis à jour le premier code.

Sinon, comment est géré la caméra orthogonale ?
je veux dire, on ne peut pas changer sa focale (pour être plus ou moins proche des objets (j'ai testé la hauteur, mais ça change la hauteur de la caméra et ça ne change pas l'aspect (grandeur) des objets affichés.)


@G-rom : j'utilisais déjà le z pour la profondeur, mais ça n'était pas suffisant.
En plus, j'ai testé avec la caméra normale et en fait, ça ne va pas du tout pour de la simulation 2D, on voit trop que c'est de la 3D.
Dernière modification par blendman le ven. 09/oct./2015 14:15, modifié 1 fois.
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: Jeu 2D avec ogre

Message par G-Rom »

@G-rom : j'utilisais déjà le z pour la profondeur, mais ça n'était pas suffisant.
En plus, j'ai testé avec la caméra normale et en fait, ça ne va pas du tout pour de la simulation 2D, on voit trop que c'est de la 3D.
Tu t'y prend mal , reprend mon exemple est modifie la camera par ceci , ligne 342 :

Code : Tout sélectionner

CamX = LinearInterpolate(CamX,EntityX(D),deltaTime/100)
      CamY = LinearInterpolate(CamY,EntityY(D),deltaTime/100)
       
      
      
      MoveCamera(Camera2D,CamX,CamY,10,#PB_Absolute)
      CameraLookAt(Camera2D,EntityX(D),EntityY(D),-1000)
si tu vois que c'est de la 3D , t'es fort ^^ , j'ai forcé le trait dans la démo exprès. toute mes tuiles sont sur l'axe X/Y , le Z pour la profondeur , il y a une coquille dans la démo que j'ai corrigé ( pas encore partagé par contre ) avec les UV de texture. chaque tuile fait une unité de taille pour être en corrélation avec le moteur physique ( une unité ~= 1 mètre )
Répondre