FPS Jump'n Run

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

KddC

Betreff: FPS Jump'n Run

BeitragMo, Jan 28, 2008 17:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi

Ich programmiere grad ein kleines jump'n Runund habe leider jetzt schon probleme mit der fps-rate. Dabeisollte das für meinen pc eig noch recht einfach zu schaffen sein.
Ich habe im moment ein animiertes Bild mit der spielfigur, und je ein animiertes Bild für die zwei Layer der map. Dazu noch ein Hintergrundbild.
Die map ist derzeit 76*24 tiles groß wobei die tiles je 32X32 groß sind. Wie gesagt habe ich zwei layer die unterschiedlich schnell gescrollt werden.
Die maps hab ich vorher mit meinem eigenen leveleditor gemacht...

Doch obwohl das ja gar nicht so viel ist sinkt die fps rate auf 45 wodurch man schon immer mal wider einen ruckler zu sehen bekommt. Vor allem sollen später auch noch gegner, extras etc dazukommen - Wo sollen die fps dann noch hin...Muss ich wohl einfach scheie programmiert haben...

HAbt ihr vllt schon mal generelle tips wie man die auslastung möglichst gering halten kann? Wenn ihr den code mal sehen wollt sagt bescheid
Ach ja ich benutze nur die Blitz2D Befehle...

Danke
Mfg Kddc

Macbook Pro 13" 2,66Ghz

Dottakopf

BeitragMo, Jan 28, 2008 17:54
Antworten mit Zitat
Benutzer-Profile anzeigen
hmm
Also wenn du es noch nicht hast probiere mal flip 0 und natürlich auch nur die tiles zeichnen die gerade auf dem monitor sichbar sind.

Code: [AUSKLAPPEN]


for x = sichtbar_startX  to sichtbar_endeX
 for y = sichtbar_startY to sichtbar_endeY
    drawimage blubber,x*32,y*32.map(x,y,layer)
 next
next



Sonst fällt mir jetzt nix größeres ein. kommt halt drauf an wie du programiert hast und wo da noch was zu optimieren ist.

mfg Dottakopf
Rechtschreibfehler gelten der allgemeinen Belustigung!

KddC

BeitragMo, Jan 28, 2008 18:08
Antworten mit Zitat
Benutzer-Profile anzeigen
hmm...ja...das mit flip 0 hatte ich auch schon....aber mit flip1 gehts am besten....

