[jeu] 2D : faire un zoom sur une map

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

[jeu] 2D : faire un zoom sur une map

Message par blendman »

salut

Je me demandais s'il y avait un moyen de faire un zoom sur une map sur laquelle sont affichées des sprites et sprites3D, autrement qu'en utilisant des zoomsprites() sur chaque sprite, ce qui en plus ne suffirait car il faudrait aussi décaler les sprites en fonction de l'intensité du zoom/dézoom... bref, le bean's :D.

Alors, existe-t-il une solution plus "simple" et générale ? :D

Merciche biench
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: [jeu] 2D : faire un zoom sur une map

Message par Cool Dji »

Salut Blendam,

Pas à ma connaissance.
J'avais commencé un truc dans le genre.
Tous les graphismes étaient dessinés de la taille pour être affiché dans le zoom (donc gros sprites)

En préambule, je réduisais les graphismes qui devaient être affiché à l'écran...

Sinon, il te reste la 3D...
Only PureBasic makes it possible
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: [jeu] 2D : faire un zoom sur une map

Message par Fig »

Pas mieux...
Mais c'est faisable et peut être pas si compliqué que cela... Il faut juste limiter le zoom parce que si tu as plus de 2200 tiles affichés simultanément, chez moi, ça rame... (petite configuration)
J'ai un petit prog 2d iso, je vais essayer de rajouter le zoom dessus.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: [jeu] 2D : faire un zoom sur une map

Message par djes »

Il y a une solution toute simple mais un peu coûteuse en temps machine : dessiner au pixel en prenant la couleur selon un intervalle régulier sur ta carte.
Sinon, la mini-carte (grabsprite) est ce qu'il y a de plus rapide, il y a juste à afficher quelques points pour les éléments à suivre. Trois images correspondraient à trois niveaux de zoom par exemple. Après tu peux en faire des intermédiaires par calcul.
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: [jeu] 2D : faire un zoom sur une map

Message par Cool Dji »

'tain Djes, t'as fumé ou c'est moi :D
J'ai rien compris !!! :lol: :lol:
Only PureBasic makes it possible
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: [jeu] 2D : faire un zoom sur une map

Message par Fig »

Ouais, Djes, ça à l'air sympa, fais tourner !!

Ou alors tu as mis un troyen et tu vois ce que je fais... 8O

Perso la mini carte j'ai fais un sprite rempli au départ (en prétraitement) de pixels correspondant aux tiles de ma carte. Comme ma carte est plus grande que ma mini-map en pixel, je prend des carrés de tiles et je garde pour la couleur du pixel de la minimap l'élément qui est en moins grand nombre. Par exemple si il y a 7 tiles vide et 1 avec une ressource pierre, je met le pixel correspondant en gris (pierre)
Ensuite, j'affiche la minimap et je rafraichis juste les élements qui bougent dessus.

Mais bon effectivement ça n'a pas grand chose à voir avec la question initiale :mrgreen:

... En te relisant je me rend compte que je n'ai rien compris :?
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: [jeu] 2D : faire un zoom sur une map

Message par djes »

Arf, c'est mon esprit de synthèse qui a encore frappé. En plus je me suis trompé, j'ai cru qu'il voulait faire une mini carte dans un coin de l'écran.
Donc pour répondre un peu mieux à la question, ça va être difficile de faire autrement qu'avec des ZoomSprite(). C'est aussi pour cela que tu as intérêt à ce que toutes tes coordonnées soient calculées en relatif, avec des variables que tu n'auras qu'à ajuster en fonction du zoom. Surtout pas de nombres codés en dur!
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: [jeu] 2D : faire un zoom sur une map

Message par Fig »

Voila, ça donne une idée.
Le -4 et +4 c'est la vitesse du zoom, à ajuster... (zoom avec les fleches clavier avant et arriere)

