[jeu] 2D : displaysprite3d() et drawtext()

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: [jeu] 2D : displaysprite3d() et drawtext()

Message par comtois »

y'a aussi ce truc là qui est pas mal pour créer sa police de caractères et l'afficher avec quelques effets sympas (code source fourni)

http://www.purebasic.fr/english/viewtop ... 12&t=43223
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 : displaysprite3d() et drawtext()

Message par blendman »

salut

Je me permets de relancer ce sujet car j'essaie en vain de faire tourner le code de case :)

Savez-vous comment je dois corriger ça ?

le code :

Code : Tout sélectionner

;{ infos
; font generator et bitmap font text, adapté d'un code de case
; case & blendman 2011
; pb 4.60
;}

;{ structures si besoin, pour font2D et font Sprite3D
; Structure fnt3d
;   f2d.i
;   f3d.I
; EndStructure
; Global Dim ascii.fnt3d(255)
;}

;{ enumeration
#window =0
;}

;{ variables globales
Global Dim ascii_.i(255)
Global key$=" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@âàéèëêûùôöîï!:;,.?&é'(-è_çà)01234567890=+-*/"+Chr(34)
Global debugued
;}

;{ init et window
InitSprite(): InitSprite3D(): InitKeyboard() : UseJPEGImageDecoder() : UsePNGImageDecoder() : UsePNGImageEncoder()  : UseJPEGImageEncoder()

If OpenWindow(#window, 0, 0, 200,100, "Bitmap Font", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget)
  If OpenWindowedScreen(WindowID(#window),0,0,200,100,0,0,0) = 0
    End
  EndIf
Else
  End
EndIf
;}

;{ font et sprite
font=LoadSprite(#PB_Any,"font0.bmp")
For a=0 To Len(key$)-1
  ClipSprite(font,a*16,0,16,16)
  DisplaySprite(font,0,0)
  ;ascii_(Asc(Mid(key$,a,1))) = GrabSprite(#pb_any,0,0,16,16) 
  GrabSprite(Asc(Mid(key$,a,1)),0,0,16,16) 
Next a
FreeSprite(font)
;}

;{ procedures
Procedure DisplayText(letext$,x,y)
  For a=0 To Len(letext$)-1
    ;ch=ascii_(Asc(Mid(key$,a,1)))
    ch = Asc(Mid(letext$,a,1))
    If debugued = 0      
      Debug ch
    EndIf    
    If IsSprite(ch) ; vérifie que le sprite est valide pour eviter une erreur si le caractere n'est pas dans la font bitmap...
    DisplayTransparentSprite(ch,(a-1)*16+x,y)
    EndIf
  Next a
  debugued = 1
EndProcedure
;}

Repeat  
  Event = WaitWindowEvent()
  ClearScreen(RGB(125,125,125))
  DisplayText("truc pas ok",2,10) 
  FlipBuffers()
Until Event = #PB_Event_CloseWindow 
Je l'ai un peu adapter mais adaptation ou non, ça ne marche correctement.

l'image que j'utilise :
http://blendman.free.fr/dev/pb/bug/font0.bmp

Merci d'avance :)
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Re: [jeu] 2D : displaysprite3d() et drawtext()

Message par case »

en fait mon exemple fonctionne avec une font dont tout les caractères font 16x16 pixel
ta font a un espacement variable, le i est plus étroit que le A tu dois donc prendre en compte une donnée supplémentaire
la largeur des caractères
ImageImage
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [jeu] 2D : displaysprite3d() et drawtext()

Message par blendman »

case a écrit :en fait mon exemple fonctionne avec une font dont tout les caractères font 16x16 pixel
ta font a un espacement variable, le i est plus étroit que le A tu dois donc prendre en compte une donnée supplémentaire
la largeur des caractères
ça m'intéress ça :)

Comment peut-on récupérer le caractère d'une font ?
Ou alors, dois-je le faire à la main, en ajoutant par exemple pour chaque lettre l'espace nécessaire dans une map par exmple ?
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Re: [jeu] 2D : displaysprite3d() et drawtext()

Message par case »

oui tu peux le faire ainsi, en 'comptant' le nombre de pixel de chaque caractère, ensuite pour l'affichage il faudra utiliser un compteur de position, ou tu ajoute la largeur de chaque caractère que tu affiche pour que le suivant soit a la bonne position, et non plus avec une simple multiplication comme dans mon exemple.


Code : Tout sélectionner

    DisplayTransparentSprite(ch,(a-1)*16+x,y)
ca donnerais plus un truc comme ca

Code : Tout sélectionner

    DisplayTransparentSprite(ch,x+pos,y)
    pos+largeur(ch)
ImageImage
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: [jeu] 2D : displaysprite3d() et drawtext()

Message par Fig »

Voila un petit code qui te permet d'ajouter facilement plusieurs polices de caractères sans t'occuper de l'espacement des caractères.
Ils sont automatiquement transformés en sprites.

Il faut initialiser la ou les polices que tu veux utiliser avec Init_Font(Nom_de_la_font$,Taille_de_la_font) et tu affiche un texte avec Messagetext(Message$,X,Y,Font,Limite_retour_à_la_ligne)

Code : Tout sélectionner

;{-initialisation
If InitSprite() = 0 Or InitKeyboard()=0 Or InitMouse()=0 Or InitSprite3D()=0 Or InitSound()=0:MessageRequester("Error","Error DirectX",0):EndIf
ExamineDesktops()
Global xmax=DesktopWidth(0),ymax=DesktopHeight(0) ;resolution ecran
;ouvre un écran
OpenScreen(xmax,ymax,DesktopDepth(0),"Test",#PB_Screen_WaitSynchronization,60)
;}
Structure Police1
  largeur.i[256]
  hauteur.i
EndStructure
#first_sprite=0;Important c'est le premier sprite des caractères, on lui donne la valeur qu'on veut.
Global NewList Police.Police1()

Procedure Init_Font(police.s,size.i)
  AddElement(Police())
  t=ListSize(Police())-1
  LoadFont(t,police,size) ;pas de test d'echec, windows n'en renvoit jamais de toute façon.
  ;On enregistre dans une table la largeur des caractères Ascii de la font (sans caractères de controle de 0 à 31)
  StartDrawing(ScreenOutput())
  DrawingFont(FontID(t))
  Police()\hauteur=TextHeight(Chr(32))
  For i=32 To 255
    Police()\largeur[i]=TextWidth(Chr(i))
    If Police()\largeur[i]=0:Police()\largeur[i]+1:EndIf ;attention le caractère 129 à une largeur de 0 !!
  Next i
  StopDrawing()
  first_sprt=#first_sprite+t*224
  ;on créé tous les sprites des caractères
  For i=32 To 255
    CreateSprite(first_sprt,Police()\largeur[i],Police()\hauteur)
    TransparentSpriteColor(first_sprt,#Black)
    StartDrawing(SpriteOutput(first_sprt))
    DrawingFont(FontID(t))
    DrawText(0,0,Chr(i))  
    StopDrawing()
    first_sprt+1
  Next i
EndProcedure

Procedure Messagetext(message$,x,y,police,longueur_ligne)
  SelectElement(Police(),police)
  colonne=x:ligne=y
  For i=1 To Len(message$)
    caractere=Asc(Mid(message$,i,1))
    DisplayTransparentSprite(caractere-32+#first_sprite+police*224,colonne,ligne)
    colonne+Police()\largeur[caractere]
    If colonne+Police()\largeur[32]>longueur_ligne+x:colonne=x:ligne+Police()\hauteur:EndIf
  Next i
EndProcedure

;on initialise les polices qu'on souhaite
Init_Font("Comic Sans MS",24)
Init_Font("Harrington",16)
Init_Font("Magneto",20)

Repeat
  ExamineKeyboard()
  FlipBuffers()
  ClearScreen(#Black)
  ;On affiche le texte voulu.
  Messagetext("Bonjour est ce que ça fonctionne bien ?",0,0,0,300)
  Messagetext("Bonjour est ce que ça fonctionne bien ?",40,100,1,400)
  Messagetext("Bonjour est ce que ça fonctionne bien ?",20,200,2,150)
Until KeyboardPushed(#PB_Key_Escape)
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
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: [jeu] 2D : displaysprite3d() et drawtext()

Message par blendman »

salut Fig, merci beaucoup pour cet exemple, c'est exactement ce que je cherchais !

Je l'ai un peu modifié :
- on peut utiliser une font placée dans un dossier si on le souhaite (utile pour être sûr que le joueur ait la bonne font sur son ordi)
- j'ai utiliser des sprites3D au lieu des sprites, ça permet d'utiliser les possibilités des sprites3D (rotations, zoom...)
- on peut sauvegarder les sprites créés si on le souhaite (utile pour créer une bitmap font si on le souhaite aussi). Pour le moment, cela crée une image (png avec transparence) par caractère. C'est vraiment pratique pour ensuite utiliser des bitmap font :). Je ferrai peut être si j'ai le temps par la suite la création d'une font bitmap (damier) avec quelques paramètres comme : taille de l'image, taille de chaque case de lettres.
- (edit) : ajout du retour automatique à la ligne, au lieu de couper les mots

le code (on pourrait le mettre dans astuces je pense) :

Code : Tout sélectionner

;{ bitmapfont utility
; By Fig , blendman
; pb 4.60
; 07/11/2011
;}

;{ constante
#window = 0
#loadfont = 0
#savefont = 1 
#fontSpace = 6 ; the global width of each character of the font
;}

;{ init
If InitSprite() = 0 Or InitKeyboard()=0 Or InitMouse()=0 Or InitSprite3D()=0 Or InitSound()=0 Or UsePNGImageEncoder() = 0 :MessageRequester("Error","Error DirectX",0):EndIf
If ExamineDesktops() = 0
  End
EndIf

;}

;{ declare
Declare CreateFont()
Declare messagetext(message$,x,y,longueur_ligne,size.a=1)
;}

;{ Open window
;Global xmax=DesktopWidth(0),ymax=DesktopHeight(0) ;resolution ecran
flag = #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget|#PB_Window_Maximize
OpenWindow(#window,0,0,DesktopWidth(0),DesktopHeight(0),"",flag)
OpenWindowedScreen(WindowID(#window),0,0,DesktopWidth(0),DesktopHeight(0),0,0,0)
;charge la font Comics avec une taille de 24 par exemple. Bien respecter le nom de la font avec Windows. 
; load a windows font. You must respect the exact name of the font
If #loadfont = 0
  LoadFont(1, "Impact", 13) ;pas de test d'echec, windows n'en renvoit jamais. / no echec
Else; autre technique : charger une font externe, depuis un dossier / load an external font
  AddFontResource_("font\blnd.ttf")
  LoadFont(1, "blnd", 12)
EndIf
CreateFont()
;}

;{ Loop
Repeat
  event = WaitWindowEvent()
  ExamineKeyboard() 
  ClearScreen(RGB(125,125,125))
  ; create a simple menu of a game :)
  Start3D()
  messagetext("Menu",WindowWidth(0)/2-Len("Menu")*#fontSpace,WindowHeight(0)/2-210,300)
  messagetext("Charger le jeu",WindowWidth(0)/2-Len("Charger le jeu")*#fontSpace,WindowHeight(0)/2-180,300)
  messagetext("Nouveau jeu",WindowWidth(0)/2-Len("Nouveau jeu")*#fontSpace,WindowHeight(0)/2-150,300)
  messagetext("A propos de nous",WindowWidth(0)/2-Len("A propos de nous")*#fontSpace,WindowHeight(0)/2-120,350)
  messagetext("Options & Aides",WindowWidth(0)/2-Len("Options & Aides")*#fontSpace,WindowHeight(0)/2-90,300)
  messagetext("Quitter",WindowWidth(0)/2-Len("Quitter")*#fontSpace,WindowHeight(0)/2-60,300)
  Stop3D()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or event = #PB_Event_CloseWindow
FreeFont(1)
;}

;{ procedures
Procedure CreateFont()
  Global Dim largeur(255)
  
  ;On enregistre dans une table la largeur des caractères Ascii de la font (sans caractères de controle de 0 à 31)
  StartDrawing(ScreenOutput())
  DrawingFont(FontID(1))
  Global hauteur=TextHeight(Chr(32))
  For i=32 To 255
    largeur(i)=TextWidth(Chr(i))
    If largeur(i)=0:largeur(i)+1:EndIf ;attention le caractère 129 à une largeur de 0 !!
  Next i
  StopDrawing()
  
  If #savefont = 1   
    CreateImage(1,256,256,32)
    StartDrawing(ImageOutput(1))  
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    Box(0,0,256,256,RGBA(0,0,0,0))
    StopDrawing()
  EndIf
    
  ;on créé tous les sprites des caractères
  For i=32 To 255
    CreateSprite(i,largeur(i)+2,hauteur+2,#PB_Sprite_Texture)
    CreateSprite3D(i,i)
    ;TransparentSpriteColor(i,#Black) ; uniquement si on crée un sprite normal, pas utile pour un sprite 3D
    StartDrawing(SpriteOutput(i))
    DrawingFont(FontID(1))
    DrawText(1,1,Chr(i)) 
    StopDrawing() 
    CreateDirectory("sprite")
    
    If #savefont = 1      ; font bitmap multi image
      CreateImage(0,largeur(i)+2,hauteur+2,32)
      StartDrawing(ImageOutput(0))  
      DrawingMode(#PB_2DDrawing_AlphaChannel)
      Box(0,0,largeur(i)+2,hauteur+2,RGBA(0,0,0,0))
      DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_AlphaBlend)
      DrawingFont(FontID(1))
      DrawText(1,1,Chr(i),RGBA(255,255,255,255)) 
      StopDrawing()
      SaveImage(0,"sprite\"+Str(i)+".png",#PB_ImagePlugin_PNG)
      ; font bitmap, unique image
      StartDrawing(ImageOutput(1))
      DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_AlphaBlend)
      DrawingFont(FontID(1))
      DrawText(1+16*((i-32)%16),1+16*(Round((i-32)/16,0)),Chr(i),RGBA(255,255,255,255)) 
      StopDrawing()    
    EndIf
  Next i
  If #savefont =1; font bitmap, unique image
    SaveImage(1,"fontbitmap"+Str(Random(500))+".png",#PB_ImagePlugin_PNG)
  EndIf  
EndProcedure
Procedure messagetext(message$,x,y,longueur_ligne,size.a=1)
  colonne=x:ligne=y
  For i=1 To Len(message$)
    caractere=Asc(Mid(message$,i,1))
    ; pour des sprites normaux / sprite
    ;DisplaySolidSprite(caractere,colonne,ligne,RGB(125,125,255))
    ;DisplayTransparentSprite(caractere,colonne,ligne)
    ; pour des sprites 3D  / sprite3D
    ZoomSprite3D(caractere,SpriteWidth(caractere)*size,SpriteHeight(caractere)*size)
    DisplaySprite3D(caractere,colonne,ligne)
    ZoomSprite3D(caractere,SpriteWidth(caractere),SpriteHeight(caractere))
    colonne+largeur(caractere)*size
    if caractere = 32
        If colonne+largeur(32)*size>longueur_ligne*size +x*size 
          colonne=x 
          ligne+hauteur 
        EndIf
    endif

  Next i
EndProcedure
;}

Encore un immense merci Fig ;)

EDIT : ajout du retour à la ligne automatique, au lieu de couper les mots ;)
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: [jeu] 2D : displaysprite3d() et drawtext()

Message par Fig »

Bien sûr tu peux le mettre dans la section astuce. :wink:

Case avait déjà donné toutes les indications nécessaires.

Pour ma part j'ai juste posté un code que j'utilise déjà dans mes progs en include en virant la partie d'initialisation bien sûr.

Je suis content que tu aies pu te réapproprier le code, c'est fait pour.
Le petit bémol c'est la limitation de la puissance de 2 pour la taille des sprites 3d. (limitation préhistorique mais que je respecte toujours)

Bonne soirée. :!:
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
Répondre