Fehler im Sourcecode mit Plot()

Für allgemeine Fragen zur Programmierung mit PureBasic.
Kooky
Beiträge: 47
Registriert: 18.09.2004 16:13
Wohnort: München
Kontaktdaten:

Fehler im Sourcecode mit Plot()

Beitrag von Kooky »

Hi,
hab folgende Frage:
wieso stürzt dieser Code ab, wenn ich in Zeile 53 "Plot" anstelle von "Circle" verwende? Ansonsten würde ich vielleicht den Code in den CodeArchiv tun, wegen der Berechnung der Schüsse :wink: .
mfg. Kooky

Code: Alles auswählen

InitSprite()
InitMouse()
InitKeyboard()
OpenScreen(800,600,32,"")

Global speed.f
speed = 5

Structure shoot
  x.f
  y.f
  rx.w
  ry.w
  richtungx.f
  richtungy.f
  multi.f
  farbe.l
EndStructure

NewList shoots.shoot()

Repeat

ExamineKeyboard()
ExamineMouse()

If MouseButton(1)
  AddElement(shoots())
  shoots()\x = 400
  shoots()\y = 300
  shoots()\farbe=Random($FFFFFF)
  shoots()\richtungx = (MouseX()-400)
  shoots()\richtungy = (MouseY()-300)
  shoots()\multi = Sqr(Pow(speed,2)/(Pow(shoots()\richtungx,2)+Pow(shoots()\richtungy,2)))
  shoots()\richtungx = shoots()\richtungx * shoots()\multi
  shoots()\richtungy = shoots()\richtungy * shoots()\multi
EndIf
  
ForEach Shoots()
  Shoots()\x + Shoots()\richtungx
  Shoots()\y + Shoots()\richtungy
  Shoots()\rx = Shoots()\x
  Shoots()\ry = Shoots()\y
  If Shoots()\x < 0 Or Shoots()\x > 800 Or Shoots()\y < 0 Or Shoots()\y > 600
    DeleteElement(Shoots())
    NextElement(Shoots())
  EndIf
Next

StartDrawing(ScreenOutput())
Plot(MouseX(),MouseY(),RGB(255,0,100))
ForEach Shoots()
  Plot(Shoots()\x,Shoots()\y,Shoots()\Farbe) ;Circle(Shoots()\x,Shoots()\y,1,Shoots()\Farbe)
Next
Circle(400,300,10,$FF0010)
StopDrawing()

FlipBuffers()
Delay(10)
ClearScreen(0,0,0)

Until KeyboardPushed(#pb_key_escape)
End
Benutzeravatar
DrShrek
Beiträge: 1970
Registriert: 08.09.2004 00:59

Beitrag von DrShrek »

Nicht ganz sicher, aber soweit ich weiss ist Plot(...) optimiert und kommt mit Werten < 0 (und auch nicht mit Werten > maxScreenSize) nicht klar.

Circle() ist da grosszügiger...
Siehste! Geht doch....?!
PB*, *4PB, PetriDish, Movie2Image, PictureManager, TrainYourBrain, ...
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8820
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Probiers mal so:

Code: Alles auswählen

ForEach shoots() 
  FrontColor(Red(shoots()\farbe), Green(shoots()\farbe), Blue(shoots()\farbe))
  Plot(shoots()\x,shoots()\y) ;Circle(shoots()\x,shoots()\y,1,shoots()\farbe) 
Next 
Bei dieser Methode sollte das ganze über die Windows GDI geregt werden, während es mit der Plot()-Color-Parameter-Version nicht funkioniert, weil Koordinaten außerhalb des Bildschirmbereiches unzulässig sind. Obwohl es bei mir so oder so funktioniert hat. :wink:
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

kann ja nicht ganz sein... die shots werden doch gelöscht, bevor sie den screen verlassen.

äh, würden sie, wenn man 800 durch 799 und 600 durch 599 ersetzen würde.

jetzt noch das frontcolor-setzen vor die for-each-schleife, dann nen performance test für beide varianten, und das ding ist feddich!
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
DrShrek
Beiträge: 1970
Registriert: 08.09.2004 00:59

Beitrag von DrShrek »

Was hat Dein Performance-Test ergeben (bitte mit Code)?
Siehste! Geht doch....?!
PB*, *4PB, PetriDish, Movie2Image, PictureManager, TrainYourBrain, ...
Kooky
Beiträge: 47
Registriert: 18.09.2004 16:13
Wohnort: München
Kontaktdaten:

Beitrag von Kooky »

Kaeru Gaman hat geschrieben:jetzt noch das frontcolor-setzen vor die for-each-schleife
Das würde in diesen Fall leider nicht ganz klappen, weil jeder Schuss ne andere Farbe hat ;) *g*.

Jup also jetzt gehts einwandfrei....

Komisch, dass das an der Farbe liegt....wenn ich das Frontcolor wegmache und bei plot den optionalen parameter mit der farbe weglasse, dann gehts auch...naja.
muss man ja nicht immer verstehen...
ich überarbeite noch einmal den Code und dann gehts gleich zu den Code-Tipps.
mfg. Kooky
PS: THX for HELP! :)
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

@Kooky
sorry, das hatte ich übersehen, dann muss es natürlich mit in die schleife.(s.u.)
however, ich denke, das korrekte setzen der begrenzungen löst das hauptproplem.
ich kanns leider nicht testen, da es auch bei mir so oder so funktioniert, wie bei nic (nvidia?)

btw: da du shoots()\multi nur beim erzeugen des schusses brauchst, kannst du es aus der stuktur herausnehmen.


