
Super encore un code à étudierFweil a écrit :Voici une proposition de mise à jour pour le code du programme Rosace3D de Cederavic. J'ai un peu commenté en français, mais pfff
Ce prog est déjà un peu relevé. Il contient une procédure assez intéressante pour construire des objets sprites. Il y a une partie qui vole un peu haut pour créer des panneaux de texte texturé avec passage de pointeur de structure en argument.
Sinon, par rapport à la version de Cederavic, c'est moins perfectionné pour le traitement des priorités des sprites par rapport à la coordonnée 3D. J'ai retiré la fonction de tri de la liste indexée, mais le calcul du fading suffit à rendre un très bon effet avant / arrière plan des sprites.
Par le fait, le programme tourne beaucoup mieux, l'affichage reste fluide avec un refresh de 40fps pour 200 balles affichées sur ma machine (1,2GHz).
J'ai également placé la strcture de code permettant de choisir un mode plein écran ou un mode fenêtré, et la version fenêtrée est de très bonne qualité en affichage.

Code : Tout sélectionner
#BubbleMax = 200 ; En adaptant cette valeur on peut diminuer ou augmenter le nombre de balles traitées. Les valeurs au-delà de 200 ralentissent quand même le raffraichissement
#Window_Main = 0 ; Si on choisi de démarrer en mode fenêtré, on utilisera cette constante pour ouvrir la fenêtre principale
#NSprites = 30 ; Ici on défini le nombre de sprites différents qui vont être créés. Une valeur de 10 ou 20 est déjà correcte.
#FullScreen = #FALSE ; Si la constante est vraie on ouvre en mode plein écran, sinon on ouvre en mode fenêtré.
#Pointer1 = #NSprites + 1 ; On donne trois constantes pour gérer le pointeur en mode écran
#Pointer2 = #NSprites + 2 ; Le pointeur 1 est une croix blanche, le pointeur 2, une croix rouge et le pointeur 3 un texte spécial
#Pointer3 = #NSprites + 3 ;
#SplashPanel = #NSprites + 4 ; Mon truc à moi
#BackgroundColor = #Black ; Et une couleur de fond d'écran pour les sprites objets (CreateSpriteObject)
Structure BubbleStruct
x.l
y.l
z.l
ax.l
ay.l
img.l
sx.b
sy.b
EndStructure
NewList Bubble.BubbleStruct()
Structure TEXTPANEL
FontName.s
FontSize.l
Text.s
TextColor.l
EndStructure
SplashPanel.TEXTPANEL
Procedure CreateSpriteObject(SpriteNumber.l, Width.l, Height.l, ObjectName.s, Param1.l, Param2.l)
;
; CreateSpriteObject allows to create parameterized sprites
;
If CreateSprite(SpriteNumber, Width, Height, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(SpriteNumber))
Select ObjectName
Case "Cross" ; Un pointeur en forme de croix utlisant deux LineXY de la couleur Color1 dans une boite de fond Color2. la couleur Color2 doit en principe être transparente.
DrawingMode(0)
Box(0, 0, Width, Height, Param2)
LineXY(0, Height / 2, Width, Height / 2, Param1)
LineXY(Width / 2, 0, Width / 2, Height, Param1)
Case "Arrow" ; Un pointeur en forme de flêche de la couleur Color1 dans une boite de fond Color2. la couleur Color2 doit en principe être transparente.
DrawingMode(0)
Box(0, 0, Width, Height, Param2)
LineXY(0, 0, 4, 13, Param1)
LineXY(4, 13, 5, 8, Param1)
LineXY(5, 8, 29, 32, Param1)
LineXY(29, 32, 32, 29, Param1)
LineXY(32, 29, 9, 6, Param1)
LineXY(9, 6, 13, 5, Param1)
LineXY(13, 5, 0, 0, Param1)
FillArea(2, 2, Param1, Param1)
Case "TextPanel" ; Attention là, je suis en cours de mise au point donc ce n'est pas forcément très exhaustif
*TextPanel.TEXTPANEL = Param1
DrawingFont(LoadFont(0, *TextPanel\FontName, *TextPanel\FontSize, #PB_Font_HighQuality))
DrawingMode(0)
For x = 0 To Width
Fading.f = x / Width - 0.5 : If Fading < 0 : Fading = 0 : EndIf : If Fading > 0.5 : Fading * 2 : EndIf
LineXY(x, 0, 0, x, RGB(Red(Param2) * Fading, Green(Param2) * Fading, Blue(Param2) * Fading))
LineXY(Width - x, Height, Width, Width - x, RGB(Red(Param2) * Fading, Green(Param2) * Fading, Blue(Param2) * Fading))
Next
DrawingMode(1)
If FindString(*TextPanel\Text, " ", 1)
FieldNumber = 1
While StringField(*TextPanel\Text, FieldNumber, " ") <> ""
FieldNumber + 1
Wend
FieldNumber - 1
For h = 1 To FieldNumber
For i = 1 To 4
Locate((Width - TextLength(StringField(*TextPanel\Text, h, " "))) / 2 + i, (Height + 3 * (h - 1) * *TextPanel\FontSize) / 2 - i)
FrontColor(Red(*TextPanel\TextColor) >> (4 - i), Green(*TextPanel\TextColor) >> (4 - i), Blue(*TextPanel\TextColor) >> (4 - i))
; FrontColor(64 * i - 1, 64 * i - 1, 50 * i - 1)
DrawText(StringField(*TextPanel\Text, h, " "))
Next
Next
Else
For i = 1 To 4
Locate((Width - TextLength(*TextPanel\Text)) / 2 + i, Height / 2 - i)
FrontColor(64 * i - 1, 64 * i - 1, 50 * i - 1)
DrawText(*TextPanel\Text)
Next
EndIf
Default ; Par défaut un objet 'non connu' est créé avec un caractère '?'
DrawingMode(0)
Box(0, 0, Width, Height, Param1)
DrawingMode(1)
Box(0, 0, Width, Height, Param2)
DrawingMode(1)
Label.s = "?"
DrawingFont(LoadFont(0, "Verdana", 12, #PB_Font_Bold | #PB_Font_HighQuality))
Locate((Width - TextLength(Label)) / 2, (Height - 3 * FontSize / 2) / 2)
FrontColor(Red(255), Green(0), Blue(0))
DrawText(Label)
EndSelect
StopDrawing()
EndIf
EndProcedure
If InitSprite() And InitSprite3D() And InitKeyboard() And InitMouse()
If #FullScreen ; Initialisation de l'écran en mode plein écran, utilisant les dimensions trouvées dans l'API
WindowXSize = GetSystemMetrics_(#SM_CXSCREEN)
WindowYSize = GetSystemMetrics_(#SM_CYSCREEN)
ScreenXSize = WindowXSize
ScreenYSize = WindowYSize
OpenScreen(WindowXSize, WindowYSize, 32, "Rosace3D")
Initialized = #TRUE
Else ; Initialisation en mode fenêtré avec une zone écran de la même taille que la fenêtre principale
WindowXSize = 480
WindowYSize = 360
ScreenXSize = WindowXSize
ScreenYSize = WindowYSize
If OpenWindow(#Window_Main, 0, 0, WindowXSize, WindowYSize, #PB_Window_Borderless | #PB_Window_ScreenCentered, "Rosace3D")
AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Escape, #PB_Shortcut_Escape)
If OpenWindowedScreen(WindowID(), 0, 0, ScreenXSize, ScreenYSize, #TRUE, 0, 0)
Initialized = #TRUE
EndIf
EndIf
EndIf
If Initialized
Sprite3DQuality(1)
CX = 3 * ScreenXSize / 7 ; Ajustement pour centrer les balles lors de l'affichage
CY = ScreenYSize / 2
CXZ = (1 + #FullScreen ) * ScreenXSize / 3 ; et coefficients zx et zy pour le calcul du rendu 3D
CYZ = (1 + #FullScreen ) * ScreenYSize / 3
s.l = 1 ; Les deux variables s et s2 sont des variables de polarité pour faire varier les variables s et s2 dans la plage définie de 5 à 35
s2.l = 1 ; Lorsque j et j2 atteignent une extrémité de la plage, s et s2 changent de polarité.
sk.l = 1 ; sk est le coefficient de polarité d'enveloppe générale de l'objet.
j.f = 0.0 ; En initialisant ces deux variables avec des valeurs au delà de la plage de variation traitée plus bas, on a un effet de désordre initial
j2.f = 50.0 ; Ces valeurs sont ensuite ressérées dans la plage de 5 à 35
k.l = 0 ; k est le coefficient d'enveloppe générale de l'objet. A 0, l'objet est un point mathématique, plus k est grand plus lo'bjet est 'zoomé'.
AngleX.f
AngleY.f
SpriteLightX.f = 0.5 ; Ces deux coefficients sont créés pour donner un effet de lumière sur les balles qui sont créées ci-dessous. Il est amusant de les faire varier
SpriteLightY.f = 0.5 ; en notant que les valeurs au-delà de -1.0 - +1.0 donnent une déformation des balles.
For t = 1 To #NSprites ; Cette boucle permet de créer les balles utilisées comme sprites
CreateSprite(t, 32, 32, #PB_Sprite_Texture) ; Chaque balle est définie avec une couleur générée aléatoirement (enfin pas tout à fait complètement aléatoire !)
StartDrawing(SpriteOutput(t))
ColorMask.l = Random(7) + 1 ; En fait la couleur, ici est une fonction aléatoire des primitives RGB
Red = 32 * Random(4) * ((ColorMask & 4) >> 2) ; ColorMask correspond à une teinte fondamentale R, G, B, RG, RB, GB, RGB
Green = 32 * Random(4) * ((ColorMask & 2) >> 1)
Blue = 32 * Random(4) * ((ColorMask & 1))
SpriteCX.f = 16.0 ; On dessine une succession de cercles de plus en plus lumineux en décalant éventuellement les cercles en direction de la source lumineuse
SpriteCY.f = 16.0 ; définie par SpriteLghtX et SpriteLightY
SpriteRadius = 10
Circle(SpriteCX, SpriteCY, SpriteRadius, RGB(0, 0, 0))
For SpriteRadius = 9 To 2 Step - 1
Circle(SpriteCX, SpriteCY, SpriteRadius, RGB(Red, Green, Blue)) ; La couleur utilisée est une fonctionn croissante où chaque fondamentale est augmentée vers
SpriteCX + SpriteLightX ; la valeur 255 pour les cercles finaux les plus petits. Cela donne automatiquement une 'bille avec reflet !'
SpriteCY + SpriteLightY
Red + 16 : If Red > 255 : Red = 255 : EndIf
Green + 32 : If Green > 255 : Green = 255 : EndIf
Blue + 32 : If Blue > 255 : Blue = 255 : EndIf
Next
StopDrawing()
CreateSprite3D(t, t) ; Et on créé le sprite3D correspondant
Next
PointerXSize = 8 ; On va créer deux sprites pour l'affichage d'un pointeur en mode écran
PointerYSize = 8
CreateSpriteObject(#Pointer1, PointerXSize, PointerYSize, "Cross", $FFFFFF, #BackgroundColor) ; Un pointeur en forme de croix blanche
CreateSpriteObject(#Pointer2, PointerXSize, PointerYSize, "Cross", $8080FF, #BackgroundColor) ; Un pointeur en forme de croix rouge
SplashPanel\FontName = "Verdana"
SplashPanel\FontSize = 8 * (#FullScreen + 1)
SPlashPanel\Text = "Visit www.francoisweil.com"
SPlashPanel\TextColor = $C0FFFF
CreateSpriteObject(#Pointer3, 256, 256, "TextPanel", @SplashPanel, $FF0000) ; Un pointeur en forme de panneau de texte
SplashPanel\FontName = "Verdana"
SplashPanel\FontSize = 8 * (#FullScreen + 1)
SPlashPanel\Text = "Designed by fweil"
SPlashPanel\TextColor = $C0FFFF
CreateSpriteObject(#SplashPanel, 128 * (#FullScreen + 1), 128 * (#FullScreen + 1), "TextPanel", @SplashPanel, $FFFFFF) ; Un panneau contenant un texte
CreateSprite3D(#SplashPanel, #SplashPanel)
SplashPanelXSize = 0
SplashPanelYSize = Random(256)
sSplashPanelX = 1
sSplashPanelY = 1
For t = 0 To #BubbleMax
AddElement(Bubble())
Bubble()\x = (Sin(t / 20) + Cos(t / 50)) * 100 + ScreenXSize / 10 + Random(ScreenXSize - 16)
Bubble()\y = (Cos(t / 20) + Sin(t / 50)) * 100 + ScreenYSize / 10 + Random(ScreenYSize - 16)
Bubble()\z = Sin(t / 10) * 32
Bubble()\img = Random(#NSprites - 1) + 1
ResetList(Bubble())
Next
Start3D()
Repeat
If #FullScreen = #FALSE
Select WindowEvent()
Case #PB_Event_CloseWindow
Quit = #TRUE
Case #PB_Event_Menu
Select EventMenuID()
Case #PB_Shortcut_Escape
Quit = #TRUE
EndSelect
EndSelect
EndIf
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape) : Quit = #TRUE : EndIf
If KeyboardPushed(#PB_Key_Left) : AngleX - 0.00025 : EndIf
If KeyboardPushed(#PB_Key_Right) : AngleX + 0.00025 : EndIf
If KeyboardPushed(#PB_Key_F1) : Delay(50) : HelpFlag = 1 - HelpFlag : EndIf
FlipBuffers()
ClearScreen(0, 0, 0)
AngleX + 0.01 ; L'effet d'angle s'applique à la rotation virtuelle de l'objet complet
AngleY + 0.01
ResetList(Bubble())
For t = 0 To #BubbleMax
NextElement(Bubble())
*h = Bubble()
j + s * 0.00025
j2 + s2 * 0.00025
If j <= 5 : s = 1 : EndIf
If j => 35 : s = -1 : EndIf
If j2 <= 5 : s2 = 1 : EndIf
If j2 => 35 : s2 = -1 : EndIf
Bubble()\x = (Sin(t / j) + Cos(t / j2 * 2 + (j2 / 2))) * k
Bubble()\y = (Cos(t / j) + Sin(t / j2 * 2 + (j2 / 2))) * k
Alpha = Sin(t / j / 2) * 32
Bubble()\ax = CX + CXZ * Bubble()\x / (ScreenXSize + Alpha)
Bubble()\ay = CY + CYZ * Bubble()\y / (ScreenYSize + Alpha)
If Alpha < 40 : Alpha = 128 - 3 * Alpha : Else : Alpha = 128 - Alpha / 3 : EndIf
If Alpha > 255 : Alpha = 255 : ElseIf Alpha < 0 : Alpha = 0 : EndIf
ZoomSprite3D(Bubble()\img, 32, 32)
DisplaySprite3D(Bubble()\img, Bubble()\ax, Bubble()\ay, Alpha)
Next
Refresh + 1
If HelpFlag
StartDrawing(ScreenOutput())
DrawingMode(1)
For i = 1 To 4
Locate(10 + i, 10 - i)
FrontColor(64 * i - 1, 64 * i - 1, 50 * i - 1)
DrawText("Refresh rate : " + Str(RefreshRate))
Next
StopDrawing()
EndIf
If StartCounter < 1000
StartDrawing(ScreenOutput())
DrawingMode(1)
If StartCounter < 500
ThisColor = 255 * StartCounter / 500
FrontColor(ThisColor, ThisColor, ThisColor)
Text.s = "Use left / right mouse buttons to change parameters - Escape to exit"
Locate((ScreenXSize - TextLength(Text)) / 2, ScreenYSize - 20)
DrawText(Text)
Else
ThisColor = 255 * (1000 - StartCounter) / 500
FrontColor(ThisColor, ThisColor, ThisColor)
Text.s = "Use left / right mouse buttons to change parameters - Escape to exit"
Locate((ScreenXSize - TextLength(Text)) / 2, ScreenYSize - 20)
DrawText(Text)
EndIf
StopDrawing()
EndIf
ExamineMouse()
If MouseButton(1)
j = Random(100) - 50
j2 = Random(100) - 50
EndIf
If MouseButton(2) And k > 0
k = -k
EndIf
If ElapsedMilliseconds() - tz => 1000
tz = ElapsedMilliseconds()
RefreshRate = Refresh
Refresh = 0
EndIf
StartCounter + 1
MouseX = MouseX()
MouseY = MouseY()
If MouseX > ScreenXSize / 4 And MouseX < 3 * ScreenXSize / 4 And MouseY > ScreenYSize / 4 And MouseY < 3 * ScreenYSize / 4
DisplayTransparentSprite(#Pointer2, MouseX() - PointerXSize / 2, MouseY() - PointerYSize / 2)
ElseIf MouseY > ScreenYSize - 120
DisplayTransparentSprite(#Pointer3, MouseX() - 256 / 2, MouseY() - 256 / 2)
Else
DisplayTransparentSprite(#Pointer1, MouseX() - PointerXSize / 2, MouseY() - PointerYSize / 2)
EndIf
k + sk
If k <= 50 : sk = 1 : EndIf
If k => 250 : sk = -1 : EndIf
If StartCounter < 1200
If StartCounter < 950
ThisFading = 255
Else
ThisFading = 1200 - StartCounter
EndIf
SplashPanelXSize + sSplashPanelX
SplashPanelYSize + sSplashPanelY
If SplashPanelXSize <= -128 : sSplashPanelX = 1 : EndIf
If SplashPanelXSize > 128 : sSplashPanelX = -1 : EndIf
If SplashPanelYSize <= -128 : sSplashPanelY = 1 : EndIf
If SplashPanelYSize > 128 : sSplashPanelY = -1 : EndIf
ZoomSprite3D(#SplashPanel, SplashPanelXSize, SplashPanelYSize)
RotateSprite3D(#SplashPanel, SplashPanelAngle, 0)
DisplaySprite3D(#SplashPanel, ScreenXSize - 100, ScreenYSize - 100, ThisFading)
SplashPanelAngle + 1
EndIf
Until Quit
Stop3D()
If #FullScreen
CloseScreen()
Else
CloseWindow(#Window_Main)
EndIf
EndIf
EndIf
TerminateProcess_(GetCurrentProcess_(), 0)
End