Frage zu ->Tribase Engine (Partikel Manager) Portiert zu PB

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
True29
Beiträge: 283
Registriert: 18.08.2012 19:18
Computerausstattung: Windows 8 64bit .Profan x2,Purebasic 5.5
Wohnort: Worms
Kontaktdaten:

Frage zu ->Tribase Engine (Partikel Manager) Portiert zu PB

Beitrag von True29 »

Hallo , Grüßt euch.
ich habe eine teil der Tribase Engine Partikel-Manager welche in einem C++ buch benutzt wird zu PB umgeschrieben.

Nun läuft er so weit und befor ich das dann alles hier bereitstelle wollte ich das da wer nochmal drüber schaut.
Hab so das Gefühl das es noch nich so rund läuft.

so hier mal ein kleines beispiel ;) 64bit und windows client.
https://www.dropbox.com/s/f4xybyev4nlfnrk/test.exe

Hier das Bild zum selbst compilieren.
https://www.dropbox.com/s/1evyulg00mh1v ... e_fire.png

update:
Habe ein Performance problem entdeckt.
DeleteElement(Particle()) verursacht einen Lag wenn es mehrere elemente gleichzeit löscht ab 50 Partikel.
Bin auf der suche nun das Problem zu lösen ;)


Grüße.

Code: Alles auswählen

