Seite 1 von 2
FPS Einbußen
Verfasst: 23.07.2005 21:05
von Defmaster
Also ich bin gerade dabei mein erstes kleien Jumü'n Run mit PB zu machen.
Geht auch erstmal alles soweit (naja der sprung sieht noch net ganz so gut aus)
Jedenfalls viel mir beim Testen auf, das auf einmal von 60FPS (per setframerate() festgelegt) auf 40 abgesackt sind.
So ich habe nen Screen von 800x600, dann 2 Array's für die Verschiedenen Objekte (1x für Normale,1x für welche wodurch man stirbt)
Nun habe ich auch 2 Proceduren um zu Prüfen ob man da gegen Trifft.
Bei den mit den Sterben habe ich Pixel genau Collision, weil dies Stachel sind
und deshalb auch transparant gezeichnet werden.
Würde dumm aussehen wenn man 10-20 Pixel vorm Stachel stirbt.
Bzw. wenn um stachel schwarzen Kästchen wäre.
Nun ist es so obwohl nicht viele Objekte sind (wie gesagt 800x600 Screen mit 32x32 großen Grafiken) das ich 20fps einbüße.
Ich weiß nicht ob es jetzt daran liegt dass zuviel bzw. die art wie es gezeichnet ist zuviel ist.
Oder ob meine abfragen zuviel sind bei der Bewegung (dürfte aber eigentlich nicht sein).
Ich hoffe ihr könnt mir helfen, denn schon bei einem so kleinem spiel so wenig fps.
(Bin noch Anfänger mit PB deshalb kann/wird es auch sein das ich vieles zu kompliziert gemacht habe)
Verfasst: 23.07.2005 21:33
von Ynnus
Lass das festsetzen der Framerate durch diesen Befehl raus, das ist sowieso keine Übliche Art. Such dir im Forum stattdessen eine bessere Methode zur Framebasierten Bewegung.
Ansonsten kommt es sehr auf den Code an, wie die FPS am Ende ausfallen. Das können auch nur wenige Objekte sein, nur ein paar Sprites, wenn man da was falsch macht beim Anzeigen kann man sich da flott ausbremsen.
Also wenn der Code noch nicht zu lang ist, kannst du ihn hier ja mal posten. Ich hab Erfahrungen damit gemacht, dass man auch gut 1000 Sprite-Objekte im 1024 x 768 Screen anzeigen kann ohne großer Einbüßen unterhalb der 60 FPS, kommt aber eben stark auf den Code an.
Verfasst: 23.07.2005 21:40
von Defmaster
Ok hier der erste Teil des code's (nich lachen bi nnoch anfänger

)
Code: Alles auswählen
;{ Dim Welt_map1.b(25,18)
Dim Welt_map1.b(25,18)
MAP DATEN
;}
;{ Dim Tode_map1.b(25,18)
Dim Tode_map1.b(25,18)
MAP DATEN
;}
startposition_map1_y = 450
Procedure welt_map1_zeichnen()
Shared spieler_x,spieler_y
For x=0 To 25
For y=0 To 18
If Welt_map1(x, y) <> 0
DisplaySprite(Welt_map1(x, y), x*32, y*32)
EndIf
Next y
Next x
EndProcedure
Procedure tode_map1_zeichnen()
Shared spieler_x,spieler_y
For x=0 To 25
For y=0 To 18
If Tode_map1(x, y) <> 0
DisplayTransparentSprite(Tode_map1(x, y), x*32, y*32)
EndIf
Next y
Next x
EndProcedure
Procedure CheckCollision(SpeedX.f, SpeedY.f)
Shared spieler_x,spieler_y
For x=0 To 25-1
For y=0 To 19-1
If Welt_map1(x, y) <> 0
If SpriteCollision(#Spieler, Int(spieler_x + SpeedX), Int(spieler_y + SpeedY), Welt_map1(x, y), x*32, y*32)
ProcedureReturn 1
EndIf
EndIf
Next y
Next x
EndProcedure
Procedure CheckSterben(SpeedX.f, SpeedY.f)
Shared spieler_x,spieler_y
For x=0 To 25-1
For y=0 To 19-1
If Tode_map1(x, y) <> 0
If SpritePixelCollision(#Spieler, Int(spieler_x + SpeedX), Int(spieler_y + SpeedY), Tode_map1(x, y), x*32, y*32)
ProcedureReturn 1
EndIf
EndIf
Next y
Next x
EndProcedure
Procedure bewegen()
Shared spieler_x,spieler_y,speed_bewegung,spieler_aussehen,geschwindigkeit,strafe,maximal_geschwindigkeit
If KeyboardPushed(#PB_Key_Right) And spieler_x < 785
If CheckCollision(speed_bewegung, 0) = 0 And CheckSterben(speed_bewegung, 0) = 0
spieler_x + speed_bewegung ; Spieler bewegen
spieler_aussehen = #Spieler ; Bildwechsel
ElseIf CheckSterben(speed_bewegung, 0) = 1
spieler_x = 0
spieler_y = startposition_map1_y
EndIf
EndIf
If KeyboardPushed(#PB_Key_Left) And spieler_x > 0
If CheckCollision(speed_bewegung-4, 0) = 0 And CheckSterben(speed_bewegung, 0) = 0
spieler_x - speed_bewegung
spieler_aussehen = #Spieler_2 ; Bild wechsel
ElseIf CheckSterben(speed_bewegung-4, 0) = 1
spieler_x = 0
spieler_y = startposition_map1_y
EndIf
EndIf
If KeyboardPushed(#PB_Key_Up) And spieler_y > 0
If CheckCollision(0, speed_bewegung-4) = 0 And CheckSterben(speed_bewegung, 0) = 0 ;And CheckCollision(0, speed_bewegung)
If geschwindigkeit < maximal_geschwindigkeit And strafe = 0
geschwindigkeit = geschwindigkeit + 1
EndIf
If geschwindigkeit = maximal_geschwindigkeit
strafe = 1
EndIf
If strafe = 1 And geschwindigkeit > 0
geschwindigkeit = geschwindigkeit - 1
ElseIf geschwindigkeit = 0 And CheckCollision(0, speed_bewegung)
strafe = 0
EndIf
If CheckCollision(0, speed_bewegung) = 1
geschwindigkeit = 0
strafe = 0
EndIf
If strafe = 0 And CheckCollision(0, speed_bewegung-14) = 0
spieler_y = spieler_y - 7
EndIf
ElseIf CheckSterben(speed_bewegung-4, 0) = 1
spieler_x = 0
spieler_y = startposition_map1_y
EndIf
EndIf
If KeyboardReleased(#PB_Key_Up)
geschwindigkeit = maximal_geschwindigkeit
strafe = 1
EndIf
If spieler_y > 600
spieler_x = 0
spieler_y = startposition_map1_y
EndIf
EndProcedure
Procedure gravitation()
Shared speed_bewegung,spieler_x,spieler_y,startposition_map1_y,geschwindigkeit
If CheckCollision(0, speed_bewegung) = 0
spieler_y = spieler_y + 2
ElseIf CheckCollision(0, 1) = 0
spieler_y = spieler_y + 1
EndIf
If CheckSterben(0, speed_bewegung) = 1
spieler_x = 0
spieler_y = startposition_map1_y
EndIf
EndProcedure
Und hier wo es abgerufen wird:
Code: Alles auswählen
Procedure level1()
Shared spieler_x,spieler_aussehen,spieler_y,level
FlipBuffers()
ClearScreen(255,0,0)
ExamineKeyboard()
DisplayTransparentSprite(spieler_aussehen,spieler_x,spieler_y)
welt_map1_zeichnen() ; In map1.pb
tode_map1_zeichnen() ; In map1.pb
bewegen()
gravitation()
DisplaySprite(#Exit,768,64)
If SpriteCollision(spieler_aussehen,spieler_x,spieler_y,#Exit,768,60)
level = 2
EndIf
EndProcedure
k Das war, ich endschuldige mich schonmal falls da irgendwas nach totalem mist aussieht

Verfasst: 23.07.2005 21:55
von Ynnus
Okay, also erstmal sollte man als Programmierer immer und überall optimieren, wenn es nicht zu Ungunsten der Übersicht geht und in Übersichtlosigkeit endet. Also ich sehe da schonmal 4 For-Schleifen die fast alle das gleiche machen, nämlich von 0 - 25 und von 0 - 18 zählen. Das so verschachtelt, dass letztendlich der Inhalt der Schleifen 494 mal ausgeführt wird. Das bei 4 Schleifen macht: 1976 Schleifendurchgänge pro Frame. Das halte ich schonmal für optimierbar. Zum Beispiel könntest du die ersten beiden Schleifen zusammenfassen zu einer und beide Dinge, die Welt und die Todeszonen in einem Durchgang zeichnen lassen. Dann formst du beide Prozeduren eben zu einer, die die Welt komplett zeichnet.
Auf Kollision und auf den Tot Checken kann man auch in einer Schleife, jeweils die Collision hintereinander prüfen. Da entfallen wieder eine Schleife, das macht insgesammt noch 2 Schleifen, von 4 ursprünglich. Eventuell könnte man diese 2 Schleifen auch noch zusammenlegen, muss man jetzt sehen, wie das mit der Überschaubarkeit des Codes passt.
Ansonsten, Pixelgenaue Spritecollision ist natürlich wesentlich langsamer als normale. Vielleicht solltest du jedem Stachel der zum Tot des Spielers führt einen Bereich auf der Karte zuweisen, in dem der Spieler stirbt. Dann musst du nur noch Variablen (die Koordinaten) vergleichen und keine volle Pixelkollision mehr. Die Box könnte dann auch so eng geschnitten sein, dass kein Teil über die Stacheln hinaus schaut.
Das wären nur so meine Vorschläge, groß angeschaut, ob da vielleicht ein kleiner Fehler irgendwo drinn ist, der das ausbremst, hab ich mir das nicht. Vielleicht hilft die Optimierung soweit auch erstmal aus.
Im übrigen würde ich flipbuffers() hinter die Sprite-Anzeigeroutienen setzen. Sonst zeigst du immer die Sprites des letzten Frame-Durchgangs an.
Verfasst: 23.07.2005 22:06
von Defmaster
k Danke erstmal.
ich hatte am anfang mal versucht die schleifen zu einer zu machen, ging nicht, jetzt habe ich mein Fehle rbemerkt denn ich damals gemacht habe.
Flipbuffers()
Habe ich am anfang weil das in den ganzen Tuts stand die ich mir angesehen, von selber hab ichs immer als letztes gemacht.
Ich werde das jetzt mal optmieren.
(Persönlich bin auch mehr ein optimier fReak, aber bei pb muß man das ja erstmal wissen)
Danke nochmal. Auf die Schleifen hät ich selber kommen können wenn ich vorher nich den fehler reingehauen hät >.<
EDIT:
Habe mal geteset also.
1 Schleife lässt sich zusammen fügen. Die andere geht Codebedingt nicht.
Wenn ich jetzt nicht Transparantzeichne dann läuft es mit 60fps.
Wenn ich transparent zeiche dann geht auf 40 runter.
Verfasst: 25.07.2005 12:28
von Defmaster
So ich bins nochmal.
Ich habe nun 1 Schleife zusammen gefügt (die mit dem zeichnen)
Die andere geht Codebedingt nicht.
Weil ich das auftreffen auf normalen boden und auf Sterbe sachen anders abfrage.
Nun habe ich mal die PixelCollision kommentiert.
Blieb immer noch bei 40fps.
Dann auskommentiert und dann das Zeichnen der Transparenten Sprites kommentiert, dann waren es wieder 60fps.
Code: Alles auswählen
Procedure welt_map1_zeichnen()
Shared spieler_x,spieler_y
For x=0 To 24
For y=0 To 18
If Welt_map1(x, y) <> 0
DisplaySprite(Welt_map1(x, y), x*32, y*32)
EndIf
If Tode_map1(x, y) <> 0
DisplayTransparentSprite(Tode_map1(x, y), x*32, y*32)
EndIf
Next y
Next x
EndProcedure
So sieht die zeichnen Procedure aus.
Wenn ich das mit Tode_map1 weg mache dann gehts schnell.
Dabei zeichne ich nur 10 (11 mit spieler) Transparente Sprites.
Sollte ich nun diese Dinger einzeln setzen und kollision abragen lassen?
Wäre es dann schneller?
btw habe noch immer PB Demo weshalb Debugger an ist daran dürften es aber nicht liegen oder?
Verfasst: 25.07.2005 13:06
von iF
Hallo Defmaster - hab den Thread nur überflogen - habe aber gesehen das Du von schwankenden FPS redest.
Bitte beachte auch das bei heutigen Prozessoren die MHZ nicht immer konstant ist. Besonders Notebooks schalten gerne eine Stufe niedriger wenn's zu warm wird.
Vielleicht erklärt das ja die Differenzen.
Salve, iF.
Verfasst: 25.07.2005 14:29
von Defmaster
Nein das kann nicht sein.
Habe einen Amd 64 3000+ (kein notebook) keine Energiesparmodus und kein Cool' Quiet an.
Es leigt an den Transparenen sprites wie ich schrieb aber das bei 10 stück so doll runtergeht hätte ich nicht gedacht liegt auch an der Programmierweise
Also mit Mhz hat das nich zu tun.
Es ist halt so zeichne ich nicht Transparent -> 60fps
Zeichne ich Transparent -> um die 40fps
Verfasst: 25.07.2005 16:45
von Batze
Bei sehr kleinen Tiles kannst du oft sogar bis auf 4 Kollisionsabfragen begrenzen.
@Admin: Ich hab nach Zaphod gepostet un d trotzdem ist sein Post hinter meinem.

Verfasst: 25.07.2005 16:48
von Zaphod
es macht auch keinen sinn auf kollision mit jedem tile deiner karte zu vergleichen. du kannst über die position deines sprites doch ziemlich genau feststellen bei welchen koordinaten eine kollision möglicherweise auftreten könnte. teste doch nur gegen diese tiles.
wenn zb dein sprite nicht größer ist als ein tile, kann die kollision doch nur gegen die umgebenden tiles passieren:
* sprite
# mögliche kollision
###
#*#
###