Page 1 sur 1

Aide pour débutants, et question débiles ;)

Publié : jeu. 07/avr./2016 22:03
par Uhuru
Hello les codeurs!

Voici que je retourne à mes premiers amours (coding il y a 20 ans sur Amiga) et vu que j'ai tout perdu je me relance doucement avec PureBasic ! Je m'appelle Marc et je vous remercie d'avance pour votre aide ;)

Avant de commencer à coder mes effets j'ai lu la doc en ligne, en tout cas la partie la plus simple (je ne me lance pas dans la 3D)

Mon idée c'est de faire une sorte d'intro avec des effets sur des pixels, lignes, dots ...

Par contre j'ai des questions toutes c..... sur certaines fonctions

Je me suis fait un petit affichage d'une image sur un fond blanc (ouhaaa) en utilisant le code ci dessous et un fichier PNG sur fond bland de taille 507x173

Mon premier problème c'est que sur ma machine j'ai un effet de flickering pendant le fading, on voit le logo clignoter au moins une fois ... Normal ? Pas normal ?

Seconde question, si je passe en fullscreen, on me dit 'pas de gadgetlist ...', comment je peux faire sans me retaper tout le code ou sans GROS changement ?

Code : Tout sélectionner

UsePNGImageDecoder()
InitSprite()

Enumeration
#Win
#ImgGadget
#MyImg
EndEnumeration