;/********************************************************************
;	 _________        __    _____
;	/\___  ___\      /\_\  /\  __\
;	\/__/\ \__/ _  __\/_/_ \ \ \_\\   ____    _____      __
;	    \ \ \  /\`´__\ /\ \ \ \  __\ /\ __\_ /\  __\   /´__`\
;	     \ \ \ \ \ \/  \ \ \ \ \ \_\\\ \\_\ \\ \____\ /\  __/
;	      \ \_\ \ \_\   \ \_\ \ \____\\ \___\ \ \____\\ \____\
;	       \/_/ \/_/    \/_/  \/____/ \/__/   \/____/ \/____/
;tbParticleSystem.cpp
;Copyright goes to TriBase-Engine.
;Autor:
;David Scherfgen
;Portiert von Johannes Meyer
;PB 5.20 beta 16

UseJPEGImageDecoder() : UsePNGImageDecoder()

If InitMouse() = 0 Or InitSprite() = 0 Or InitKeyboard() = 0 Or InitSound() = 0 Or InitMovie() = 0
  MessageRequester("test", "Can't open DirectX 11", 0)
  End
EndIf
If OpenWindow(0, 0, 0,1024,900,"test") = 0
  MessageRequester("test", "Can't open Screen", 0) 
  End
EndIf

If OpenWindowedScreen(WindowID(0),0,0,1024,900,0,0,0) = 0
  MessageRequester("test", "Can't open Screen", 0) 
  End
EndIf

Enumeration
  #Textur_Kreis
EndEnumeration


Structure Particle
  fLifeTime.f  
  Particle.f
  fParticle.f
  fDeltaParticle.f
  fStartParticle.f
  fEndParticle.f
  Array Vector3_position.f(1)
  Array Vector3_velocity.f(1)  
  fFriction.f
  fDeltaSize.f
  fSize.f
  fStartsize.f
  fEndsize.f
  Color.f
  DeltaColor.i
  Startcolor.i
  Endcolor.i
  fRotation.f
  fStartRotation.f
  fEndRotation.f
  fDeltaRotation.f
  StartTransparenz.i
  maxparticle.i
EndStructure

Global NewList Particle.Particle() 
Define Explode.Particle ;Explosion
Global  maxparticle.i = 40 ;Maximale Partikel

Explode\fLifetime = 7.0 ;Lebenszeit
Explode\Vector3_velocity.f(0) = 1.0   ;Beschleunigung
Explode\Vector3_velocity.f(1) = 1.0   
Explode\Vector3_position.f(0) = 20  ;pos
Explode\Vector3_position.f(1) = 20 
Explode\fStartsize = 20.0 ;startGröße
Explode\fEndsize = 30.0 ;startGröße
Explode\Startcolor = RGB(0,0,0);startGröße
Explode\Endcolor = RGB(250,0,0);startGröße
Explode\StartTransparenz = 100 ;Trransparenz der Partikel
Explode\fStartParticle = 0
Explode\fFriction = 1.0
Explode\fEndParticle = #Textur_Kreis



;// Lade Textur
If Not CatchSprite(#Textur_Kreis,?Particle,#PB_Sprite_AlphaBlending)
  Debug "error"
  End
EndIf


;// Erstelle Textur
;CreateSprite(#Textur_Kreis,30,30,#PB_Sprite_AlphaBlending )
;StartDrawing(SpriteOutput(#Textur_Kreis))
;  Circle(5,5,6,RGB(250,0,0))
;StopDrawing()


; 
; // int-Zufallswert
Procedure IntRandom(iMin.i,iMax.i)
  ProcedureReturn Random(iMax,iMin)
EndProcedure


Procedure.f FloatRandom(fMin.f, fMax.f)
  ProcedureReturn fMin + (fMax - fMin) * (Random(10001) / 10000.0)
EndProcedure

Procedure.f FPS()
  Static time.i = -1
  Protected currentTime.i = ElapsedMilliseconds()
  Protected timeDiff.i = currentTime - time
  time = currentTime
  If timeDiff > 0    
    ProcedureReturn   1000. / timeDiff   
  EndIf
EndProcedure

;// Bewegt alle Partikel
Procedure MOVE_PARTICLE(fTime.f) 
  
  ;//Alle Partikel druchgehen
  ForEach Particle() 
    With Particle()          
      ;// Lebenszeit verringern
      \fLifeTime - (fTime.f) ;// Lebenszeit verringern  
      
      ;// Ist der Partikel verschwunden?
      If \fLifeTime <= 0.0
        DeleteElement(Particle())        
        ProcedureReturn OK
      EndIf
      ;// Bewegen      
      \Vector3_position(0) + \Vector3_velocity(0) * (fTime.f) ;X                
      \Vector3_position(1) + \Vector3_velocity(1) * (fTime.f ) ;Y
      
      ;// Abbremsen
      If Not \fFriction = 1.0
        \Vector3_velocity(0) * Pow(\fFriction,(fTime.f)) 
        \Vector3_velocity(1) * Pow(\fFriction,(fTime.f))
      EndIf
      
      ;// Partikel animieren
      \fParticle + \fDeltaParticle * fTime.f
      \fSize + \fDeltaSize * fTime.f
      \Color + \DeltaColor * fTime.f
      \fRotation + \fDeltaRotation * fTime.f		  
      
      \Vector3_position(0) + Cos(\fRotation) * \Vector3_velocity(0) ;X
      \Vector3_position(1) + Sin(\fRotation) * \Vector3_velocity(1) ;Y
    EndWith 
  Next
  
  ProcedureReturn OK
EndProcedure



Procedure.f ADD_PARTICLE(fLifeTime.f,fStartParticle.f,fEndParticle.f,fXVector3_position.f,fYVector3_position.f,fXVector3_velocity.f,fYVector3_velocity.f,fFriction.f,fStartsize.f,fEndsize.f,Startcolor.i,Endcolor.i,fStartRotation.f,fEndRotation.f) 
  If(fLifeTime <= 0.0) : ProcedureReturn 0 : EndIf
  Protected.f fInvLifeTime = 1.0 / fLifeTime;
  
  If ListSize(Particle()) < maxparticle 
    AddElement(Particle())    
    With Particle()
      \fLifeTime            = fLifeTime   
      \fParticle            = fStartParticle
      \fDeltaParticle		   = (fEndParticle - fStartParticle) * fInvLifeTime;
      \Vector3_position(0)  = fXVector3_position 
      \Vector3_position(1)  = fYVector3_position
      \Vector3_velocity(0)  = fXVector3_velocity
      \Vector3_velocity(1)  = fYVector3_velocity   
      \fFriction            = fFriction
      \fsize                = fStartsize    
      \fDeltaSize	    	   = (fEndSize - fStartSize) * fInvLifeTime;   
      \color                = Startcolor
      \DeltaColor		       = (EndColor - StartColor) * fInvLifeTime;
      \fRotation		         = fStartRotation;   
      \fDeltaRotation	     = (fEndRotation - fStartRotation) * fInvLifeTime;   
    EndWith
  EndIf
  
  ProcedureReturn OK
EndProcedure


Procedure RENDER_PARTICLE(fTime.f,Transp)
  ForEach Particle ()
    With Particle()    
      Debug \fSize
      ZoomSprite(\Particle,\fSize,\fSize)       
      ;DisplayTransparentSprite(\Particle,\Vector3_position(0),\Vector3_position(1),Transp,\Color)      
      DisplayTransparentSprite(\Particle,\Vector3_position(0),\Vector3_position(1))      
    EndWith
  Next   
  ProcedureReturn OK
EndProcedure

Repeat
  Define dwtime1 = ElapsedMilliseconds()  
  ClearScreen(0)
  
  ADD_PARTICLE(Explode\fLifetime+FloatRandom(-0.25,0.25),Explode\fStartParticle,Explode\fEndParticle,Explode\Vector3_position.f(0)+FloatRandom(0.0,20.0),Explode\Vector3_position.f(1)+FloatRandom(0.0,20.0),Explode\Vector3_velocity.f(0)+FloatRandom(0.0,5.0),Explode\Vector3_velocity.f(1)+FloatRandom(0.0,5.0),Explode\fFriction,Explode\fStartsize+FloatRandom(-5.0,5.0),Explode\fendsize+FloatRandom(-5.0,5.0),Explode\Startcolor+FloatRandom(-1.0,1.0)*FloatRandom(0.0,0.5),Explode\Endcolor+FloatRandom(-1.0,1.0)*FloatRandom(0.0,0.5),FloatRandom(0.0,2.0),FloatRandom(0.0,2.0))
  
  MOVE_PARTICLE(fTime.f)                
  ;SpriteBlendingMode(5,2) ; Schöner "glüh-Effekt"
  ;SpriteQuality(1)
  RENDER_PARTICLE(fTime.f,Transp)
  
  StartDrawing(ScreenOutput())
  DrawText(0,0,"Partikel: "+StrF(ListSize(Particle ())))
  DrawText(0,20,"FPS: " + Str(FPS()))
  StopDrawing()
  
  FlipBuffers ()
  Define dwTime2 = ElapsedMilliseconds() 
  Define.f ftime = (dwtime2 - dwtime1) / 1000.0
  
  Define Event = WindowEvent ()
  Select Event
    Case #PB_Event_CloseWindow
      End
  EndSelect 
ForEver

DataSection
  particle:
  IncludeBinary "particle_fire.png"
EndDataSection
Zuletzt geändert von True29 am 08.09.2013 12:42, insgesamt 4-mal geändert.
i7,12gb ram , Windows 10 ,Purebasic 5.50
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Frage zu ->Tribase Engine (Partikel Manager) Portiert zu

Beitrag von Regenduft »

True29 hat geschrieben:welche in einem C++ buch benutzt wird
Hast Du das Urheberrecht berücksichtigt? Ist zwar unwahrscheinlich, aber nicht dass Du ärger bekommst! (ggf., denn vielleicht ist's ja frei verwendbar)
Glaube kaum, dass hier jemand eine exe zieht und testet... außerdem gibt's noch die Linuxer und die Macianer - wenn auch in der Minderheit. :wink:
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
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: Frage zu ->Tribase Engine (Partikel Manager) Portiert zu

Beitrag von Drago »

Wieso sollte man bei Dropbox keine .exe ziehen ?????
Versteh ich jetzt nicht.....
Benutze es schon seit einem halben Jahr und bin absolut begeistert davon, sowie
viele andere auch hier im Forum....

Aber zum testen wäre ein Beispiel für x86 auch nicht schlecht.....
Benutzeravatar
Chimorin
Beiträge: 451
Registriert: 30.01.2013 16:11
Computerausstattung: MSI GTX 660 OC mit TwinFrozr III
6Gb DDR 3 RAM
AMD Phenom II X4 B55 @ 3,6GHz
Windows 7 Home Premium 64-bit

Re: Frage zu ->Tribase Engine (Partikel Manager) Portiert zu

Beitrag von Chimorin »

Weil man nicht weiß, wer am anderen Ende des Kabels sitzt...
Würdest du einfach eine Exe von mir annehmen? Du weißt nicht, was ich da reinprogrammiert habe...
Bild

- formerly known as Bananenfreak -
True29
Beiträge: 283
Registriert: 18.08.2012 19:18
Computerausstattung: Windows 8 64bit .Profan x2,Purebasic 5.5
Wohnort: Worms
Kontaktdaten:

Re: Frage zu ->Tribase Engine (Partikel Manager) Portiert zu

Beitrag von True29 »

sorry ;) werde dann noch das bild hochladen
i7,12gb ram , Windows 10 ,Purebasic 5.50
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: Frage zu ->Tribase Engine (Partikel Manager) Portiert zu

Beitrag von Drago »

Nun denn, wie auch immer... :mrgreen:

Grundlegend solltest du dir die Beispiele und/oder das PureBasic-Buch durcharbeiten/ansehen.

Das Buch gibt es hier:
http://www.purebasic.com/documentation/PureBasic.pdf

Hier ein paar Tipps und Grundlegendes ( Bitte korrigiert mich, weil ich auch nicht unbedingt ein EXPERTE bin ):

Am Anfang IMMER EnableExplicit gebrauchen, wofür und warum entimm bitte der Hilfe

Variablen NIE in einer Repeat/Until oder sonst wo declarieren, sondern IMMER am Anfang des Programmes

Auch brauchst du eine declarierte Variable nicht immer wieder mit .f oder so bezeichnen. Einmal am Anfang
und gut ist. Ich denke mir, das du es machst, um zu erkennen, um was für eine Variable es sich handelt.
Das kannst du aber auch machen, indem du den Variablennamen dementsprechend wählst, wie bei dir z.B mit fTime.

Wie dem auch sei, hier mal ein Grundgerüst. Wobei ich weniger Wert auf Bezeichnung ala fTime gelegt habe... :-)
In diesem Beispielcode siehst du nur ein schwarzes Fenster, das du dann mit F12/F11 auf Fullscreen oder wieder
auf normal stellen kannst....
Drin rum malen kannste selbst... :D

Code: Alles auswählen

EnableExplicit; IMMER !!!

;====================================================================
; Konstanten declarieren
;====================================================================

#Window             = 0
#Screen_Width    = 1024
#Screen_Heigth    = 768
#FPS                   = 60

;====================================================================
;Enumeration würden dann hier hin kommen
;====================================================================
; Enumeration 
;      #XY
;      #ZZ
; EndEnumeration

;====================================================================
; 
;====================================================================
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitSprite3D() = 0 Or InitSound() = 0 Or InitMouse() = 0 
     MessageRequester( "Error", "Can't open DirectX 7 or later", 0 )
     End
EndIf

ExamineDesktops()

Define Frequenz.i = DesktopFrequency( 0 )
Global  DWidth.i  =  1024
Global  DHeight.i   = 768

OpenWindow( #Window, 0, 0, DWidth,DHeight, "Windowed Screen", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered )
OpenWindowedScreen( WindowID( #Window ), 0, 0, DWidth, DHeight, 1, 0, 0)

;====================================================================
; Hier declariere ich ALLE anderen Variablen
;====================================================================

; Damit auch alles auf jedem Pc schön gleich schnell fliegt u.s.w.
Global  Time.f, OldTime.f, MoveTime.f

;====================================================================

; Variablen für die Größenänderung des Fensters
Global Win_X.i, Win_Y.i, Win_Width.i, Win_Height.i
Global Dim Border.i( 1 )
Global BorderFlag.b
Global Win_X = WindowX( #Window )
Global Win_Y = WindowY( #Window )

Win_Width = WindowWidth( 0 )
Win_Height = WindowHeight( 0 )
Border(0) = #WS_CLIPSIBLINGS | #WS_VISIBLE | #WS_CAPTION | #WS_SYSMENU
Border(1) = #WS_CLIPSIBLINGS | #WS_VISIBLE | #WS_POPUP

;====================================================================

Global Event.i

;====================================================================
; Structuren würden dann hier hin kommen
;====================================================================

; Structure ObjData
;      x.f
;      y.f
;      vx.f
;      vy.f
; EndStructure
; 
; Global NewList Sprite.ObjData()

;====================================================================
; Proceduren
;====================================================================

Procedure ChangeSize( Flag.i )
     
     Select Flag
               
          Case 0
               SetWindowLongPtr_(WindowID( #Window ), #GWL_STYLE, Border( Flag ) )
               SetWindowState( #Window, #PB_Window_Normal )
               ResizeWindow( #Window, Win_X, Win_Y, Win_Width, Win_Height )
               
          Case 1
               
               Win_X = WindowX( #Window )
               Win_Y = WindowY( #Window )
               SetWindowLongPtr_( WindowID( #Window ), #GWL_STYLE, Border( Flag ) )
               SetWindowState( #Window, #PB_Window_Maximize )
               ExamineDesktops()
               DWidth  = DesktopWidth( 0 )
               DHeight = DesktopHeight( 0 )
               
     EndSelect
     
EndProcedure

Procedure UpdateKeyboard()
     
     ExamineKeyboard()
     
     If KeyboardPushed( #PB_Key_Escape )
          
          Event = #PB_Event_CloseWindow
          
     EndIf
     
     If KeyboardPushed(#PB_Key_F11) And BorderFlag <> 0
          
          BorderFlag = 0
          ChangeSize( BorderFlag )
          
     EndIf
     
     If KeyboardPushed(#PB_Key_F12) And BorderFlag <> 1
          
          BorderFlag = 1
          ChangeSize( BorderFlag )
          
     EndIf
     
EndProcedure

Procedure RenderScreen()
     
     StartDrawing( ScreenOutput() )
     DrawText( 450, 320,"F12 = Fullscreen" )
     DrawText( 450, 340, "F11 = Normal" )
     DrawText( 450, 360, "ESC = Ende" )
     StopDrawing()
     
EndProcedure

Procedure RenderSprites()
     ; Sprites eben... :-)
EndProcedure

Procedure MoveSprites()
     
     ; Bewegen der Obekte in Pixel pro Sekunde
     ; wobei Speed die Anzahl der Pixel sind, um welche sich das Objekt in der Sekunde bewegen soll
    
     ; mit Winkel ( ich denke Bewegung mit Winkelangaben braucht man fast IMMER )
     ;x = x + Cos( Radian( Winkel ) ) * Speed * MoveTime
     ;y = y + Sin( Radian( Winkel ) ) * Speed * MoveTime
     
     ; oder als Vektor2D
     ; Bei Vektoren wird das ganze nur zerlegt, das ist alles.
     ; Wobei dann vx und vy sozusagen die Richtung angeben 
     ; Bildlich gesehen geben dann vx und vy Richtung an, in welche der Richtungspfeil im Bild zeigen würde
     ; UND um wieviel Pixel sich das Obekt dann in eben in diese Richtung bewegen soll.
     
     ;vx = Cos( Radian( Winkel ) ) * Speed * MoveTime
     ;vy = Sin( Radian( Winkel ) ) * Speed * MoveTime
     ; x + vx
     ; y + vy
     
EndProcedure

Procedure DrawScreen()
     
     RenderScreen()
     RenderSprites()
     
EndProcedure

Time = ElapsedMilliseconds()
OldTime = Time

;- Main
Repeat
     
     ; Events am Anfang abfragen
     Repeat
          
          Event = WindowEvent()
          
          Select Event
                    
               Case #PB_Event_Gadget
                    
                    If EventGadget() = 0
                         
                         End
                         
                    EndIf
                    
               Case #PB_Event_CloseWindow
                    
                    End
                    
          EndSelect
          
     Until Event = 0
     
     ; und hier gehört alles andere rein
     
     MoveTime = (ElapsedMilliseconds() - OldTime ) * 0.001
     OldTime = ElapsedMilliseconds()
     
     DrawScreen()
     MoveSprites()
     UpdateKeyboard()
     
     FlipBuffers()
     
     Delay( 0 )
     
Until Event = #PB_Event_CloseWindow
CloseScreen()
End
Hoffe es hilft dir weiter...

LG Klaus
True29
Beiträge: 283
Registriert: 18.08.2012 19:18
Computerausstattung: Windows 8 64bit .Profan x2,Purebasic 5.5
Wohnort: Worms
Kontaktdaten:

Re: Frage zu ->Tribase Engine (Partikel Manager) Portiert zu

Beitrag von True29 »

danke Dark für dein Beispiel und deine Mühe ;)
Werde trotzdem bei meiner Version bleiben.
Manche Grundlegende sachen fehlen hier der Grund ist das das ganze als Erweiterung arbeiten soll.
Und mir ging es ja darum das Beispiel aus dem Buch umzusetzen hehe.
Grüße.

vielleicht hat ja noch wer eine Idee wie ich das Problem mit delete element umgehe :(
i7,12gb ram , Windows 10 ,Purebasic 5.50
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: Frage zu ->Tribase Engine (Partikel Manager) Portiert zu

Beitrag von Drago »

Nun, so wie du es gemacht hast ist es einfach kein sauberer Programmcode....
Mann macht einfach kein Define in einer Repeat/Until Routine...
Aber mir soll`s egal sein.... :mrgreen:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Frage zu ->Tribase Engine (Partikel Manager) Portiert zu

Beitrag von ts-soft »

Code: Alles auswählen

ProcedureReturn OK
Häh, nirgends deklariert, wird wohl ewig die Null sein.
Bei dem Stil wird das wohl so schnell nichts, mit was brauchbarem :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
True29
Beiträge: 283
Registriert: 18.08.2012 19:18
Computerausstattung: Windows 8 64bit .Profan x2,Purebasic 5.5
Wohnort: Worms
Kontaktdaten:

Re: Frage zu ->Tribase Engine (Partikel Manager) Portiert zu

Beitrag von True29 »

@Drago
Werde bei der nächsten änderung deine Kritikpunkte miteinfließen lassen ;)

@TS-SOFT
is mir auch klar ;)
das ganze hier is ja noch nich Fertig.
spielt ja auch momentan noch keine Rolle was die prozeduren zurückliefern da das ergebniss nich weiterverarbeitet wird.
i7,12gb ram , Windows 10 ,Purebasic 5.50
Antworten