@IceSoft
der test ergibt, wie erwartet, eine wesentlich höhere geschwindigkeit bei der ersten variante.
(13700 zu 52000 [ms für 20'000'000 shots])
(gibs zu, ice, du wolltest nur wissen, ob ichs kann :wink: - du hast wohl erwartet, dass ich die komplette schleife incl. FlipBuffers und Delay messe, und mich nach 1/2 stunde wundere, warum es keinen unterschied ergibt :twisted: )

Code: Alles auswählen

InitSprite() 
InitMouse() 
InitKeyboard() 
OpenScreen(800,600,32,"") 

Tim1.l
Tim2.l

Structure shoot 
x.f 
y.f 
rx.w 
ry.w 
richtungx.f 
richtungy.f 
multi.f 
farbe.l 
EndStructure 

NewList shoots.shoot() 

For n=0 To 19
    AddElement(shoots()) 
    shoots()\x = 400 
    shoots()\y = 300 
    shoots()\farbe=Random($FFFFFF) 
    shoots()\richtungx = (MX-400) 
    shoots()\richtungy = (MY-300) 
    shoots()\multi = Sqr(Pow(speed,2)/(Pow(shoots()\richtungx,2)+Pow(shoots()\richtungy,2))) 
    shoots()\richtungx = shoots()\richtungx * shoots()\multi 
    shoots()\richtungy = shoots()\richtungy * shoots()\multi 
Next

Tim1 = ElapsedMilliseconds()
For n= 0 To 1000000
    StartDrawing(ScreenOutput()) 
        ForEach Shoots() 
            Plot(Shoots()\x,Shoots()\y,Shoots()\Farbe) 
        Next 
    StopDrawing() 
Next
Tim1 = ElapsedMilliseconds()-Tim1
Debug Tim1

Tim2 = ElapsedMilliseconds()
For n= 0 To 1000000
    StartDrawing(ScreenOutput()) 
        ForEach Shoots() 
            FrontColor(Red(shoots()\farbe), Green(shoots()\farbe), Blue(shoots()\farbe)) 
            Plot(shoots()\x,shoots()\y) ;Circle(shoots()\x,shoots()\y,1,shoots()\farbe) 
        Next 
    StopDrawing() 
Next
Tim2 = ElapsedMilliseconds()-Tim2
Debug Tim2

End
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
DrShrek
Beiträge: 1970
Registriert: 08.09.2004 00:59

Beitrag von DrShrek »

Kaeru Gaman hat geschrieben: @IceSoft
der test ergibt, wie erwartet, eine wesentlich höhere geschwindigkeit bei der ersten variante.
(13700 zu 52000 [ms für 20'000'000 shots])
(gibs zu, ice, du wolltest nur wissen, ob ichs kann :wink: - du hast wohl erwartet, dass ich die komplette schleife incl. FlipBuffers und Delay messe, und mich nach 1/2 stunde wundere, warum es keinen unterschied ergibt :twisted: )
Nein, ehrlich wollte ich eigentlich nicht.
Aber Du hättest natürlich ein delay und Flipbuffers drinnen lassen können. Nur den Messbereich hättest Du entsprechend einschränken müssen.

Übrigends glaube ich das die erste Variante (inklusive eines 'BorderChecks') trotzdem schneller waere als die 2. Variante. Möchtest Du das vieleicht nochmal messen?

Es geht mir darum Euch klar zu machen, das Grafik-Operationen (meistens) mehr CPU Zeit brauchen als irgendwelche Checks die dazu führen eben keine Grafik auszugeben.
Zuletzt geändert von DrShrek am 24.11.2004 11:00, insgesamt 1-mal geändert.
Siehste! Geht doch....?!
PB*, *4PB, PetriDish, Movie2Image, PictureManager, TrainYourBrain, ...
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8820
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

@Kaeru Gaman: Du musstest diese Tests ja sicherlich mit Debugger machen, sonst hättest du die Werte nicht sehen können. Ich habe es mal ein wenig umgeschrieben, dass es auch ohne Debugger läuft.

Code: Alles auswählen

Tim1 = ElapsedMilliseconds() 
For n= 0 To 1000000 
  StartDrawing(ScreenOutput()) 
    ForEach shoots() 
      Plot(shoots()\x,shoots()\y,shoots()\farbe) 
    Next 
  StopDrawing() 
Next 
Tim1 = ElapsedMilliseconds()-Tim1 

Tim2 = ElapsedMilliseconds() 
For n= 0 To 1000000 
  StartDrawing(ScreenOutput()) 
    ForEach shoots() 
      FrontColor(Red(shoots()\farbe), Green(shoots()\farbe), Blue(shoots()\farbe)) 
      Plot(shoots()\x,shoots()\y) ;Circle(shoots()\x,shoots()\y,1,shoots()\farbe) 
    Next 
  StopDrawing() 
Next 
Tim2 = ElapsedMilliseconds()-Tim2 

CloseScreen()
MessageRequester("Zeiten", "tim1 = " + Str(Tim1) + #LFCR$ + "tim2 = " + Str(Tim2))
Was mich allerdings jetzt verblüfft, ist ja, dass mein Rechner da ohne Debugger trotzdem schlechter abgeschnitten hat als deiner mit Debugger. :o

Code: Alles auswählen

Tim1 = 28891
Tim2 = 86685
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

@IceSoft

ist mir klar, deshalb habe ich ja dafür plädiert, die grenzen auf 799 und 599 zu korrigieren...

@nic

naja, der AthXP3000+ rennt zwar nur mit effektiven 2100Mhz, aber vielleicht ist ja doch was dran an den sprüchen von AMD, die wär so fix wie'n 3000er von intel...

ausserdem sind hier ja grafik-operationen das kritische, und so ne GForce FX5700LE mit 256MB reisst da schon was raus...

...und gut aussehen tut das baby auch noch :wink:
Bild
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten