Page 1 sur 2

[OK] Redimensionner un sprite

Publié : mar. 30/juin/2015 11:40
par blendman
salut

Quand on crée un sprite, on lui donne des dimensions W et H.
Peut-on redimensionner le sprite, c'est à dire changer ces dimensions (internes j'imagine) comme on le fait avec resizeImage() ?

J'ai testé zoomSprite() et transformSprite() mais ni l'un ni l'autre ne modifie les dimensions réelles du sprite (pourtant, spriteWith() et spriteHeight( nous renvoient bien les bonnes dimensions, mais en fait non, le sprite est "juste" agrandi).

Du coup, pour agrandir un sprite, je suis obligé de le supprimer puis de le recréer, c'est quand même balot comme manip.

Il existe une autre technique ou est-ce une fonction manquante ?

Code : Tout sélectionner

InitSprite()
screenwidth = 1024
screenheight = 768

OpenWindow(0, 0, 0, screenwidth, screenheight, "Antialiased Line Demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)


If OpenWindowedScreen(WindowID(0),0,0,screenwidth, screenheight)
  
  w = 100
  h = 200
  CreateImage(0,w,h)
  
  
  StartDrawing(ImageOutput(0))
  
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  Circle(w/2,h/2,40,RGBA(255,120,120,255))
  StopDrawing()
  
  CreateSprite(0,w,h)
  
  StartDrawing(SpriteOutput(0))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  DrawAlphaImage(ImageID(0),0,0)
  StopDrawing()
  
  Debug Str(SpriteWidth(0))+"/"+Str(SpriteHeight(0))
  
  
  
  w = 200
  h = 300
  ResizeImage(0,w,h)
  
  ZoomSprite(0,w,h)
  
  StartDrawing(SpriteOutput(0))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  DrawAlphaImage(ImageID(0),0,0)
  StopDrawing()
  
  ; with transformSprite() = same result
  Debug Str(SpriteWidth(0))+"/"+Str(SpriteHeight(0))
  
  
  
  ; result should be :
  CreateSprite(1,w,h)
  StartDrawing(SpriteOutput(1))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  DrawAlphaImage(ImageID(0),0,0)
  StopDrawing()

  
  Repeat
    
    Repeat      
      event =WaitWindowEvent(1)
    Until event = 0 Or event = #PB_Event_CloseWindow
    
    ClearScreen(0)

    DisplayTransparentSprite(0,100,100)
    DisplayTransparentSprite(1,400,100)

    FlipBuffers()
    
  Until event = #PB_Event_CloseWindow

EndIf


EDIT (15/10/2015)

Solution : utiliser une map pour stocker les sprites et recréer le sprite à redimensionner :

Code : Tout sélectionner

InitSprite()
Structure sSprite
  Sprite.i ; id du sprite
  Image.i ;id de l'image
EndStructure
Global NewMap Sprite.sSprite()

Procedure CreateSprite2(sprite,w,h)
 
  NewSprite = CreateSprite(sprite,w,h,#PB_Sprite_AlphaBlending )
 
  If sprite = #PB_Any
    sprite = newsprite
  EndIf
 
  ; creation of the new sprite
  key$ = Str(Sprite)
  AddMapElement(sprite(), key$)
  Sprite(key$)\Sprite = sprite
  Sprite(key$)\Image = -1

  ProcedureReturn NewSprite
EndProcedure

Procedure SetSpriteSize(sprite,w,h)
 
  OriginalSpriteId = sprite
  key$ = Str(OriginalSpriteId)
 
  Idsprite = Sprite(key$)\Sprite
 
  FreeSprite(Idsprite)
   
    If OriginalSpriteId > 10000
      sprite = #PB_Any
    EndIf
   
    NewSprite= CreateSprite(sprite,w,h,#PB_Sprite_AlphaBlending)
   
    If sprite = #PB_Any
      sprite = NewSprite
    EndIf
   
    Sprite(key$)\Sprite = sprite
   
  ; puis on redessine le sprite si besoin
    If Sprite(key$)\Image <> -1
      If StartDrawing(SpriteOutput(sprite))
        ; erase the sprite
        DrawingMode(#PB_2DDrawing_AllChannels)
        Box(0,0,OutputWidth(),OutputHeight(),RGBA(0,0,0,0))
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        DrawAlphaImage(ImageID(Sprite(key$)\Image),0,0)
        StopDrawing()
      EndIf
    EndIf   
EndProcedure

screenwidth = 640
screenheight = 480
OpenWindow(0, 0, 0, screenwidth, screenheight, "Game", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0),0,0,screenwidth, screenheight)=0
  MessageRequester("Error", "Can't Open Screen!", 0)
  End
EndIf

ui = CreateSprite2(#PB_Any,10,50)
; Change size of the sprite
SetSpriteSize(ui,128,60)

Repeat
  Repeat
    event = WaitWindowEvent(1)
    If  event = #PB_Event_CloseWindow
      End
    EndIf   
  Until event = 0
  DisplayTransparentSprite(ui,100,100) 
  FlipBuffers()
  ClearScreen(RGB(100,100,100))
ForEver

Re: Redimensionner un sprite

Publié : mar. 30/juin/2015 11:58
par falsam
Il n'y a pas de fonction manquante. Un zoom est un zoom. Je pense que c'est à toi de fournir une image suffisamment riches en pixels de manière à être zoomer correctement.

Re: Redimensionner un sprite

Publié : mar. 30/juin/2015 12:37
par blendman
falsam a écrit :Il n'y a pas de fonction manquante. Un zoom est un zoom. Je pense que c'est à toi de fournir une image suffisamment riches en pixels de manière à être zoomer correctement.
Ben si, un resizeSprite(), ça me manque :)

Je t'explique ce que je fais :
- dans animatoon, je veux créer un texte, avec une certaine police (disons du arial en 24)
- je crée une image grâce à textwidth() et textHeight(), je sais quelle taille l'image(et donc le sprite) va faire précisément pour afficher le texte.
- puis, je crée un sprite pour afficher cette image

Mais si je change la taille de ma police ou le texte, je dois recalculer la taille de mon image et pour le sprite, ça ne marche pas : les dimensions réelles du sprite (position réel des vertex 'j"imagine) ne changent pas, ce sont les dimensions d'affichage qui changent (d'ailleurs spritewidth() et spriteheight() sont trompeurs car ils nous donnent de nouvelle dimensions alors qu'en fait ben non..
Du coup, si je change mon image, je suis obligé de supprimer mon sprite et de le recréer avec la nouvelle taille.
Comme si on devait supprimer une image et la recréer à la nouvelle, au lieu d'utiliser resizeImage() ^^.

J'avais cru que TransformSprite() changeait la position réelle des vertex, mais non même pas, car ça ne marche pas non plus avec TransformSprite().

Re: Redimensionner un sprite

Publié : mar. 30/juin/2015 13:52
par Mesa
Je pense qu'il n'y a pas de réponse simple à ta question.

En effet, historiquement, les sprites ont été inventés pour déplacer rapidement une (petite) image sur un fond. Et rien d'autre. Puis le canal alpha est arrivé pour améliorer la qualité de l'animation. Quand la quantité de mémoire embarquée dans les cartes graphiques a été suffisante, les programmeurs en ont profité, et de nos jours un sprite est sous-entendu être une image en mémoire dans la carte graphique. D'où la très grande rapidité de l'affichage et des animations, mais on ne peut pas faire ce que l'on veut.

Le hardware de la carte graphique transforme les sprites mais à ma connaissance, il ne les crée pas, c'est le programmeur qui les crées. Changer la taille d'un sprite sans transformation par la carte n'a pas de sens car c'est au programmeur de créer son screen tout entier (contenant des sprites).

Une carte graphique ne peut pas faire des tâches "générales" sauf depuis l'arrivé de CUDA https://fr.wikipedia.org/wiki/Compute_U ... chitecture

Des PBsiens se sont attaqués à CUDA sur le forum UK. Du coup , ce que tu cherches à faire est peut être possible avec CUDA.

A voir...

M.

Re: Redimensionner un sprite

Publié : mar. 30/juin/2015 15:22
par microdevweb
Je ne voie qu'une solution, supprimer le sprite. Modifier la taille de l'image, recharger le sprite.

Re: Redimensionner un sprite

Publié : mar. 30/juin/2015 16:26
par blendman
C'est ce que je fais, mais avec des sprites créés dynamiquement (avec #pb_any), n'est-ce pas gênant ?
Au bout d'un moment, ne risque-t-on pas d'avoir trop d'index de créer ou sont-ils réaffectés s'ils ne sont plus utilisés ?

Re: Redimensionner un sprite

Publié : mar. 30/juin/2015 17:26
par microdevweb
Tu dois le supprimer avant FreeSprite(monSprite), autrement tu va avoir une floppée de sprite qui resteront en mémoire. Tu peux également vérifier si le sprite existe avant de le supprimer

Code : Tout sélectionner

if isSprite(monSprite)
    FreeSprite(monSprite)
endif
monSprite=LoadSprite(#Pb_Any,"monImage.png")

Re: Redimensionner un sprite

Publié : mar. 30/juin/2015 18:22
par blendman
microdevweb a écrit :Tu dois le supprimer avant FreeSprite(monSprite), autrement tu va avoir une floppée de sprite qui resteront en mémoire. Tu peux également vérifier si le sprite existe avant de le supprimer

Code : Tout sélectionner

if isSprite(monSprite)
    FreeSprite(monSprite)
endif
monSprite=LoadSprite(#Pb_Any,"monImage.png")
Oui, c'est exactement ce que je fais ;)

Re: Redimensionner un sprite

Publié : mar. 30/juin/2015 21:45
par microdevweb
Il ne devrait pas avoir de problème alors...

Re: Redimensionner un sprite

Publié : mar. 30/juin/2015 22:37
par crisot
Sinon tu utilises des fonctions 3D simples. Un polygones plat, ce n'est finalement qu'un sprite moderne, et ça te permet de l'afficher dynamiquement de la taille que tu veux.

A mon sens les fonctions "pures 2D" de n'importe quel Os/Langage n'ont plus aucun intérêt par rapports aux fonctions 3D, surtout quand elles sont aussi facilement utilisables qu'en PB.

Re: Redimensionner un sprite

Publié : mar. 30/juin/2015 22:51
par falsam
Et on peut voir plus facilement le derriere d'un sprite 2D :mrgreen:

Re: Redimensionner un sprite

Publié : mer. 01/juil./2015 12:32
par blendman
crisot a écrit :Sinon tu utilises des fonctions 3D simples. Un polygones plat, ce n'est finalement qu'un sprite moderne, et ça te permet de l'afficher dynamiquement de la taille que tu veux.

A mon sens les fonctions "pures 2D" de n'importe quel Os/Langage n'ont plus aucun intérêt par rapports aux fonctions 3D, surtout quand elles sont aussi facilement utilisables qu'en PB.
oui, je pourrais faire ça, mais ça voudrait dire réécrire presque tout mon soft (encore une fois, ça ne fera que la 7ème fois ^^), qui fait plus de 14 000 lignes, enfin réécrire les parties utilisant les sprites et y'en a un paquet, sans être certain de retrouver toutes les fonctions des sprites facilement (blendmodes).
J'y ai pensé, mais j'hésite quand même un peu ^^.

Ce serait plus rapide par rapport aux sprites ? Je peux dessiner facilement sur un plan comme sur un sprite ?
Tu aurais un exemple ?

Re: Redimensionner un sprite

Publié : mer. 01/juil./2015 12:44
par falsam
Je me demande même si ça ne va pas te facilité la création de maps isométriques

Re: Redimensionner un sprite

Publié : mer. 01/juil./2015 13:14
par blendman
falsam a écrit :Je me demande même si ça ne va pas te facilité la création de maps isométriques
d'image pour map iso, tu veux dire ?
Ah oui, c'est vrai que ça pourrait être super pratique, je n'y avais pas pensé ^^.
Cela dit, je ne vois toujours pas comment utiliser l'engine 3D pour dessiner.

Re: Redimensionner un sprite

Publié : mer. 01/juil./2015 13:19
par falsam
Je sens que je vais lacher 5 minutes lixu pour une démo de ce type
:arrow: http://falsam.com/Vache/

Utilises la souris pour changer l'orientation de la scene.