Page 1 sur 1

Screen/Sprite : grille isométrique infinie

Publié : mer. 06/sept./2017 8:44
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 ;)

Re: Screen/Sprite : grille isométrique infinie

Publié : mer. 06/sept./2017 11:28
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



Re: Screen/Sprite : grille isométrique infinie

Publié : mer. 06/sept./2017 17:40
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)