Performance bei DrawImage

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

Travis

Betreff: Performance bei DrawImage

BeitragMi, Jan 07, 2004 19:56
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMi, Jan 07, 2004 22:04
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Jan 08, 2004 15:16
Antworten mit Zitat
Benutzer-Profile anzeigen
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. Very Happy

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

BeitragDo, Jan 08, 2004 15:58
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Jan 08, 2004 16:00
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Jan 08, 2004 18:52
Antworten mit Zitat
Benutzer-Profile anzeigen
@ Clonker

Tatsächlich! Smile
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. Very Happy

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

BeitragDo, Jan 08, 2004 23:06
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Jan 08, 2004 23:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

manchmal sieht man den Wald vor lauter Bäumen nicht. Embarassed
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

BeitragFr, Jan 09, 2004 16:25
Antworten mit Zitat
Benutzer-Profile anzeigen
@ 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.

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group