Performance bei DrawImage
Übersicht

![]() |
TravisBetreff: Performance bei DrawImage |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich bin dabei eine kleine Mautstation-Simulation zu machen. Die Straße ist schon fertig und es fließt auch schon Verkehr auf meiner Autobahn, nun habe ich aber das Problem, das die Autos anfangen zu flimmern, sobald es mehr als 12-15 Stück werden.
Ich habe das komplette Prog mal hochgeladen, ihr könnt es euch ja mal ansehen. http://home.t-online.de/home/Daniel.Nobis/Maut.rar |
||
www.funforge.org
Ich hasse WASD-Steuerung. Man kann alles sagen, man muss es nur vernünftig begründen können. |
![]() |
Ralf |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
der Fehler liegt an diesen beiden Zeilen: Code: [AUSKLAPPEN] If c\x > 1042 Then Delete c: cars = cars - 1: Exit
If c\x < 0 Then Delete c: cars = cars - 1: Exit Wenn Du laufend einen Type löscht, werden die anderen Typefelder verschoben, dadurch kommt es zu den Aussetzern. Zum Test lösche diese Zeilen mal, dann läuft alles ohne zu ruckeln, was natürlich keine Lösung ist. Definier vorher die Type-Felder und setze einfach die X-Werte neu, anstatt den Type zu löschen, wenn das Auto den Bildschirmrand erreicht. Oder ersetzte die Types durch Dim-Felder. Oder lass Dir eine andere Lösung einfallen. Gruß Ralf |
||
![]() |
Travis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Cool, danke für die Hilfe. Dann werde ich es wohl so einrichten, dass ich immer in 30er Schritten lösche. Ich lasse die Autos einfach unsichtbar über den Bildschirmrand weiterfahren und wenn es dann 30 Stück durch sind, dann lösche ich einfach alle, die nicht mehr angezeigt werden. ![]() Code: [AUSKLAPPEN] ; --- Autos darstellen und bewegen
For c.car = Each car If c\Richtung = 1 Then DrawImage Car1r, c\x, c\y, c\Farbe If c\Richtung = 2 Then DrawImage Car2l, c\x, c\y, c\Farbe If c\Richtung = 1 Then c\x = c\x + c\speed If c\Richtung = 2 Then c\x = c\x - c\speed ;If c\x > 1042 And c\OnRoad = 1 Then c\OnRoad = 0: OffRoads = OffRoads + 1:OnRoads = OnRoads - 1: Exit ;If c\x < 0 And c\OnRoad = 1 Then c\OnRoad = 0: OffRoads = OffRoads + 1: OnRoads = OnRoads - 1: Exit Next ;If OffRoads > 30 Then ;Text 0, 300, "SPEICHERSÄÜBERUNG" ;c.car = First car ;For i = 1 To OffRoads ;Delete c: OffRoads = OffRoads - 1 ;c.car = After c ;Next ;EndIf (Für OffRoads und OnRoads könnte man auch sagen Autos auf dem Bildschirm/Autos außerhalb des Schirms) EDIT: Ich hab's versucht, aber dafür muss ich ja ständig jedes Auto abfragen, ob es noch auf dem Schirm ist und das geht wieder so lahm, das es schon wieder flimmert. Und wenn ich sie nicht lösche werden alle Autos ab dem 350 plötzlich sehr langsam. |
||
www.funforge.org
Ich hasse WASD-Steuerung. Man kann alles sagen, man muss es nur vernünftig begründen können. |
BIG BUG |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hmm, kann mir jetzt eigentlich nicht vorstellen, dass das Typelöschen sooo langsam ist, da ja nur Zeiger verbogen werden...
Und bei 12-15 Stück sollte es wirklich keine Probleme geben. Was haste denn für einen Rechner? |
||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
![]() |
Clonker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich hab hier einen Lösungsvorschlag.
Zum Car-Type noch ein Field mit dem Namen aktiv erstellen. Code: [AUSKLAPPEN] Type Car Field x, y, speed, Richtung, Farbe, aktiv End Type Und hier der Teil zum anzeigen der Autos: Code: [AUSKLAPPEN] ; Autos darstellen und bewegen For c.car = Each car If c\aktiv = 1 then If c\Richtung = 1 Then DrawImage Car1r, c\x, c\y, c\Farbe If c\Richtung = 2 Then DrawImage Car2l, c\x, c\y, c\Farbe If c\Richtung = 1 Then c\x = c\x + c\speed If c\Richtung = 2 Then c\x = c\x - c\speed If c\x > 1024 Then c\aktiv=0 : cars = cars - 1 If c\x < 0 Then c\aktiv=0 : cars = cars - 1 Else Delete c EndIf Next Und hier die CreateCar Funktion: Code: [AUSKLAPPEN] Function CreateCar(Spur) c.car = New car cars = cars + 1 If Spur = 1 Then c\y = 105: c\Richtung = 1 If Spur = 2 Then c\y = 125: c\Richtung = 1 If Spur = 3 Then c\y = 158: c\Richtung = 2 If Spur = 4 Then c\y = 177: c\Richtung = 2 If c\Richtung = 1 Then c\x = 0 ; von links nach rechts If c\Richtung = 2 Then c\x = 1024 ; von rechts nach links If Spur = 1 Or Spur = 4 Then c\speed = Rnd(4,5) ; linke Spuren (schnell) If Spur = 3 Or Spur = 2 Then c\Speed = Rnd(2,3) ; rechte Spuren (langsam) c\Farbe = Rnd(0,4) c\aktiv=1 ;damit das Auto angezeigt wird End Function Bei mir flimmert es so, nicht mehr! |
||
Die exzessive Akkumulation von Fremdwörtern suggeriert pseudointellektuelle Kompetenz.
Athlon XP 2800|Radeon 9600 Pro|512MB DDR RAM|240GB Festplatte |
![]() |
Travis |
![]() Antworten mit Zitat ![]() |
---|---|---|
@ Clonker
Tatsächlich! ![]() Ich schätze mein Fehler lag also darin, daß ich in jeder Schleife immer alle Autos gezeichnet habe, egal ob sie nun auf dem Schirm waren oder nicht. Sonst kann ich mir das nicht vorstellen. Denn hier wird ja auch jedes Auto gelöscht,sobald es nicht mehr auf dem Schirm ist. Jetzt läuft es bis ca. 250 Autos ziemlich flüssig. Es passen aber nur etwa 100 Autos gleichzeitg auf die Straße. ![]() Danke für die Hilfe. |
||
www.funforge.org
Ich hasse WASD-Steuerung. Man kann alles sagen, man muss es nur vernünftig begründen können. |
BIG BUG |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Der Fehler lag im Programm bei den Delete-Befehlen und hängt nicht mit der Performance zusammen, da auch ein zu langsames Spiel nicht flimmern kann, weil ja Doublebuffering verwendet wird.
Das Problem sind die beiden Exits. Ein Exit beendet nämlich die komplette Schleife und nicht den aktuellen Durchlauf. Da du diese Schleife aber zum Darstellen der Autos verwendet hast, wurde die Darstellung der Autos bei den Deletes abgebrochen und nicht alle Autos dargestellt und bewegt. Dadurch kam es zu den benannten Aussetzern(Clonker hat diesen Fehler nicht gemacht, deswegen funktioniert sein Coding und nicht wegen dem "Aktiv"-Kennzeichen). Lösung: Ersetze das: Code: [AUSKLAPPEN] If c\x > 1042 Then Delete c: cars = cars - 1: Exit If c\x < 0 Then Delete c: cars = cars - 1: Exit durch das: Code: [AUSKLAPPEN] If c\x > 1042 Or c\x < 0 Then Delete c cars = cars - 1 EndIf Außerdem solltest du deine Timersteuerung überarbeiten, da momentan die Geschwindigkeit und die Anzahl der erstellten Autos direkt an der Monitorrefreshrate hängt. |
||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
![]() |
Ralf |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
manchmal sieht man den Wald vor lauter Bäumen nicht. ![]() Big Bug hat natürlich Recht, es liegt am Exit. Ich hatte mich auch gewundert, dass ein Delete so viel Zeit in Anspruch nehmen sollte, nur habe ich nicht weiter darüber nachgedacht... Gruß Ralf |
||
![]() |
Travis |
![]() Antworten mit Zitat ![]() |
---|---|---|
@ BIG BUG
Danke für den Tipp. So ist es natürlich viel einfacher. Das kommt davon, wenn man immer alles in eine Schleife quetschen will. Bei meinen anderen Projekten habe ich nur für's Zeichnen auch immer eine eigene Schleife genommen. Was den Timer angeht, solange ich mit "Flip 1" arbeite, hängt die Geschwindigkeit doch sowieso von der Frequenz des Monitors ab. Und die Autos werden ja immer in bestimmten Zeitabständen eingefügt. Zwischenzeitlich habe ich den Teil aber noch mal geändert, damit die Straße ein bisschen Belebter ist. Code: [AUSKLAPPEN] ; Mautsystem mit Verkehrssimulation ; Copyright (C) Jan 2004, Daniel Nobis Graphics 1024, 768, 16, 2 SetBuffer BackBuffer() AppTitle "Travis Collect Mautsystem" Titel = LoadImage("Titel.png") Road = LoadImage("Road.png") Car1r = LoadAnimImage("Cars1r.png", 24, 10, 0, 5) Car2l = LoadAnimImage("Cars2l.png", 24, 10, 0, 5) MidHandle Car1r MidHandle Car2l MaskImage Car1r, 255,0,255 MaskImage Car2l, 255,0,255 Type Car Field x, y, speed, Richtung, Farbe End Type Global Cars ; --- Timer vorbereiten Start# = MilliSecs() SeedRnd MilliSecs() ; ------ Hauptschleife ------ Repeat Cls ; --- Timer aktualisieren Zeit# = MilliSecs() - Start# Zeitabstand# = Rnd(180,3000) ; --- Zufällige Autos erstellen If Zeit# > ZeitAbstand# Then For i = 1 To 4 CreateCar(i) Next Zeit# = 0 Start# = MilliSecs() EndIf ; Titelschrift DrawImage Titel, 100, 10 ; Straße darstellen For x = 0 To 1024 Step 40 DrawImage Road, x, 55 Next ; Autos darstellen, bewegen und löschen For c.car = Each car If c\Richtung = 1 Then DrawImage Car1r, c\x, c\y, c\Farbe If c\Richtung = 2 Then DrawImage Car2l, c\x, c\y, c\Farbe If c\Richtung = 1 Then c\x = c\x + c\speed If c\Richtung = 2 Then c\x = c\x - c\speed If c\x > 1042 Or c\x < 0 Then Delete c cars = cars - 1 EndIf Next ; --- Abstand einhalten For c.car = Each car For c2.car = Each car If Abs(c\x - c2\x) < 30 And c\y = c2\y Then c2\Speed = c\Speed Next Next ; StatistikInfos Text 0,300, MouseX() + "/" + MouseY() Text 0,240, "Autos auf der Strasse: " + cars Flip 1 Until KeyHit(1) End ; ------ Ende der Hauptschleife ------ ; ------ Funktion Neues Auto erstellen ------ Function CreateCar(Spur) c.car = New car Cars = Cars + 1 If Spur = 1 Then c\y = 105: c\Richtung = 1 If Spur = 2 Then c\y = 125: c\Richtung = 1 If Spur = 3 Then c\y = 158: c\Richtung = 2 If Spur = 4 Then c\y = 177: c\Richtung = 2 If c\Richtung = 1 Then c\x = 0 ; von links nach rechts If c\Richtung = 2 Then c\x = 1024 ; von rechts nach links If Spur = 1 Or Spur = 4 Then c\speed = Rnd(3,4) ; linke Spuren (schnell) If Spur = 3 Or Spur = 2 Then c\Speed = Rnd(2,3) ; rechte Spuren (langsam) c\Farbe = Rnd(0,4) End Function |
||
www.funforge.org
Ich hasse WASD-Steuerung. Man kann alles sagen, man muss es nur vernünftig begründen können. |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group