Amélioration à faire demain si je n'ai pas trop de boulot:
1-Optimisation de la vitesse de zoom parceque franchement avec mon système de calcul des coordonnées de toutes les tiles ça craint niveau vitesse la mise à jour des 1024x1024 tiles :roll: Je peux juste calculer au fur et à mesure les coordonnées de chacune des tiles affichés. Je ne sais pas pourquoi j'avais fait comme cela.Ca ne devrait pas être trop dur.[FAIT, maintenant c'est rapide+ code épuré des artefacts du code complet]
2- Faut que les arbres ils grossissent proportionnellement bien sûr[Fait]
3- Adapter le système de selection pour la taille variable des sprite (système que j'ai retiré du code pour ne pas l'encombrer, mais qui permet de sélectionner précisément les sprites sans passer par le test 2d de collision, mais en utilisant une table de hashing)
Enfin c'était juste un essais pour dire que c'est faisable.
Bonne soirée. :o



Code : Tout sélectionner

;***
;***   @Fig 12/05/2011
;***        PB 4.51
If InitSprite() = 0 Or InitKeyboard()=0 Or InitMouse()=0 Or InitSprite3D()=0 Or InitSound()=0:MessageRequester("Error","Error DirectX",0):EndIf
ExamineDesktops():Sprite3DQuality(#PB_Sprite3D_BilinearFiltering)
;{-structures
Structure carte1
  tile.i
  *element
  X.i
  Y.i
EndStructure
Structure ordre_affichage1
  X.i
  Y.i
EndStructure
Structure sprite1
  spritedebase.i
  biasX.i
  biasY.i
EndStructure
;}
;{- Taille d'origine des tiles
X_Tilesize=64
Y_Tilesize=X_Tilesize/2
;}
;{-déclare les variables globales
Global xmax=DesktopWidth(0),ymax=DesktopHeight(0)
Global xscroll,yscroll,Xscrolliso,Yscrolliso
Global nbcaseX=Round(xmax/X_Tilesize,1);nombre de Case en hauteur en diagonal à afficher
Global nbcaseY=Round(ymax/Y_Tilesize,0);nombre de Case en largeur en diagonal à afficher
Global Scroll_X=80,Scroll_Y=80,IsoScroll_X=1,IsoScroll_Y=80,XX,YY
Global Scroll_X=80,Scroll_Y=80,IsoScroll_X=1,IsoScroll_Y=80,XX,YY
Global vitesse_scroll=32,miliscrol_X,miliscrol_Y,zoom_carte=4
;}
;{-déclare les variables "temporaires"
Global T_i,T_j,T_nb,T_DecX=0,T_DecY=0,T_offset=0
;}
;déclare l'aire de jeu
Global Dim carte.carte1(1023,1023)
;déclare le tableau d'ordre d'affichage des tiles
Global Dim ordre_affichage.ordre_affichage1(20000)
;liste des caractéristiques de l'animation des arbres
Global NewList sprite.sprite1()
;ouvre un écran
OpenScreen(xmax,ymax, DesktopDepth(0), "test")

;{-rempli la carte
;rempli de Tiles
For t_i=0 To 1023
  For t_j=0 To 1023
    carte(t_i,t_j)\tile=Random(2)+1
  Next t_j
Next t_i
;initialise les arbres
For t_i=0 To 10000
  Repeat
    X=Random(1021)+1
    Y=Random(1021)+1
    AddElement(sprite())
    sprite()\spritedebase=150
    sprite()\biasX=-64
    sprite()\biasY=-224
  Until carte(x,y)\element=0
  carte(X,Y)\element=@sprite()
Next t_i
;}

;pré-calcul l'ordre d'affichage des tiles à l'écran
Macro ordredaffichage
  T_nb=0
  ReDim ordre_affichage(60000)
  For T_j=nbcaseY To -nbcaseY Step -1
    For T_i=nbcaseX To -nbcaseX Step -1
      T_nb+1
      ordre_affichage(T_nb)\X=-T_j-T_i
      ordre_affichage(T_nb)\Y=T_i-T_j
    Next T_i
    For T_i=nbcaseX To -nbcaseX+1 Step -1
      T_nb+1
      ordre_affichage(T_nb)\X=-T_j-T_i+1
      ordre_affichage(T_nb)\Y=T_i-T_j
    Next T_i
  Next T_j
  ReDim ordre_affichage(T_nb)
EndMacro
ordredaffichage

;{-création des sprites
T_T=100000
For t_j=1 To 3
  ;sprite de terrain :herbe verte, herbe sèche et terre nue
  CreateSprite(t_j,256,256,#PB_Sprite_Texture)
  StartDrawing(SpriteOutput(t_j))
  Box(0,0,256,256,RGB(0,0,0))
  Box(0,0,256,256,RGB(196, 178, 86))
  For T_i=1 To T_T
    Plot(Random(256-1),Random(256-1),RGB(0,200,50))
    Plot(Random(256-1),Random(256-1),RGB(0,127,0))
  Next T_i
  T_T/2
  StopDrawing()
Next T_j
;sprite arbre
CreateSprite(150,256,256,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(150))
Box(107,64,42,255,RGB(1,1,1))
Box(108,64,40,255,RGB(173, 103, 82))
Circle(128,65,66,RGB(1,1,1))
Circle(128,65,64,RGB(0,200,0))
Circle(128,65,30,RGB(1,1,1))
Circle(128,65,28,RGB(0,0,0))
StopDrawing()
;sprite de la souris
CreateSprite(100,16,16,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(100))
LineXY(0,0,15,5,RGB(255,255,255))
LineXY(0,0,5,15,RGB(255,255,255))
LineXY(15,5,5,15,RGB(255,255,255))
StopDrawing()

;transforme les sprites carrées en tiles losanges isométriques rapport 1/2
For T_i=1 To 3
  CreateSprite3D(T_i,T_i)
  TransformSprite3D(T_i,X_Tilesize/2,0,X_Tilesize,Y_Tilesize/2,X_Tilesize/2,Y_Tilesize,0,Y_Tilesize/2)
Next T_i
CreateSprite3D(150,150)
CreateSprite3D(100,100)
;}

;boucle principale
Repeat
  FlipBuffers()
  ClearScreen(RGB(0,0,0))
  Delay(3)
  ExamineKeyboard()
  ExamineMouse()
  XX=MouseX()
  YY=MouseY()
  ;{-scroll+zoom de la carte
  ;zoomIN
  If KeyboardPushed(#PB_Key_Up)
    x_tilesize+zoom_carte
    y_tilesize=x_tilesize/2
    nbcaseX=Round(xmax/x_tilesize,1);nombre de Case en hauteur en diagonal à afficher
    nbcaseY=Round(xmax/y_tilesize,1)
    Start3D()
    ;change la taille des tiles
    For T_i=1 To 3
      TransformSprite3D(T_i,X_Tilesize/2,0,X_Tilesize,Y_Tilesize/2,X_Tilesize/2,Y_Tilesize,0,Y_Tilesize/2)
    Next T_i
    ;change la taille des arbres
    ratiox.f=X_tilesize/64
    ratioy.f=y_tilesize/32
    ZoomSprite3D(150,256*ratiox,256*ratioy)
    Stop3D()
    ordredaffichage
  EndIf
  ;zoomOut
  If KeyboardPushed(#PB_Key_Down) And x_tilesize>32
    x_tilesize-zoom_carte
    y_tilesize=x_tilesize/2
    nbcaseX=Round(xmax/x_tilesize,1);nombre de Case en hauteur en diagonal à afficher
    nbcaseY=Round(xmax/y_tilesize,1)
    Start3D()
    ;change la taille des tiles
    For T_i=1 To 3
      TransformSprite3D(T_i,X_Tilesize/2,0,X_Tilesize,Y_Tilesize/2,X_Tilesize/2,Y_Tilesize,0,Y_Tilesize/2)
    Next T_i
    ;change la taille des arbres
    ratiox.f=X_tilesize/64
    ratioy.f=y_tilesize/32
    ZoomSprite3D(150,256*ratiox,256*ratioy)    
    Stop3D()
    ordredaffichage
  EndIf
  
  If XX>xmax-20
    If Scroll_X<1023 And Scroll_Y>0
      miliscrol_X-vitesse_scroll
      If miliscrol_X<=0
        Scroll_X+1:Scroll_Y-1
        IsoScroll_X+1
        miliscrol_X=X_Tilesize
      EndIf
    EndIf
  EndIf
  
  If XX<20
    If Scroll_X>0 And Scroll_Y<1023
      miliscrol_X+vitesse_scroll
      If miliscrol_X>=X_Tilesize
        miliscrol_X=0
        Scroll_X-1:Scroll_Y+1
        IsoScroll_X-1
      EndIf
    EndIf
  EndIf    
  
  If YY>ymax-20
    If Scroll_X<1023 And Scroll_Y<1023
      miliscrol_Y-vitesse_scroll/2
      If miliscrol_Y<=0
        Scroll_X+1:Scroll_Y+1:IsoScroll_Y+1:miliscrol_Y=Y_Tilesize
      EndIf
    EndIf
  EndIf
  
  If YY<20
    If Scroll_X>0 And Scroll_Y>0
      miliscrol_Y+vitesse_scroll/2
      If miliscrol_Y>=Y_Tilesize
        Scroll_X-1:Scroll_Y-1:IsoScroll_Y-1:miliscrol_Y=0
      EndIf
    EndIf
  EndIf
  ;}
  
  ;{-Affichage sprites 3D
  Start3D()
  ;affichage des tiles
  For i=0 To T_nb
    sx=Scroll_X+ordre_affichage(i)\X
    sy=Scroll_Y+ordre_affichage(i)\Y
    ;Si dans le tableau de jeu...
    If sx>=0 And sy>=0 And sy<=1023 And sx<=1023
      T_Cases=carte(sx,sy)\tile
      sxx=-sy*(X_Tilesize/2)+ sx*(X_Tilesize/2)-IsoScroll_X*X_Tilesize+xmax/2-X_Tilesize+miliscrol_X
      syy=sy*(Y_Tilesize/2) + sx*(Y_Tilesize/2)-IsoScroll_Y*Y_Tilesize+ymax/2-Y_Tilesize-Y_Tilesize/2+miliscrol_Y
      ;affiche la case de terrain
      DisplaySprite3D(T_Cases,sxx,syy)
    EndIf
  Next i
  
  ;affichage des éléments sur les tiles
  For i=0 To T_nb
    sx=Scroll_X+ordre_affichage(i)\X
    sy=Scroll_Y+ordre_affichage(i)\Y
    ;Si dans le tableau de jeu...
    If sx>=0 And sy>=0 And sy<=1023 And sx<=1023
      sxx=-sy*(X_Tilesize/2)+ sx*(X_Tilesize/2)-(IsoScroll_X*X_Tilesize)+xmax/2-X_Tilesize+miliscrol_X
      syy=sy*(Y_Tilesize/2) + sx*(Y_Tilesize/2)-IsoScroll_Y*Y_Tilesize+ymax/2-Y_Tilesize-Y_Tilesize/2+miliscrol_Y
      If carte(sx,sy)\element
        ;affiche l'élément sur cette case
        ChangeCurrentElement(sprite(),carte(sx,sy)\element)
        sxx1=sxx+sprite()\biasX*ratiox
        syy1=syy+sprite()\biasY*ratioy
        DisplaySprite3D(sprite()\spritedebase,sxx1,syy1)
      EndIf
    EndIf
  Next i
  ;affichage de la souris
  DisplaySprite3D(100,XX,YY)
  Stop3D()
  ;}
  
  ;{-affiche le texte
  If Val(FormatDate("%ss", Date()))=sek
    FPS+1
  Else
    FPS$=Str(FPS)
    FPS=0
  EndIf
  sek=Val(FormatDate("%ss", Date()))
  StartDrawing(ScreenOutput())
  DrawText(1,1,"FPS: "+FPS$)
  DrawText(1,15,"nombre de tiles affichées: "+Str(T_nb))
  StopDrawing()
  ;}  
Until KeyboardPushed(#PB_Key_Escape)
Dernière modification par Fig le jeu. 12/mai/2011 16:31, modifié 5 fois.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
SPH
Messages : 4949
Inscription : mer. 09/nov./2005 9:53

Re: [jeu] 2D : faire un zoom sur une map

Message par SPH »

Merci fig pour ton exemple. Moi perso, j'avais mal lu l'intitulé; croyant que blendman voulait une mini map. Mais effectivement, il ne veux pas ca mais un zoom. :oops:

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [jeu] 2D : faire un zoom sur une map

Message par blendman »

Fig : merci pour ton exemple :) mais finalement, je ne pense pas faire de zoom, c'est un peu galère à mettre en place :p.

Sinon, pour la mini-map, la technique que je pense utiliser par la suite, c'est simple un clipsprite() sur une image de la map pré-rendue et quelques sprites de couleur en carré genre 8*8 pour les objets importants : mobs, perso, porte, etc.., qui bougeraient en pourcentage par rapport à leur déplacement.

A ce propos, djes, tu parles de position en relatif, c'est à dire ?

Ah oui, une autre question :
- j'utilise des variables dont le type est .point
exemple position.point
et j'accède comme ça :
position\x
position\x

Mais c'est quoi le type de x et y car du coup, j'ai des bugs dans le déplacement de certains mobs, etc.. c'est space..
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: [jeu] 2D : faire un zoom sur une map

Message par djes »

En relatif, ça veut dire utiliser des variables au lieu de valeurs "en dur", et n'avoir si possible qu'une valeur absolue, et tout faire en rapport à celle-ci.
Par exemple, quand tu fais un champ d'étoiles, tu définis un début et une fin : tu peux dire qu'elles vont par exemple de 0 à 1024. Si tu prends comme référence le début (0), la fin devient "debut + 1024" ; ceci te permet de déplacer le champ d'étoile en changeant la variable début. Si maintenant tu remplaces 1024 par une variable "largeur", tu peux adapter ton champ à n'importe quel écran en changeant cette largeur. Si maintenant tu mets la fin à "Début + FacteurZoom * Largeur", tu peux encore faciliter le contrôle. Enfin tu vois le truc quoi ;)

Au delà de ça, avec des matrices on peut facilement jouer sur toutes les variables d'un espace à n dimensions.

Sinon, pour la structure point, va dans le menu outils -> visualisateur de structures.
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: [jeu] 2D : faire un zoom sur une map

Message par Fig »

Voila j'ai mis à jour mon code, il est plus lisible car j'ai retiré les bouts de codes inutiles, il est optimisé pour le zoom, les arbres ont la bonne taille. 8)

Blendman> C'est la méthode que j'emploie. Rien n'est en dur ce qui permet d'afficher sur n'importe quel résolution d'écran et de zoomer avec n'importe quel taille de tile. :wink: Evidamment il faut imaginer avec des jolis graphiques...
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: [jeu] 2D : faire un zoom sur une map

Message par Cool Dji »

Nice Fig :D
Only PureBasic makes it possible
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [jeu] 2D : faire un zoom sur une map

Message par blendman »

FIG : merci pour la mise à jour, finalement, j'essaierai peut être par la suite d'intégrer un zoom avec ta méthode, (mais ce ne sera pas pour tout de suite, j'ai encore beaucoup à faire :)).

DJES : merci pour l'explication, je comprends mieux. par contre, il est difficile pour la position de mes objets (décors, arbres, buissons, sol, etc..) d'utiliser des variables, à moins comme tu le dis d'utiliser la variable origine(0,0)+position(x,y) par exemple.

pour la structure point, c'est donc du .l
J'imagine que c'est la raison pour laquelle le déplacement ne marche que pour certains mobs et pas d'autres, car il faut que le déplacement soit en .f pour que ça marche pour certains mobs, c'est bizarre...

Je vais poster un code pour voir s'il y a une autre technique :).
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Re: [jeu] 2D : faire un zoom sur une map

Message par case »

pourquois tu definie pas une structure avec un x et y en .f et que tu remplace pas tout le point par celle ci ?

structure cord
x.f
y.f
endstructure

et ensuite search >.point replace >.cord


ca te prendra 5 minutes a faire en changeant manuellement ou 10 secondes en remplacer tout si tu as confiance dans le fait que .point n'est utilisé que dans ce cas la

fais une backup de ton source avant si tu flippe vraiment :)
ImageImage
Répondre