Global logo = CatchImage(#PB_Any, ?datalogo)


                    
Procedure Fade(speed)
                
 For i = 1 To 255 Step 5

     If StartDrawing(ImageOutput(#MyImg))

           DrawingMode(#PB_2DDrawing_AlphaBlend)

               DrawImage(ImageID(logo), 0, 0, 507, 173)
               Box(0, 0, 507, 173, RGBA(255,255,255,i))

           StopDrawing()
     EndIf

     SetGadgetState(#ImgGadget, ImageID(#MyImg))
     Delay(speed)
 Next


EndProcedure

;==== gestion du fullscreen ou non

FS=1

If FS=1
	OpenWindow(1,0,0,640,480,"",#PB_Window_BorderLess|#PB_Window_ScreenCentered|#PB_Window_WindowCentered)
	OpenWindowedScreen(WindowID(1),0,0,640,480,true,0,#PB_Screen_SmartSynchronization)
	ShowCursor_(0)	;-no mouse cursor!
Else
  OpenScreen(640,480,32,"",#PB_Screen_SmartSynchronization,60)
  ShowCursor_(0)	;-no mouse cursor!
EndIf

;==== méthode pour éviter le flahs ecran noir avant l'affiche du logo sur fond blanc
ClearScreen($FFFFFF)
CreateImage(#MyImg, 507,173, 32)
FlipBuffers()
;==== affichage du logo
ImageGadget(#ImgGadget, (640-507)/2,(480-173)/2, 507, 173, 0)

;==== on lance le fading out (on va vers le blanc total)
Fade(25)

;==== timer general pour les effets
FPSTimer = ElapsedMilliseconds()
Start_Time.f = ElapsedMilliseconds()


Repeat
  Current_Time.f = ElapsedMilliseconds()
  Time_Passed.f = Current_Time - Start_Time
Until Time_Passed.f=5000 Or GetAsyncKeyState_(#VK_ESCAPE)
End

DataSection
  datalogo:
	IncludeBinary"gfx\logo.png"
EndDataSection
Pour finir j'ai une question plus 'générale'. imaginons un code avec 4 effets, que vous souhaitez déclencher sur une variable X (X pouvant être un temps en secondes). Comment faites vous votre boucle de repeat until keypressed (code faux mais c'est l'algo qui m'interesse)

Code : Tout sélectionner

repeat
effet()
delay(x)
effet2()
delay (x)
until keypressed

Re: Aide pour débutants, et question débiles ;)

Publié : ven. 08/avr./2016 0:06
par falsam
Bonjour et bienvenue Uhuru.
Uhuru a écrit :Mon premier problème c'est que sur ma machine j'ai un effet de flickering pendant le fading, on voit le logo clignoter au moins une fois ... Normal ? Pas normal ?
Normal parce que tu n'es pas encore au point sur la façon de coder les sprites.

Dans ton code tu as pris un shaker avec un tiers de fonctionnalités images, un tiers de fonctionnalités ImageGadget et un tiers de fonctionnalité sprites. Tu as secoué le tout et prié très fort pour que ça fonctionne. Hooooo Miracle, il en sort quelques chose.

Tous cela est à prendre avec de l'humour bien sur. Des bêtises j'en ai fait pas mal aussi. :wink:

Petit code affichant trois effets ce qui permet de répondre à la question
Uhuru a écrit :Pour finir j'ai une question plus 'générale'. imaginons un code avec 4 effets, que vous souhaitez déclencher sur une variable X (X pouvant être un temps en secondes). Comment faites vous votre boucle de repeat until keypressed

Code : Tout sélectionner

UsePNGImageDecoder()

InitSprite() 
InitKeyboard()
InitMouse()

Enumeration
  #Win
  #ImgGadget
  #MyImg
EndEnumeration

Global logo , Intensite = 255

Global FadeOut = 1, FadeIn = 2, VerticalLine = 3

;==== gestion du fullscreen ou non
FS=1

If FS=1
  OpenWindow(1,0,0,640,480,"",#PB_Window_BorderLess|#PB_Window_ScreenCentered|#PB_Window_WindowCentered)
  OpenWindowedScreen(WindowID(1),0,0,640,480,true,0,#PB_Screen_SmartSynchronization)
Else
  OpenScreen(640,480,32,"",#PB_Screen_SmartSynchronization,60)
EndIf

;Creation du sprite
logo = CatchImage(#PB_Any, ?datalogo)
CreateSprite(#MyImg, ImageWidth(logo), ImageHeight(logo), #PB_Sprite_AlphaBlending )
StartDrawing(SpriteOutput(#MyImg))
DrawImage(ImageID(Logo), 0, 0)
StopDrawing()

;Intialisation du premier effet
Effet = FadeOut

;Boucle evenementielle
Start_Time = ElapsedMilliseconds()
Repeat
  
  ClearScreen($FFFFFF)
  
  Select Effet
    Case FadeOut
      If (ElapsedMilliseconds() - Start_Time > 10)
        Intensite - 1
        Start_Time=ElapsedMilliseconds()
        If Intensite = 0
          Effet = Fadein 
        EndIf
      EndIf
      
    Case FadeIn
      If (ElapsedMilliseconds() - Start_Time > 10)
        Intensite + 1
        Start_Time=ElapsedMilliseconds()
        If Intensite = 255
          Effet = VerticalLine
        EndIf
      EndIf
      
    Case VerticalLine
      If (ElapsedMilliseconds() - Start_Time > 10)
        x + 2
        StartDrawing(SpriteOutput(#MyImg))
        LineXY(x, 0, x, SpriteHeight(#MyImg), RGB(0, 0, 0))
        StopDrawing()
      EndIf
      If x = SpriteWidth(#MyImg)
        Effet = #False
      EndIf
  EndSelect
    
  DisplayTransparentSprite(#MyImg, 0, 0, Intensite)
  
  ExamineKeyboard()
  FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape)

DataSection
  datalogo:
  IncludeBinary #PB_Compiler_Home + "Examples\3D\Data\purebasic3dlogo.png"
EndDataSection

Re: Aide pour débutants, et question débiles ;)

Publié : ven. 08/avr./2016 7:40
par Uhuru
Bonjour Falsam

Tout d'abord un grand merci pour avoir regardé mon cas :)
De l'humour j'en ai, et plein, et je sais aussi faire la part des choses (avantage de l'âge) donc je suis tout à fait en phase avec ce que tu as dis. Je me suis planté en beauté :D

Même si j'ai pris du temps pour lire la doc, j'ai fais ce que tout débutant (en tout cas les moyens ;)) fait, prendre des bouts de codes donnés dans les exemples de la doc (le pdf) et mélanger dans la même source (shake shake shake)

Même dans les tutoriaux il est dommage qu'on explique pas (où alors je n'ai pas vu du tout) pourquoi ici c'est sprite, ici c'est screen, ici image. A l'heure actuelle je t'avoue que je n'ai pas encore bien compris la différence entre les opérations sur les images et sur les sprites (différences/avantages/inconvénients).

Je vais regarder le code que tu m'as transmis et je vais tacher d'avancer. Ne le prends pas mal si je te pose encore quelques questions pour bien comprendre le fonctionnement (normalement une fois qu'on m'a expliqué et que j'ai compris, je ne repose jamais deux fois la même question :))

Très bonne journée à toi (et aux autres qui ont lu / vont lire les échanges ici :))

Re: Aide pour débutants, et question débiles ;)

Publié : ven. 08/avr./2016 8:19
par djes
Bienvenue Uhuru ! :)

Re: Aide pour débutants, et question débiles ;)

Publié : ven. 08/avr./2016 9:21
par Bernie
welcome Uhuru

Re: Aide pour débutants, et question débiles ;)

Publié : ven. 08/avr./2016 9:28
par Uhuru
Merci pour votre accueil :) Super plaisir :)

@falsam

Dans l'effet verticalLine, on se base sur la largeur du sprite (forcement comme je fais comme tout le monde, le mien à une largeur impaire), hors tu ajoutes 2 à x à partir de 0 et tu lui demandes de finir quand X = largeur.

L'effet tourne donc en boucle sans jamais sortir, j'ai bon (et c'est adaptable à tout sprite) si je remplace par le code ci dessous ?

Code : Tout sélectionner

If x = SpriteWidth(#MyImg) - 1
En fait je me suis un peu amusé à rajouter le balayage inverse en effaçant à blanc les X pairs, puis les x impaires mais dans le sens inverse. J'ai bien entendu rajouter le verticalLine2 = 4 en global

Code : Tout sélectionner

    Case VerticalLine
      If (ElapsedMilliseconds() - Start_Time > 10)
        x + 2
        StartDrawing(SpriteOutput(#MyImg))
        LineXY(x, 0, x, SpriteHeight(#MyImg), RGB(255, 255, 255))
        StopDrawing()
      EndIf
      If x = SpriteWidth(#MyImg) - 1
        x = SpriteWidth(#MyImg)
        Effet = VerticalLine2
      EndIf
      
    Case VerticalLine2
      If (ElapsedMilliseconds() - Start_Time > 10)
        x - 2
        StartDrawing(SpriteOutput(#MyImg))
        LineXY(x, 0, x, SpriteHeight(#MyImg), RGB(255, 255, 255))
        StopDrawing()
      EndIf
      If x = 1
        Effet = #False
      EndIf
et là maintenant je m'interroge sur certains points, restons sur l'effet 1 (le fadeout)

Code : Tout sélectionner

    Case FadeOut
      If (ElapsedMilliseconds() - Start_Time > 10)
        Intensite - 1
        Start_Time=ElapsedMilliseconds()
        If Intensite = 0
          Effet = Fadein 
        EndIf
      EndIf
A quoi servent ici : If (ElapsedMilliseconds() - Start_Time > 10) et Start_Time=ElapsedMilliseconds()

Si je lis bien, on rentre ici dès le début du programme (initialisation du premier effet)
Ensuite on regarde si il y a plus de 10 entre le timer au début du programme et maintenant
puis, on remets le start_time au temps actuel donc le premier IF sera toujours = 0 non ?

Re: Aide pour débutants, et question débiles ;)

Publié : ven. 08/avr./2016 11:31
par blendman
bienvenue sur le forum Uhuru :)

Alors, pour simplifier, dans purebasic :
- une image, ce sont "juste" des informations de couleur et d'alpha (et bien sûr de taille (width/height)). En gros, tu peux stocker toutes ces informations (chaque pixel) dans un tableau avec par exemple 4 paramètres pour chaque entrée (R,G,B,A) par exemple.

Ensuite, pour "dessiner" ou "afficher" l'image, purebasic permet de le faire :
- sur le screen directement
- sur la fenêtre
- sur un imagegadget()
- sur un canvas (une autre sorte de gadget qui permet d'afficher des images, mais en plus balèze que l'imagegadget())
- sur un bouton ou tout autre gadget acceptant les images
- sur un menu

Ne pas confondre dessiner et afficher l'image.

On peut dessiner sur plusieurs sorties, mais on ne peut "afficher" que sur certaines d'entre elles.

Pour "dessiner", il faut aller voir du coté de StartDrawing() ou StartVectorDrawing() (pour dessiner avec des formes vectorielles)
Sur ceux-ci ça se voit tout de suite :
- ScreenOutput() : dessiner sur l'écran (en fait c'est = à de l'affichage sur écran ^^)
- WindowOUtput() : dessiner sur la fenêtre (en fait c'est = à de l'affichage sur la fenêtre ^^)
- canvasoutput() : dessiner sur un canvas

sur ceux-ci, il faudra afficher le résultat sur une des 3 sorties précédentes
- ImageOutput() : dessiner sur une image (on peut dessiner une image sur une autre image ;), mais ensuite, il faudrait utiliser un gadget ou un sprite ou le screen ou la fenêtre pour l'afficher.)
- SpriteOutput() : dessiner sur un sprite. Attention : ne peut être afficher QUE sur le screen (avec clearscreen() , displaysprite(), flipbuffers())

cas spécial :
- printoutput() : faire une sortie impression j'imagine ^^.


Pour afficher, on peut utiliser :
- le screen : c'est la même technique que pour dessiner, avec startdrawing() pour les dessins ou avec displaysprite() pour les sprites.
- la fenêtre : ce sera la même technique que pour le dessin avec startdrawing.
- un gadget le permettant (imagegadget(), canvas, buttonimagegadget()...) : Chaque gadget a sa propre technique pour afficher l'image. Certains su'tilisent avec startdrawing(), d'autres pas.

On ne peut pas afficher un gadget sur le screen, mais à côté oui (si le screen est plus petit que la fenêtre par exemple).


Afficher une image sur un sprite :
l

Code : Tout sélectionner

LoadSprite(SpriteId, Fichier de l'image) ; on charge l'image sur le sprite
; puis dans ta boucle principale : 
clearscreen(0) ; on efface l'écran
displaysprite(spriteid,x,y)
flipbuffers() ; on flip le buffer :), en gros, on affiche tout sur l'écran (voir la doc pour plus d'informations)
Voilà, j'espère que ces petites explications pourront un peu t'aider à mieux comprendre tout ça ;).

Re: Aide pour débutants, et question débiles ;)

Publié : ven. 08/avr./2016 11:58
par omega
Félicitations Blendman ! Une excellente leçon !

Bravo !

Re: Aide pour débutants, et question débiles ;)

Publié : ven. 08/avr./2016 16:11
par falsam
Uhuru a écrit :Même dans les tutoriaux il est dommage qu'on explique pas (où alors je n'ai pas vu du tout) pourquoi ici c'est sprite, ici c'est screen, ici image.
■ Screen et Sprite sont indissociables et sont utilisés pour une application 2D (Jeu ou animation 2D). Un sprite peut aussi intervenir dans une application 3D pour afficher un score par exemple.

■ Hors context 2D ou 3D, une image peut être affichée dans une application avec ImageGadget()

Code : Tout sélectionner

Enumeration Window ;Déclaration d'une ou des fenetres 
  #MainForm
EndEnumeration

Enumeration Gadget ;Déclaration du ou des gadgets
  #MyImage  
EndEnumeration

If OpenWindow(#MainForm, 0, 0, 400, 90, "Afficher une image", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)        
  UsePNGImageDecoder()  
  Image = LoadImage(#PB_Any, #PB_Compiler_Home + "Examples\3D\Data\purebasic3dlogo.png")
  
  ImageGadget(#MyImage, 10, 10, 381, 68, ImageID(Image))
  
  Repeat : Until WaitWindowEvent(10) = #PB_Event_CloseWindow
EndIf
■ Si tu souhaites faire de petites animations alors tout comme les sprites mais moins pratique, cette image peut être modifiée avec un système de timer par exemple.

Code : Tout sélectionner

Enumeration Window
  #MainForm
EndEnumeration

Enumeration Gadget
  #MyImage  
EndEnumeration

Enumeration Timer 
  #MyTimer
EndEnumeration

Global Image, Intensite = 255, Increment = 1 

Declare Effet()

If OpenWindow(#MainForm, 0, 0, 400, 90, "Afficher une image", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)      
  UsePNGImageDecoder()  
  
  ;Chargement d'une image et affichage de celle çi dans un GadgetImage
  Image = LoadImage(#PB_Any, #PB_Compiler_Home + "Examples\3D\Data\purebasic3dlogo.png")
  ImageGadget(#MyImage, 10, 10, 381, 68, ImageID(Image))
  
  ;Ajout d'un timer de 10 ms 
  AddWindowTimer(#MainForm, #MyTimer, 10)
  
  ;Déclencheur
  BindEvent(#PB_Event_Timer, @Effet(), #MyTimer)
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Procedure Effet()
  Protected Color.i
  
  If Intensite = 0 Or Intensite = 255 
    Increment * -1
  EndIf
  
  Intensite + Increment
  
  ;Modification de la transparence d'une image
  StartDrawing(ImageOutput(Image))
  DrawingMode(#PB_2DDrawing_AlphaChannel)
  For x = 0 To ImageWidth(Image) - 1
    For y = 0 To ImageHeight(Image) - 1
      
      ;Lecture de la couleur d'une image 
      Color = Point(x, y) 
      
      ;Modification de la transparence
      Plot(x, y, RGBA(Red(Color), Green(Color), Blue(Color), Intensite))
    Next
  Next
  StopDrawing()
  
  ;Raffraichissement de l'imagegadsget
  SetGadgetState(#MyImage, ImageID(Image))
EndProcedure
Je pense que tu vas le constater : De temps en temps le GadgetImage() à la tremblotte.

Autre solution passer par un CanvasGadget() de cette manière.

Code : Tout sélectionner

Enumeration Window
  #MainForm
EndEnumeration

Enumeration Gadget
  #MyCanvas 
EndEnumeration

Enumeration Timer 
  #MyTimer
EndEnumeration

Global Image, Intensite = 255, Increment = 1 

Declare Effet()

If OpenWindow(#MainForm, 0, 0, 400, 90, "Afficher une image", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)      
  UsePNGImageDecoder()  
  
  ;Chargement d'une image et affichage de celle çi dans un GadgetImage
  Image = LoadImage(#PB_Any, #PB_Compiler_Home + "Examples\3D\Data\purebasic3dlogo.png")
  CanvasGadget(#MyCanvas, 10, 10, 381, 68)
  
  ;Ajout d'un timer de 10 ms 
  AddWindowTimer(#MainForm, #MyTimer, 10)
  
  ;Déclencheur
  BindEvent(#PB_Event_Timer, @Effet(), #MyTimer)
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Procedure Effet()
  Protected Color.i
  
  If Intensite = 0 Or Intensite = 255 
    Increment * -1
  EndIf
  
  Intensite + Increment
  
  ;Modification de la transparence d'une image
  StartDrawing(ImageOutput(Image))
  DrawingMode(#PB_2DDrawing_AlphaChannel)
  For x = 0 To ImageWidth(Image) - 1
    For y = 0 To ImageHeight(Image) - 1
      
      ;Lecture de la couleur d'une image 
      Color = Point(x, y) 
      
      ;Modification de la transparence
      Plot(x, y, RGBA(Red(Color), Green(Color), Blue(Color), Intensite))
    Next
  Next
  StopDrawing()
  
  StartDrawing(CanvasOutput(#MyCanvas))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  Box(0, 0, 381, 68, RGBA(255, 255, 255, 255))
  DrawImage(ImageID(Image), 0, 0)
  StopDrawing()
EndProcedure

Re: Aide pour débutants, et question débiles ;)

Publié : ven. 08/avr./2016 21:14
par Uhuru
Merci à vous tous.

J'ai beau essayer et tester beaucoup de chose je crois qu'il y a LE TRUC qui m'échappe. Je ne comprends pas (en tout cas pas totalement)

Imaginons un cas assez simple (pour vous en tout cas ;))

un ecran en full screen, résolution 800 par 600 (pas un mode fenetré MsWindows)
un png de fond qui fait la taille de l'écran
un png => sprite de taille plus réduite genre 400 par 100 que je dois poser par dessus (comme un layer)
et ensuite un cercle que je dois bouger (sur x et y) par dessus le tout, le cercle doit laisser apparaitre le logo mais pas le fond

pour l'écran c'est bien un openSCREEN ?

Code : Tout sélectionner

OpenScreen(800,600,32,"test pb",#PB_Screen_SmartSynchronization,60)
pour le fond, j'ai fait ça (avant la BOUCLE)

Code : Tout sélectionner

fond1 = CatchImage(#PB_Any, ?fond1) <= pour générer
ImageGadget(0, 0, 0, 0, 0, ImageID(fond1)) <= pour afficher
puis pour le logo j'ai fait ca (avant la BOUCLE)

Code : Tout sélectionner

logo = CatchImage(#PB_Any, ?datalogo)
CreateSprite(#MyImg, ImageWidth(logo), ImageHeight(logo), #PB_Sprite_AlphaBlending )
StartDrawing(SpriteOutput(#MyImg))
DrawImage(ImageID(Logo), 0, 0)
StopDrawing()
bon maintenant le truc qui me bloque (sauf si c'est déjà faux au dessus)
pour faire le cercle qui bouge on est d'accord que je dois le faire dans le repeat ?

je le dessine dans une autre image ?

Code : Tout sélectionner

angle.f = 5.0
D       = 0
PPD     = 300
X       = 400+(X*D)
Y       = 300+(Y*D)
Z       = (Cos(Sqr(((X * X) + (Y * Y)) / 2 )))
Rayon   = 45

repeat
If CreateImage(1, 800, 600, 32) And StartDrawing(ImageOutput(1))
  DrawingMode(#PB_2DDrawing_AlphaBlend)  
  Circle(X+64*Cos(angle+Sin(Sqr(64*16))),Y+64*Sin(angle+Cos(Sqr(64*16))),Rayon+64,RGBA(255,255,255,128))
  DrawAlphaImage(ImageID(1), 0, 0)
  StopDrawing()
  
EndIf
ExamineKeyboard()
  Until KeyboardPushed(#PB_Key_Escape)

Re: Aide pour débutants, et question débiles ;)

Publié : ven. 08/avr./2016 23:50
par falsam
Uhuru tu n'as pas lu ce que j'ai posté ou alors je me suis mal exprimé. :wink:
■ Screen et Sprite sont indissociables et sont utilisés pour une application 2D (Jeu ou animation 2D). Un sprite peut aussi intervenir dans une application 3D pour afficher un score par exemple.

Code:
Hors dans ton code tu utilises un ImageGadget() pour afficher un fond.

On va commencer par afficher simple :
- un sprite affichant un fond
- un sprite affichant un logo par dessus le fond

Code : Tout sélectionner

InitSprite() 
InitKeyboard()
InitMouse()

UseJPEGImageDecoder()
UsePNGImageDecoder()

Enumeration
  #Win
  #Spritebackground
  #SpriteLogo
EndEnumeration

OpenScreen(1024, 768, 32, "", #PB_Screen_SmartSynchronization,60)

;Création d'un sprite pour afficher le fond
fond1 = CatchImage(#PB_Any, ?fond1) 
CreateSprite(#Spritebackground, 1024, 768, #PB_Sprite_AlphaBlending )
StartDrawing(SpriteOutput(#Spritebackground))
DrawImage(ImageID(fond1), 0, 0)
StopDrawing()

;Creation d'un sprite affiché sur le fond
logo = CatchImage(#PB_Any, ?datalogo)
CreateSprite(#SpriteLogo, ImageWidth(logo), ImageHeight(logo), #PB_Sprite_AlphaBlending )
StartDrawing(SpriteOutput(#SpriteLogo))
DrawImage(ImageID(Logo), 0, 0)
StopDrawing()

Repeat  
  ClearScreen(RGB(0, 0, 0))
  
  ;Affichage du fond
  DisplayTransparentSprite(#Spritebackground, 0, 0)
  
  ;Affichage du logo
  DisplayTransparentSprite(#SpriteLogo, 350, 350)
  
  ExamineKeyboard()
  FlipBuffers()
  
Until KeyboardReleased(#PB_Key_Escape)

DataSection
  fond1:
  IncludeBinary #PB_Compiler_Home + "Examples\3D\Data\Textures\nvidia\dirt_grayrocky_diffusespecular.jpg"
  
  
  datalogo:
  IncludeBinary #PB_Compiler_Home + "Examples\3D\Data\purebasic3dlogo.png"
EndDataSection


■ Maintenant ce deuxième code simple pour montrer que toutes manipulation de sprite se fait dans la boucle Repeat ... Until KeyboardReleased(#PB_Key_Escape)

Code : Tout sélectionner

InitSprite() 
InitKeyboard()
InitMouse()

UseJPEGImageDecoder()
UsePNGImageDecoder()

Enumeration
  #Win
  #Spritebackground
  #Spritelogo
EndEnumeration

OpenScreen(1024, 768, 32, "", #PB_Screen_SmartSynchronization,60)

;Création d'un sprite pour afficher le fond
fond1 = CatchImage(#PB_Any, ?fond1) 
CreateSprite(#Spritebackground, 1024, 768, #PB_Sprite_AlphaBlending )
StartDrawing(SpriteOutput(#Spritebackground))
DrawImage(ImageID(fond1), 0, 0)
StopDrawing()

;Creation d'un sprite affiché sur le fond
logo = CatchImage(#PB_Any, ?datalogo)
CreateSprite(#Spritelogo, ImageWidth(logo), ImageHeight(logo), #PB_Sprite_AlphaBlending )
StartDrawing(SpriteOutput(#Spritelogo))
DrawImage(ImageID(Logo), 0, 0)
StopDrawing()

Repeat  
  ClearScreen(RGB(0, 0, 0))
  
  ;Affichage du fond
  If StartDrawing(SpriteOutput(#Spritebackground))
    DrawingMode(#PB_2DDrawing_AlphaBlend)  
    Circle(Random(1024), Random(768), Random(64), RGBA(255,255,255,10))
    StopDrawing()
  EndIf
    
  DisplayTransparentSprite(#Spritebackground, 0, 0)
  
  ;Affichage du logo
  DisplayTransparentSprite(#SpriteLogo, 350, 350)
  
  ExamineKeyboard()
  FlipBuffers()
  
Until KeyboardReleased(#PB_Key_Escape)

DataSection
  fond1:
  IncludeBinary #PB_Compiler_Home + "Examples\3D\Data\Textures\nvidia\dirt_grayrocky_diffusespecular.jpg"
  
  
  datalogo:
  IncludeBinary #PB_Compiler_Home + "Examples\3D\Data\purebasic3dlogo.png"
EndDataSection

Re: Aide pour débutants, et question débiles ;)

Publié : sam. 09/avr./2016 8:39
par Uhuru
Merci pour ton temps Falsam

En fait j'avais lu mais pas compris, maintenant je vais passer un peu de temps dessus pour faire du multiples layers et vérifier que j'ai bien vraiment compris :)

Je veux avancer (j'ai acheté la licence hier) mais je veux être sur d'avoir les bonnes bases dans l'utilisation

Merci donc à toi et à blendman pour votre aide :)

Marc

Re: Aide pour débutants, et question débiles ;)

Publié : sam. 09/avr./2016 10:17
par blendman
Uhuru : Je crois que je n'ai pas été assez clair ;)

En fait, j'avais écrit ceci :
On ne peut pas afficher un gadget sur le screen, mais à côté oui (si le screen est plus petit que la fenêtre par exemple).
Or, dans ton précédent code tu essayes d'afficher un imageGadget() dans un screen, ce n'est pas possible ou en tout cas, ça ne va pas bien fonctionner ^^.
Sur un screen, il faut afficher des sprites ou éventuellement DESSINER des images (ou d'autres formes comme les box(), circle(), etc (voir la lib 2D drawing)) avec :

Pour dessiner des sprites sur le screen :

Code : Tout sélectionner

ClearScreen(0)
DisplayTransparentSprite(sprite,x,y)
FlipBuffers()
Pour dessiner des images directement sur le screen :

Code : Tout sélectionner

if Startdrawing(Screenoutput())
Drawimage(image,x,y)
DrawalphaImage(image,x,y)
Stopdrawing()
endif
On peut cumuler dessins (images et autre formes (voir lib 2Ddrawing) sur le screen et affichage de sprites sur ce même screen :

Code : Tout sélectionner


screenwidth = 1024
screenheight = 768

If InitSprite() =0
    MessageRequester("erreur","impossible d'initialiser directx")
    End
EndIf

If OpenWindow(0, 0, 0, screenwidth, screenheight, "Affichage screen", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If UsePNGImageDecoder() : EndIf
    
    If OpenWindowedScreen(WindowID(0),0,0,screenwidth, screenheight)=0
        MessageRequester("Error", "Can't Open Screen!", 0)
        End
    EndIf
        
    Image = LoadImage(#PB_Any, #PB_Compiler_Home + "Examples\3D\Data\purebasic3dlogo.png")
    Sprite = LoadSprite(#PB_Any, #PB_Compiler_Home + "Examples\3D\Data\purebasic3dlogo.png",#PB_Sprite_AlphaBlending)
        
    ; je définis les deux vitesses pour bouger le sprite et le carré
    dir = 2
    dirY = 4
    
    Repeat
        
        ; très important : d'abord, on vérifie les evènements
        Repeat
            
            EventID     = WindowEvent()
            
            Select EventID                   
                    
                Case #PB_Event_CloseWindow 
                    End                    
            EndSelect
            
        Until event = 0
        
        ; si aucun évènement, on va afficher ce qu'il y a sur le screen                
       
       ; on d'abord efface le screen
        ClearScreen(RGB(120,120,120))
        
        ; on peut dessine des formes dessins si besoin : image, box(), circle...,
        ; mais je déconseille personnellement cette technique, 
        ; il faut mieux dessiner la forme sur un sprite et afficher le sprite, ça ira plus vite
        
        y +dirY
        If y >= 500
            dirY = -4
        ElseIf y <= 0
            dirY = 4
        EndIf
        
        If StartDrawing(ScreenOutput())
            
            ; on modifie le mode d'affichage ( voir drawingmode()) pour afficher l'image 
            DrawingMode(#PB_2DDrawing_AlphaBlend ) 
            DrawImage(ImageID(image),50,50) ; on dessine l'image sur le screen (ce qui revient à l'afficher, sauf si on efface avant ce même screen avec clearscreen()
            
            DrawingMode(#PB_2DDrawing_AlphaBlend)
            Box(20,y,50,50,RGBA(255,120,120,254)) ; on dessine un carré
            StopDrawing()
        EndIf
        
        ; décommente cette ligne pour ne plus voir les formes (on les efface avant de les afficher ^^
        ; ClearScreen(RGB(120,120,120))
        
        ; on peut aussi dessiner des sprites si besoin (c'est d'ailleurs préférable, ça va beaucoup plus vite ;)
        x +dir
        If x > 300
            dir = -2
        ElseIf x < 0
            dir = 2
        EndIf
        
        DisplayTransparentSprite(sprite,x,200)
        
        ; et on affiche tout :)
        FlipBuffers()
        
    ForEver
        
EndIf
En fait, une chose importante à retenir c'est ceci :
- si tu utilises OpenScreen(), tu n'as pas réellement de fenêtre, donc tu ne peux afficher aucun gadget, à l'extérieur de ce screen.
- si tu utilises OpenWindowedScreen(), tu ne peux afficher tes gadgets qu'à l'EXTERIEUR de ton screen ;)

Dans ton cas, il est peut-être préférable d'utiliser des sprites, mais si tu veux qu'un layer cache un autre layer, il faudra soit utiliser un cache (voir spriteblendingmode()), soit utiliser des images que tu dessineras sur un sprite, que tu afficheras ensuite sur le screen :)

- dessiner sur un sprite avec Startdrawing(Spriteoutput(Sprite)) en jouant sur le drawingmode(#PB_2DDrawing_AlphaClip)pour n'afficher qu'une partie de l'image :

Code : Tout sélectionner

screenwidth = 1024
screenheight = 768

If InitSprite() =0
    MessageRequester("erreur","impossible d'initialiser directx")
    End
EndIf

If OpenWindow(0, 0, 0, screenwidth, screenheight, "Affichage screen", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If UsePNGImageDecoder() : EndIf
    
    If OpenWindowedScreen(WindowID(0),0,0,screenwidth, screenheight)=0
        MessageRequester("Error", "Can't Open Screen!", 0)
        End
    EndIf
        
    Image = LoadImage(#PB_Any, #PB_Compiler_Home + "Examples\3D\Data\purebasic3dlogo.png")
    Sprite = LoadSprite(#PB_Any, #PB_Compiler_Home + "Examples\3D\Data\purebasic3dlogo.png",#PB_Sprite_AlphaBlending)
        
    ; je définis les deux vitesses pour bouger le sprite et le carré
    dir = 2
    dirY = 4
    
    Repeat
        
        ; très important : d'abord, on vérifie les evènements
        Repeat
            
            EventID     = WindowEvent()
            
            Select EventID                   
                    
                Case #PB_Event_CloseWindow 
                    End                    
            EndSelect
            
        Until event = 0
        
        ; si aucun évènement, on va tout afficher 
        ; on efface le screen
        ClearScreen(RGB(120,120,120))
        
        
        x +dir
        If x > 300
            dir = -2
        ElseIf x < 0
            dir = 2
        EndIf
        
        If StartDrawing(SpriteOutput(sprite))
            
            ; on efface le sprite
             DrawingMode(#PB_2DDrawing_AllChannels)
             Box(0,0,OutputWidth(),OutputWidth(),RGBA(0,0,0,0))
                          
            ; on affiche le cercle           
             Circle(x,25,50,RGBA(254,254,254,254))
                    
            DrawingMode(#PB_2DDrawing_AlphaClip )
            
            DrawImage(ImageID(image),0,0) ; on dessine l'image sur le screen (ce qui revient à l'afficher, sauf si on efface avant ce même screen avec clearscreen()
           
            StopDrawing()
        EndIf
        
        ; on affiche le sprite
        DisplayTransparentSprite(sprite,200,200)
        
        ; et on affiche tout :)
        FlipBuffers()
        
    ForEver
        
EndIf
Voilà, j'espère que ça pourra t'aider, mais surtout n'hésite pas à bien relire nos explications ;)
Elles sont simples, mais c'est fondamental pour comprendre comment tout ça fonctionne.

EDIT : d'ailleurs, grâce à toi, j'ai trouvé un bug que je vais poster sur le forum, si on utilise RGBA(255,255,255,255), ça affiche du noir, alors que (254,254,254,254), ça affiche bien du blanc ^^.

Edit 2 : @falsam : pourquoi tu utilises plot() ? C'est assez gourmand, pour gérer la transparence d'une image, je pense qu'il est préférable d'utiliser :

Code : Tout sélectionner

DrawAlphaImage(ImageID(Image), 0, 0,Intensite)
Après, pour changer les couleurs par exemple, ça peut être intéressant.