Linie zeichnen/berechnen zwischen zwei punkten

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Drago
Beiträge: 148
Registriert: 02.02.2010 18:22
Computerausstattung: Win XP SP3, AMD Sempron (MMX) 1.2 GHz, 512 MB, Nvidia GeForce FX 5200, 128 MB, DirectX 9.0c
Wohnort: Westerwald

Re: Linie zeichnen/berechnen zwischen zwei punkten

Beitrag von Drago »

Deshalb unter anderem auch der Hinweis von Stargate auf das Sprite3D gedingense :-)
Ist in der Darstellung viel schneller als die 2D Drawingsachen...
Guckst du:

Code: Alles auswählen

Dim Sprite2D.i ( 49 ); 2D Sprites als Array ( wird benötigt, um daraus ein 3D Sprite erstellen zu können )
Global Dim Sprite3D.i ( 49 ); selbiges als 3D

; Gibt eine zufällige Fließkommazahl im Intervall [0.0, Maximum] zurück.
Procedure.f RandomFloat(Maximum.f=1.0)
     ProcedureReturn Maximum * 4.6566128752457969241e-10 * Random(2147483647)
EndProcedure

; Gibt einen zufälligen Winkel im Bogenmaß im Intervall [0, 2*Pi[ zurück.
Procedure.f RandomAngle()
     ProcedureReturn 2.9258361585343193621e-9 * Random(2147483647)
EndProcedure

; Partikelstruktur
Structure Particle
     Sprite.i
     X.f
     Y.f    
     Zoom.f
     DirectionX.f
     DirectionY.f
EndStructure

Global NewList Particle.Particle()

; Erzeugt eine Explosion
Procedure CreateExplosion(X.f, Y.f, Particles.i=1000)
     Protected Index.i, Speed.f, Angle.f
     For Index = 1 To Particles
          AddElement(Particle())
          Particle()\Sprite = Sprite3D( Random( 49 ) )
          Particle()\X = X
          Particle()\Y = Y
          Angle = RandomAngle()
          Speed = RandomFloat(6)
          Particle()\DirectionX = Cos(Angle)*Speed ; Hier speicher ich die Veränderung für X und Y direkt im Element,
          Particle()\DirectionY = Sin(Angle)*Speed ;  um nicht jedes mal später Cos() und Sin() (langsammer) aufzurufen.          
          Particle()\Zoom = RandomFloat(3)+2
     Next
EndProcedure



Enumeration
     #Window
EndEnumeration

InitSprite()
InitSprite3D()
InitMouse()
InitKeyboard()

OpenWindow(#Window, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)

; 50 Particle als Sprite3D in verschiedenen Farben erstellen

For i = 0 To 49 
     
     ClearScreen( 0 )
     
     If StartDrawing( ScreenOutput() )
          Circle( 16, 16, 16, RGB(30+Random(255), 30+Random(255), 30+Random(255)))
          StopDrawing()
          
     EndIf  
     
     Sprite2D( i ) = GrabSprite( #PB_Any, 0, 0, 32, 32, #PB_Sprite_Texture )
     Sprite3D( i ) = CreateSprite3D( #PB_Any, Sprite2D( i ) )
     
Next

Define MousePushed.i, MouseX.i, MouseY.i

Repeat
     
     Repeat
          
          Select WindowEvent()
               Case #PB_Event_CloseWindow
                    End
               Case #Null
                    Break
          EndSelect
          
     ForEver
     
     If ExamineKeyboard()
          If KeyboardPushed(#PB_Key_Escape)
               End
          EndIf
     EndIf
     
     If ExamineMouse()
          MouseX = MouseX()
          MouseY = MouseY()
          If MouseButton(#PB_MouseButton_Left)
               MousePushed = #True
          ElseIf MousePushed
               CreateExplosion(MouseX, MouseY)
               MousePushed = #False
          EndIf
     EndIf
     
     ; Partikelberechungen
     ForEach Particle()
          Particle()\X + Particle()\DirectionX
          Particle()\Y + Particle()\DirectionY
          Particle()\Zoom - 0.05      ; Macht das Partikel kleiner und
          If Particle()\Zoom <= 0.0  ;  löscht es dann wenn es zu klein wird
               DeleteElement(Particle())
          EndIf
     Next
     
     ClearScreen(0)
     
     If Start3D()
          ; Partikelanzeige
          ForEach Particle()
               ZoomSprite3D( Particle()\Sprite, Particle()\Zoom, Particle()\Zoom )
               DisplaySprite3D( Particle()\Sprite, Particle()\X, Particle()\Y, 255 )
          Next
          
          Stop3D()
          
     EndIf
     
     If  StartDrawing( ScreenOutput() )
          
          DrawText( 0, 0, "Anzahl Particle : " + Str( ListSize( Particle() )), $FFFFFF )
          Circle( MouseX, MouseY, 5, $FFFFFF )
          
          StopDrawing()
          
     EndIf
     
     FlipBuffers()
     
ForEver
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Linie zeichnen/berechnen zwischen zwei punkten

Beitrag von STARGÅTE »

Agent hat geschrieben:Warum sind die nötig? Erzeugt nicht ein einfaches Random() eine "brauchbare" Zufallszahl? Ok, Du willst eine Fließkomma haben, könnte man die nicht einfach teilen?
Jo klar, aber wenn ich zB Random(40)/10 mache, habe ich auch nur 0.0, 0.1, 0.2 usw.
man würde deutlich diese "11 Ringe" sehen, da es 11 verschiedene Geschwindigkeiten gibt.
Gut du kannst dann Random(4000)/1000 machen, aber ich hab halt diese beiden Prozeduren geschirben, damit ich mir eben sowas erleichtern kann. Die beiden "wirren" Zahlen dienen der Normierung der Zufallszahl, damit aus Random(2147483647) wieder eine Zufallszahl zwischen 0.0 und 1.0 entsteht.
Stell Dir in meinem Beispiel mal vor da sind ein paar duzend Schüsse, Einheiten und animationen und dann noch die ein oder andere Explosion. Dann steht das ganze. Und ich habe aktuelle Hardware
Eine Explosion mit 1000 Partikel ist quatsch. 100 oder noch weniger reichen aus, denn es kommt ja auf das Partikel selbst an und nicht auf die 1000 ...
Desweiteren, explodiert ja nicht alles auf der selben Stelle, sodass du explosionen die außerhab des Sichtbereichs sind, garnicht erst berechnen musst/anzeigen musst. Das sind die stellen an denen du optimieren musst.
Wie oben schon gesagt, bringen Thread für sowas rein garnix, weil die eh immer wieder warten müssen.

@Drago: danke für das Beispiel.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Agent
Beiträge: 296
Registriert: 13.09.2004 11:28
Kontaktdaten:

Re: Linie zeichnen/berechnen zwischen zwei punkten

Beitrag von Agent »

Habs umgesetzt. Prima!
Ich hätte es so oder so auf sprites umgeschrieben, danke!
Agent_Sasori
It's not a bug - it's a feature!
http://www.StephenKalisch.de | http://www.ria-tec.com | http://www.dirsync.de
Antworten