Screen/Sprite : grille isométrique infinie

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Screen/Sprite : grille isométrique infinie

Message par blendman »

Salut

Pour mon éditeur de niveau 2D, j'avais besoin d'une grille isométrique infinie.

Voici la méthode que j'ai trouvée. Ca n'est pas parfait, mais ça fonctionne plutôt pas mal ;)
- vous pouvez zoomer/dézoomer (touche + -)
- vous pouvez bouger la vue (flèches)

Code : Tout sélectionner



InitSprite()
InitKeyboard()

Global zoom.d, screenW, screenH, viewx,viewy
screenW = 640
screenH = 480
zoom = 1
 
Structure sSprite
  
  x.f
  y.f
  w.i
  h.i
  
EndStructure


#iIsoGrid = 0
#SpIsoGrid = 0

CreateImage(#iIsoGrid, ScreenW+128, ScreenH+64, 32)


; grid
Procedure SetSpriteImage(sprite,image)
  
  If StartDrawing(SpriteOutput(sprite))
    
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    Box(0, 0, OutputWidth(), OutputHeight(),RGBA(0,0,0,0))
    
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(image),0,0)
    StopDrawing()
    
  EndIf 
  
EndProcedure
  
Procedure UpdateIsoGridPosition()
  
  ; update the position of the grid
  
  Shared zoom.d, sp.sSprite
  
  z.d = zoom
  If z<=0
    z= 0.1
  EndIf
  
  sp\x =  (- Mod(viewx, 64) - 64) * z
  sp\y =  (- Mod(viewy, 32) - 32) * z
  
  ; SetSpritePosition(#SpIsoGrid, x1, y1)
  
EndProcedure

Procedure SetIsoGrid()
  
  ; to update the iso grid 
  
  Shared zoom.d
  
  z.d =  zoom
  
  If z<=0
    z= 1
  EndIf
  
    
    If StartDrawing(ImageOutput(#iIsoGrid))
      DrawingMode(#PB_2DDrawing_AlphaChannel)
      Box(0, 0, OutputWidth(), OutputHeight(),RGBA(0,0,0,0))
      
      
      DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AlphaBlend)
      x = screenW +64
      y = 0
      
      For i=0 To 128/z  
        
        LineXY(x + (-i*64)* z,
               y,
               x + (i*64)* z,
               y + i*64 * z,
               RGBA(0,0,0,255))  
        
        LineXY((-i*64)* z ,
               i*64* z,
               (i*64)* z ,
               0,
               RGBA(0,0,0,255))  
      Next i
      
      StopDrawing()
      
    EndIf  
    
    
   SetSpriteImage(#SpIsoGrid, #iIsoGrid)

    
  
  
EndProcedure

Procedure ResetIsoGrid()
  
  Shared sp.sSprite
  ;  resize sprite & image for isogrid 
  
  w = ScreenW + 2*64 
  h = ScreenH + 2*32
  
  ResizeImage(#iIsoGrid, w, h)
  ; SetSpriteSize(#SpIsoGrid, w, h)
  
  sp\w = w
  sp\h = h
  
  ; on update le dessin sur la grille si besoin
  SetIsoGrid()
  
  ;on repositionne la grille
  UpdateIsoGridPosition() 
  
  
  
EndProcedure




Procedure updatescreen()
  
  Shared sp.sSprite
  
  ClearScreen(RGB(100,100,100))
  
  z.d = zoom
  
  DisplayTransparentSprite(#SpIsoGrid, sp\x , sp\y )
  
  FlipBuffers()
  
EndProcedure


MaFenetre = OpenWindow(0, 0, 0, 1024, 768,"iso grid", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)

If MaFenetre  = 0
  
  MessageRequester("Erreur", "Impossible d'ouvrir une fenêtre DirectX", #PB_MessageRequester_Ok)
  
Else
 
  x = (WindowWidth(0) - screenW)*0.5 
  y = 50
  
  OpenWindowedScreen(MaFenetre, x, y, screenW, screenH)
  
  CreateSprite(#SpIsoGrid, ScreenW+128, ScreenH+64, #PB_Sprite_AlphaBlending)
  ResetIsoGrid()
  
  speed = 4 
 
  updatescreen()
  
  Repeat
    
    Repeat
      
      Event = WindowEvent()
      
    Until Event = 0 Or Event = #PB_Event_CloseWindow
    
    ExamineKeyboard()
    
    ; move the view
    If KeyboardPushed(#PB_Key_Left)
      l = speed
    EndIf
    If KeyboardReleased(#PB_Key_Left)
      l = 0
    EndIf
    
    If KeyboardPushed(#PB_Key_Right)
      r = -speed
    EndIf 
    If KeyboardReleased(#PB_Key_Right)
      r = 0
      
    EndIf
    If KeyboardPushed(#PB_Key_Up)
      t = speed
    EndIf
    If KeyboardReleased(#PB_Key_Up)
      t = 0
    EndIf
    
    If KeyboardPushed(#PB_Key_Down)
      b = -speed
    EndIf 
    If KeyboardReleased(#PB_Key_Down)
      b = 0    
    EndIf
    
    
    ; zoom the view
    If KeyboardPushed(#PB_Key_Add)
      If zoom <5
        zoom + 0.01
      EndIf
      Debug zoom
      SetIsoGrid()
      updatescreen()
    EndIf
    If KeyboardPushed(#PB_Key_Subtract)
      If zoom > 0.3
        zoom - 0.01
      EndIf 
      SetIsoGrid()
      updatescreen()
    EndIf
    
    
    
    viewx+r+l
    viewy+t+b
    
    If oldx <> viewx Or oldy <> viewy
      oldx = viewx
      oldy = viewy
      UpdateIsoGridPosition()
      updatescreen()
    EndIf
        
  Until Event = #PB_Event_CloseWindow
  
EndIf



Le dernier bug à corriger : que la grille reste en 0/0 qd on zoome / dézoome

n'hésitez pas à poster vos commentaires ;)
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Screen/Sprite : grille isométrique infinie

Message par blendman »

hello

une autre technique qui permet de facilement modifier certains paramètres : taille écran, taille de la grille, grille centrée en 0,0

Code : Tout sélectionner


InitSprite()
InitKeyboard()

Global zoom.d, screenW, screenH, viewx, viewy, ZoomMax
screenW = 640
screenH = 480
zoom = 1
ZoomMax = 4

Structure sSprite
  
  x.i
  y.i
  w.i
  h.i
  
EndStructure


#iIsoGrid = 0
#iIsoGrid2 = 1
#SpIsoGrid = 0

#caseW = 64
#caseH = 32

CreateImage(#iIsoGrid, ScreenW+ #caseW * ZoomMax*2, ScreenH+ #caseH * ZoomMax*2, 32)
CreateImage(#iIsoGrid2, #caseW, #caseH, 32)

If StartDrawing(ImageOutput(#iIsoGrid2))
  DrawingMode(#PB_2DDrawing_AlphaChannel)
  
  Box(0, 0, OutputWidth(), OutputHeight(),RGBA(0,0,0,0))
  
  DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_AlphaBlend)
  LineXY(0, 0, #caseW, #caseH, RGBA(0,0,0,255)) 
  LineXY(#caseW, 0, 0 ,#caseH, RGBA(0,0,0,255))  
  
  StopDrawing()
  
EndIf  


; grid
Procedure SetSpriteImage(sprite,image)
  
  
  Define z.d =  zoom
  
  If z<=0
    z= 1
  EndIf
  
  temp = CopyImage(image,#PB_Any)
  ResizeImage(temp,#caseW * z, #caseH* z)
  
  If StartDrawing(SpriteOutput(sprite))
    
    w = OutputWidth()
    h = OutputHeight()
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    Box(0, 0, w, h, RGBA(0,0,0,0))
    
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    For i=0 To w/#caseW / z 
      For j=0 To h/#caseh / z
        x = Round(i * #caseW * z, #PB_Round_Down )
        y = Round(j * #caseH * z, #PB_Round_Down )
        DrawAlphaImage(ImageID(temp), x-i, y-j)
      Next
    Next
    
    StopDrawing()
    
  EndIf 
  
EndProcedure
  
Procedure UpdateIsoGridPosition()
  
  ; update the position of the grid
  
  Shared zoom.d, sp.sSprite
  
  z.d = zoom
  If z<=0
    z= 0.1
  EndIf
  
  w.d = #caseW ; * ZoomMax * 0.5
  h.d = #caseH ; * ZoomMax * 0.5 
  
  sp\x =  (- Mod(viewx, w) - w) * z
  sp\y =  (- Mod(viewy, h) - H) * z
  
EndProcedure

Procedure SetIsoGrid()
  
  ; to update the iso grid 
 
   SetSpriteImage(#SpIsoGrid, #iIsoGrid2)
   
   UpdateIsoGridPosition()
   
   SetWindowTitle(0,"Isometric grid "+Str(Zoom*100)+"%")

  
EndProcedure

Procedure ResetIsoGrid()
  
  ; update the grid
  SetIsoGrid()
  
  UpdateIsoGridPosition() 
    
  
EndProcedure




Procedure updatescreen()
  
  Shared sp.sSprite
  
  ClearScreen(RGB(100,100,100))
  
  z.d = zoom
  
  DisplayTransparentSprite(#SpIsoGrid, sp\x , sp\y )
  
  FlipBuffers()
  
EndProcedure


MyWindow = OpenWindow(0, 0, 0, 1024, 768,"Isometric grid", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)

If MyWindow  = 0
  
  MessageRequester("Error", "Unable to open DirectX", #PB_MessageRequester_Ok)
  
Else
 
  x = (WindowWidth(0) - screenW)*0.5 
  y = 50
  
  OpenWindowedScreen(MyWindow, x, y, screenW, screenH)
  SpriteQuality(1)
  
  CreateSprite(#SpIsoGrid, ScreenW + #caseW * ZoomMax, ScreenH + #caseH * ZoomMax, #PB_Sprite_AlphaBlending)
  ResetIsoGrid()
  
  speed = 4 
 
  updatescreen()
  
  Repeat
    
    Repeat
      
      Event = WindowEvent()
      
    Until Event = 0 Or Event = #PB_Event_CloseWindow
    
    ExamineKeyboard()
    
    ; move the view
    If KeyboardPushed(#PB_Key_Left)
      l = speed
    EndIf
    If KeyboardReleased(#PB_Key_Left)
      l = 0
    EndIf
    
    If KeyboardPushed(#PB_Key_Right)
      r = -speed
    EndIf 
    If KeyboardReleased(#PB_Key_Right)
      r = 0
      
    EndIf
    If KeyboardPushed(#PB_Key_Up)
      t = speed
    EndIf
    If KeyboardReleased(#PB_Key_Up)
      t = 0
    EndIf
    
    If KeyboardPushed(#PB_Key_Down)
      b = -speed
    EndIf 
    If KeyboardReleased(#PB_Key_Down)
      b = 0    
    EndIf
    
    
    ; zoom the view
    If KeyboardPushed(#PB_Key_Add)
      If zoom < ZoomMax
        zoom + 0.01
      EndIf
      SetIsoGrid()
      updatescreen()
    EndIf
    If KeyboardPushed(#PB_Key_Subtract)
      If zoom > 0.3
        zoom - 0.01
      EndIf 
      SetIsoGrid()
      updatescreen()
    EndIf
    
    
    viewx+r+l
    viewy+t+b
    
    If oldx <> viewx Or oldy <> viewy
      oldx = viewx
      oldy = viewy
      UpdateIsoGridPosition()
      updatescreen()
    EndIf
        
  Until Event = #PB_Event_CloseWindow
  
EndIf


Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Screen/Sprite : grille isométrique infinie

Message par Kwai chang caine »

Quand tu regardes bien la grille...ça donne le mal de mer, heureusement qu'elle est pas bleue :lol:
Les deux codes marchent nickel ici, merci 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Répondre