im mom zeichne ich die tiles so,wobei mapwidth 74 und mapheight 24 sind,also werden ja alle tiles gezeichnet:
Code: [AUSKLAPPEN]
For x = 0 To mapwidth
   For y = 0 To mapheight
      DrawImage Vordergrund,(x*32-(scrollx#*2)),(y*32 scrolly),map(x,y)
   Next
Next


Wie man nur die sichtbaren zeichnet habe ich noch nie probiert....muss ich mal n bisschen rumprobierne....

danke schon mal
Mfg Kddc

Macbook Pro 13" 2,66Ghz

The_Nici

BeitragMo, Jan 28, 2008 18:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Ohne Code geht garnichts.

Lädst du was in der Schleife?
Hast du ql:Line in der Schleife?

D2006

Administrator

BeitragMo, Jan 28, 2008 18:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Du hast irgendeinen massiven Fehler. So ein paar Tiles malen sollte eigentlich kein Problem sein, selbst wenn du alle zeichnest (Es ist ohnehin davon auszugehen, dass DrawImage nichts macht, wenn es angewiesen wird außerhalb des gültigen Bereichs zu malen.)

Deine Hauptschleife wäre durchaus mal interessant. Wenn sie zu groß ist, versuche unwichtige Dinge zu extrahieren. Ich würde fast tippen du machst sowas fatales wie ql:LoadFont in der Hauptschleife oder so.
Intel Core i5 2500 | 16 GB DDR3 RAM dualchannel | ATI Radeon HD6870 (1024 MB RAM) | Windows 7 Home Premium
Intel Core 2 Duo 2.4 GHz | 2 GB DDR3 RAM dualchannel | Nvidia GeForce 9400M (256 MB shared RAM) | Mac OS X Snow Leopard
Intel Pentium Dual-Core 2.4 GHz | 3 GB DDR2 RAM dualchannel | ATI Radeon HD3850 (1024 MB RAM) | Windows 7 Home Premium
Chaos Interactive :: GoBang :: BB-Poker :: ChaosBreaker :: Hexagon :: ChaosRacer 2
 

Dreamora

BeitragMo, Jan 28, 2008 18:52
Antworten mit Zitat
Benutzer-Profile anzeigen
D2006 hat Folgendes geschrieben:
(Es ist ohnehin davon auszugehen, dass DrawImage nichts macht, wenn es angewiesen wird außerhalb des gültigen Bereichs zu malen.)


Die Annahme ist falsch.
DrawImage wird immer zeichnen auch wenns nicht drin ist.
DirectDraw kennt keine Clip Planes / ScissorTests, dass ist ein Direct3D Feature und ohne dieses gibts auch keine "ist draussen" Tests durch die Grafikkarte.

Darum muss man die Loop ändern von minViewX, minViewY to maxViewX, maxViewY
sonst wirds ganz übel den bach runter gehen wenns sehr viel grösser als der screen is.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

D2006

Administrator

BeitragMo, Jan 28, 2008 18:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Kann ich mir nicht vorstellen. Wie sollte DrawImage Pixel außerhalb der Range verändern, ohne dass es zum Absturz kommt? Siehe ql:Writepixelfast mit gelocktem Buffer, wenn man mal eben bei x=-100 Pixel was malt.
Intel Core i5 2500 | 16 GB DDR3 RAM dualchannel | ATI Radeon HD6870 (1024 MB RAM) | Windows 7 Home Premium
Intel Core 2 Duo 2.4 GHz | 2 GB DDR3 RAM dualchannel | Nvidia GeForce 9400M (256 MB shared RAM) | Mac OS X Snow Leopard
Intel Pentium Dual-Core 2.4 GHz | 3 GB DDR2 RAM dualchannel | ATI Radeon HD3850 (1024 MB RAM) | Windows 7 Home Premium
Chaos Interactive :: GoBang :: BB-Poker :: ChaosBreaker :: Hexagon :: ChaosRacer 2

BladeRunner

Moderator

BeitragMo, Jan 28, 2008 19:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Vorberechnung beschleunigt den code schon deshalb weil nicht zig- bis hunderte mal ein Befehl aufgerufen und dann nicht ausgeführt wird. Macht schon einen deutlichen Unterschied das.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Dottakopf

BeitragMo, Jan 28, 2008 19:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Nunja tortzdem spart man sich durch soeine begrenzung n haufen rechen zeit...

bei mode 0 hab ich so 28 fps und bei mode 1 so rund 60

Code: [AUSKLAPPEN]

Graphics 800,600,16,2
SetBuffer BackBuffer()

Global bild = LoadImage("bild.bmp")

Dim map(300,300,5)




Repeat
Cls



   If KeyHit(28) Then mode = 1



   If mode = 0 Then

     
      For x = 0 To 299
        For y = 0 To 299
         DrawImage bild,x*32,y*32
        Next
      Next
    
   

   Else
     ;nur sichbare tiles zeigen

      For x = 0 To 24
        For y = 0 To 17
          DrawImage bild,x*32,y*32
        Next
      Next
   

   End If
   
;fps
FPSZahl=FPSZahl+1
If MilliSecs()-timer >= 1000 Then
  timer = MilliSecs()
  FPS=FPSZahl
  FPSZahl=0
EndIf
Text 200,40,"FPS: "+FPS   

 


Flip 0
Until KeyHit(1)





Sry das ich da drawimage benutze aber rect ist einfach zu langsam ^^

mfg Dottakopf
Rechtschreibfehler gelten der allgemeinen Belustigung!
 

Dreamora

BeitragMo, Jan 28, 2008 21:10
Antworten mit Zitat
Benutzer-Profile anzeigen
D2006 hat Folgendes geschrieben:
Kann ich mir nicht vorstellen. Wie sollte DrawImage Pixel außerhalb der Range verändern, ohne dass es zum Absturz kommt? Siehe <a href="http://www.blitzbase.de/befehle2d/writepixelfast.htm" class="postlink" target="_blank">WritePixelFast<img src="/images/quicklink.gif" width="13" height="11" alt="" title="Begriff nachschlagen" border="0"></a> mit gelocktem Buffer, wenn man mal eben bei x=-100 Pixel was malt.


Das crasht leider je nach Grafikkarte und Treiber genau so wenig ... weswegen einige schon liebe mühe hatten einige recht interessante Fehler zu fixen.

Normalerweise bekommste direkt im Debug Mode nen Fehler ... aber nur normalerweise.

und das problem mit draw image is, das es nicht ganz so arbeitet, sondern es weist DD an es da zu zeichnen, das wird DD auch tun, die grafikkarte probierts auch und wird erst dann feststellen das es draussen ist wenns ausserhalb des backbuffers zeichnet. Bei 3D könnte es schon am anfang der operation abbrechen.
Deswegen ist es relativ wichtig, das man nur den sichtbaren Bereich zeichnet, net eine 100x100 oder noch grösser Tilemap bruteforce like durchwürgt.
Man wird es ja sowieso brauchen, den positions- und animationsupdates sollen ja auch nur im sichtbaren bereich stattfinden.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

KddC

BeitragDi, Jan 29, 2008 12:15
Antworten mit Zitat
Benutzer-Profile anzeigen
ok...ich werde als nächstes mal nur die sichtbaren tiles zeichnen....hier noch mal der ursprungscode...mit flip1 läuft das ganze schon einmal um einiges besser....jedenfalls bei mir....
Aber trotzdem ist eine cpu auslastung von 100% ein wenig viel für so eine kleine spielerei...
Könnte mir vorstellen dass das vllt an den vielen überprüfungen liegt, welches frame von der spielfigur abgespielt werden soll...
Code: [AUSKLAPPEN]
Global mapwidth = 75
Global mapheight =23
Global Player_pos_y = 200
Global Player_pos_x = 1024/2
Global playerframe = 6
Global Player_temp_y# = 0
Global jump
Global jumptimer#
Global Grav=False
Global Gravity#=-4

f#=0
time=MilliSecs()


Const rauf = 200, runter = 208, rechts = 205, links = 203, space = 57

Dim map(mapwidth,mapheight)
Dim map2(mapwidth/2,mapheight/2)
Dim map3(mapwidth,mapheight)

Graphics 1280,800,32,1
SetBuffer BackBuffer()
timer=CreateTimer(60)

load()

Global y,mx,my,mapx,mapy,mapx2,mapy2,tile
Global x;=200


Himmel = LoadImage("Himmel.jpg")
ScaleImage himmel,1.5,1

meerschweinchen = LoadAnimImage ("Kopie von ani8.bmp",64,64,0,18)
MaskImage Meerschweinchen,232,25,205
Vordergrund = LoadAnimImage("tilesetu.bmp",32,32,0,20)
MaskImage Vordergrund,232,25,205
Hintergrund = LoadAnimImage("tilesetup.bmp",64,64,0,20)
MaskImage Hintergrund,232,25,205

While Not KeyHit(1)
WaitTimer(timer)
Cls
DrawImage Himmel,0,0
For x = 0 To mapwidth/2
   For y = 0 To mapheight/2
      DrawImage Hintergrund,(x*64-(scrollx#)),(y*64-scrolly),map2(x,y)
   Next
Next


For x = 0 To mapwidth
   For y = 0 To mapheight
      DrawImage Vordergrund,(x*32-(scrollx#*2)),(y*32-scrolly),map(x,y)
   Next
Next

If KeyDown(links) Then   
      If map((Player_pos_x-16+scrollx#*2) /32,(Player_pos_y+32) /32)=0 Then
         scrollx#=scrollx#-2.5
         If jump=False And grav=False
         d=d-5
         If playerframe<9 Then playerframe=9
         If playerframe=17 Then playerframe=14
         If d Mod 25 =0 Then playerframe=playerframe+1
         If playerframe>14 Then playerframe=9
         ElseIf Jump=True
         playerframe=16
         EndIf         
      EndIf
   ElseIf KeyDown(rechts) Then
      If map((Player_pos_x+50+scrollx#*2)/32,(Player_pos_y+32)/32)=0 Then
         scrollx#=scrollx#+2.5
         If jump=False
            d=d+5
            If playerframe>9 Then playerframe=0
            If playerframe=8 Then playerframe=5
         If d Mod 25 =0 Then playerframe=playerframe+1
         If playerframe>5 Then playerframe=0   
         ElseIf jump=True
         playerframe=7
         EndIf
      EndIf
EndIf



If map(((Player_pos_x+scrollx#*2)+20) /32,(Player_pos_y+50) /32)=0 And Jump=False Then
grav=True
EndIf

If grav=True
    If playerframe<8 Then playerframe=8
    If playerframe>9 Then playerframe=17
   Gravity#=Gravity#-0.2
   Player_pos_y=Player_pos_y-Gravity#;6
   If map(((Player_pos_x+scrollx#*2)+20) /32,(Player_pos_y+50) /32)>0 Then Gravity#=-4 grav=False
EndIf

If KeyHit(rauf) And jump=False Then
Jump=True
player_temp_y#=8
EndIf

If Jump=True
    If playerframe<>7 And playerframe<9 Then playerframe=7
    If playerframe<>16 And playerframe>9 Then playerframe=16
   player_temp_y#=player_temp_y#-0.23
   Player_pos_y=player_pos_y-player_temp_y#
   If player_temp_y#<=0
      If playerframe=16 Then playerframe=17
      If playerframe=7 Then playerframe=8
      If player_temp_y#<-5 Then player_temp_y#=-5
      Player_pos_y=player_pos_y-player_temp_y#
      If map(((Player_pos_x+scrollx#*2)+20) /32,(Player_pos_y+50) /32)>0 Then
         Jump=False
      EndIf
   EndIf
EndIf

If KeyDown(rechts)<>True And KeyDown(links)<>True And playerframe<9 And jump<>1 And grav<>1 And map(((Player_pos_x+scrollx#*2)+20) /32,(Player_pos_y+50) /32)>0 Then playerframe=6
If KeyDown(rechts)<>True And KeyDown(links)<>True And playerframe>9 And jump<>1 And grav<>1 And map(((Player_pos_x+scrollx#*2)+20) /32,(Player_pos_y+50) /32)>0 Then playerframe=15


DrawImage meerschweinchen,Player_pos_x,Player_pos_y,playerframe
Plot Player_pos_x /32 ,player_pos_y
f=f+1
Color 0,0,0
Text 5,45,f#/(MilliSecs()-time)*1000
Text 5,5,"Gravitation = " + grav;player_temp_y
Text 5,25,"Sprung = " + Jump

Flip 1
Wend

Function load()
karte$ = ReadFile("map1.dat")
   For x = 0 To mapwidth
      For y = 0 To mapheight
         tile = ReadLine(karte$)
         map(x,y) = ReadInt(karte$)
      Next
   Next
   For x = 0 To mapwidth/2
      For y = 0 To mapheight/2
         tile = ReadLine(karte$)
         map2(x,y) = ReadInt(karte$)
      Next
   Next
CloseFile(karte$)
End Function



Hier nochmal zum download mit grafiken....:https://www.blitzforum.de/upload/file.php?id=2627
Mfg Kddc

Macbook Pro 13" 2,66Ghz

Dottakopf

BeitragDi, Jan 29, 2008 15:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Mal davon abgesehen das meim monitor grad von der auflösung agenippelt ist, ist es etwas krass ein 1200x800 großes bild zu scrollen. klammer das doch mal aus und schau dan mal die fps an. bei mir steigen die von 15 auf 48.

Ich würd sagen mach den vordergrund und hintergrund als 1 layer.
Dann denn den sichtbarkeitsbereich aller tiles auf den wirklich sichtbaren bereich einschränken.

Und ich würd dir vll anraten mit n paar funktionen mehr zu arbeiten.
Sowas wie :

Do_scrolling()
Update_player
Draw_map()


Zum thema wie mache ich das mit dem sichtbarkeits bereich. Hier ein beispiel des dir die antwort sogut wie fertig präsentiert:

Code: [AUSKLAPPEN]

Graphics 800,600,16,2
SetBuffer BackBuffer()

;einen sichbarkeitsbereich von 5x5 tiles
Global x_start = 0
Global x_max   = 5 

Global y_start = 0
Global y_max = 5



Dim tile_map(200,200)



;pseudo map
For x = 0 To 199
For y = 0 To 199
tile_map(x,y) = Rnd(0,1)
Next
Next


;--------------------------------------------
Repeat
Cls



      do_scrolling()
        draw_map()




Flip
Until KeyHit(1)
;--------------------------------------------



Function do_scrolling()

            ;beim scollen entweder den sichbarkeitsbereich "mit zählen" oder berechnen lassen
            If KeyHit(203) Then x_start = x_start -1 x_max = x_max -1
            If KeyHit(205) Then x_start = x_start +1 x_max = x_max +1
            If KeyHit(200) Then y_start = y_start -1 y_max = y_max -1
            If KeyHit(208) Then y_start = y_start +1 y_max = y_max +1


End Function



Function draw_map()

         ;immer nur sichtbarkeitsbereich malen
            For x = x_start To x_max
           For y = y_start To y_max

             If tile_map(x,y) >0 Then Rect x*32,y*32,32,32,tile_map(x,y)
            
         Next
         Next


End Function


mfg Dottakopf
Rechtschreibfehler gelten der allgemeinen Belustigung!

KddC

BeitragDi, Jan 29, 2008 17:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Cool....vielen dank für deine mühe....
das mit den functions hätte ich auch noch gemacht...aber eig mehr zur übersichtlichkeit....bringt das auch was um mehr geschw rauszuholen?
Mfg Kddc

Macbook Pro 13" 2,66Ghz

Dottakopf

BeitragMi, Jan 30, 2008 9:56
Antworten mit Zitat
Benutzer-Profile anzeigen
ob man jetzt mit funktionen arbeitet oder nicht, macht bestimmt keinen Geschwindigkeitsunterschied bei der Ausführung. Allerdings wird dein projekt evt. "arbeitszeitmäßig" schneller vorrankommen, und wenn man im team arbeitet, ist es doch sehr vorteilhaft wenn man seinen kollegen sagen kann, in welcher funktion das problemchen stecken könnte.

Des weiteren kann z.b. "IDEal" funktionen einfach einklappen, so dass es noch übersichtlicher wird.


mfg Dottakopf
Rechtschreibfehler gelten der allgemeinen Belustigung!

BladeRunner

Moderator

BeitragMi, Jan 30, 2008 11:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Funktionen sind per se langsamer als reiner code, da hier erst einmal alle Variablen in der Funktion sowie einsprung- und Rücksprungadresse auf dem Stack geparkt werden. Daher kann es sinnvoll sein zeitkritische Dinge nicht in eine Funktion auszulagern.

Ich persönlich würde allerdings immer zuerst eine Funktion nutzen, weil es einfach übersichtlicher ist. Den Code kann man später ohne weiteres in den Hauptcode rückverlagern, falls es so auf den Speed ankommt. Umgekehrt ists da wesentlich schwerer, man hat einen Codewust und soll Funktionen draus isolieren.

Also: Eine Funktion ist ein Kompromiss zugunsten der Übersichtlichkeit und zu ungunsten der Geschwindigkeit, aber einer der sich fast immer lohnt.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

KddC

BeitragDo, Jan 31, 2008 13:01
Antworten mit Zitat
Benutzer-Profile anzeigen
gut....genau deshalb hab ich functionen bis jetzt auch immer genutzt...mache sachen meist aber immer zuerst als reinen code....

IDEAL kenne ich und nutze ich auch ab und zu....

Jetzt werden immer nur die tiles angezeigt die auch sichtbar sind(und ein/zwei vorraus damit nicht sieht wie die eingeblendet werden)
Im fenstermodus hat sich, was die fps angeht nicht viel verändert(~4-5fps) aber im vollbild habe ich jetzt wieder 60...außerdem kann die map jezt ja auch beliebig groß sein...
Jetzt muss ich nur noch sehen welche auflösung ich nehme...mal sehen ob 800/600 oder 1024/768...

danke für eure hilfe

Nochmal so als frage...wie ist eig der code sonst so? gibt es da sehr viele sachen, die ihr komplett anders machen würdet? Und habt ihr sonst noch iwas zu meinem programierstil zu sagen? Würde mich über eine ehrlich rückmeldung freuen Smile
Mfg Kddc

Macbook Pro 13" 2,66Ghz

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group