Seite 1 von 1
pygame langsam und ruckelt?
Verfasst: Montag 31. August 2009, 15:25
von The Hit-Man
ich habe mal nen kleines programm geschrieben, das einen sternenhimmel simuliert. allerdings habe ich das gefühl, das es nicht so recht smooth ist, und irgendwie auch ruckelt. auf meinem 700Mhz rechner, ist es dann kaum noch zumutbar, obwohl alle rechner 3D beschleunigung haben ( nutze linux debian lenny ).
Code: Alles auswählen
import pygame, random
from pygame.locals import *
xsize=800
ysize=600
pygame.init()
screen = pygame.display.set_mode([xsize,ysize],pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.FULLSCREEN,32)
screen.fill([0,0,0])
mainloop, x,y, color, fontsize, delta, fps = True, 25 , 0, (16,16,16), 35, 1, 30
clock = pygame.time.Clock()
x=range(xsize)
for i in range(1, xsize):
x[i]=random.randrange(1,xsize)
while mainloop:
y=0
tick_time = clock.tick(fps) # milliseconds since last frame
pygame.display.set_caption("press Esc to quit. FPS: %.2f" % (clock.get_fps()))
for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
mainloop = False
screen.fill([0,0,0])
for i in range(1, xsize):
screen.set_at((x[i], y), (255,255,255))
y=y+1
for i in range(1, xsize):
x[i]=x[i]+1
for i in range(1, xsize, 2):
x[i]=x[i]+1
for i in range(1, xsize, 3):
x[i]=x[i]+1
for i in range(1, xsize):
if x[i]>xsize:
x[i]=0
pygame.display.update()
weiß da jemand rat?
Verfasst: Montag 31. August 2009, 17:50
von EyDu
Ich kenne mich mit PyGame nicht aus, aber vielleicht ist
Clock.tick etwas für dich.
Die letzten vier for-Schleifen kann man übrigens gut zu einer zusammenfassen. Für die letzte Schleife Empfehle ich einen Blick auf den Modulo-Operator (%).
Nur kurz nachgefragt: Zeilen 30 bis 32 sollen nicht den Bildschirm löschen, oder?
Verfasst: Montag 31. August 2009, 18:06
von BlackJack
@EyDu: Die Zeilen sollen die Sterne (Punkte) zeichnen, aber damit ist definitiv etwas nicht in Ordnung, weil `y` von 1 bis 799 läuft, aber so viele Zeilen gibt es auf dem Surface ja gar nicht.
Verfasst: Montag 31. August 2009, 18:37
von The Hit-Man
@BlackJack
richtig, löschen mache ich mit fill.
ja, suche schon nach einem timer, sprich clock, tick. aber ich habe mal gehört, das das gar nicht so einfach sein soll, da jeder bildschirm eine andere frequenz haben könnte.
EDIT:
nur hier sehe ich gerade, das der clock timer nur dafür da ist, eine bestimmte zeit einzuhalten
http://jonasbsb.jo.funpic.de/hendrix/py ... ample.html
beim c64er war das irgendwie einfacher. da konnte ich den rasterstrahl einfach abfragen. je nach dem, wo er stand, konnte man einen weichen scroller programmieren. ich frage mich nur, wie soll so etwas auf dem PC bzw. SDL gehen?
Verfasst: Montag 31. August 2009, 20:14
von BlackJack
@The Hit-Man: Zuverlässig geht das auf dem PC im Grunde (heute) gar nicht (mehr). TFTs haben ja nicht einmal einen Rasterstrahl, dessen Position man abfragen könnte.
Bei VGA-Karten kann man den Zeitpunkt abfragen, bei dem der Rasterstahl wieder vom unteren Bildrand zum oberen Bildrand hochbewegt wird, ich weiss aber nicht, ob SDL das benutzt oder irgendwie zur Verfügung stellt. Ausserdem würde man die Geschwindigkeit dann von der Bildwiederholzahl des Monitors bzw. Grafikmodus abhängig machen. Etwas, dass man eigentlich auch nicht wirklich möchte.
Andererseits kann ich bei meinem Starscroller und einem TFT kein besonderes ruckeln feststellen:
http://paste.pocoo.org/show/137336/
Verfasst: Dienstag 1. September 2009, 08:17
von The Hit-Man
@BlackJack
habs mir angesehen, und deines sieht genau so aus wie meins. bei den sternen fällt das auch nicht ganz so auf, aber laß mal nen logo drüber fliegen in einem tic tac effekt. also nen logo, was sich von links nach rechts bewegt, per sinus bewegung ( sinus deshalb, das es sanft hin und her schwingt ). ich glaube, dann sieht man das ruckeln. des weiteren weiß ich nicht, warum meine framerate so in den keller geht und der prozessor so ausgelastet ist
EDIT: es spielt auch keine rolle, welche programmiersprache. habs in python, C und C# programmiert. überall der gleiche effekt. irgendwie muß es aber möglich sein, da es ja auch gute spiele unter SDL gibt. des weiteren hatte ich irgendwo nen smooth-scroller gesehen, der eine landschaft scrollt. war unter C geschrieben, aber was der da für timerberechnungen genommen hatte, war nen wahnsinn. das wollte ich eigentlich vermeiden, irgendwie.
Verfasst: Dienstag 1. September 2009, 12:39
von yipyip
Um irgendwelche Timerberechnungen wirst Du wohl nicht herumkommen. Die wahrgenommene Geschwindigkeit sollte natuerlich unabhaengig von den FPS sein. Die Geschwindigkeit in Pixeln sollte in Abhaengigkeit von der Dauer eines Frames berechnet werden. Habe mit Deinem Code mal etwas herumgespielt, weiss aber nicht, ob das hier Dir 'smooth' genug ist:
Code: Alles auswählen
import pygame, random
from pygame.locals import *
xsize = 800
ysize = 600
pygame.init()
screen = pygame.display.set_mode([xsize,ysize],pygame.DOUBLEBUF |
pygame.HWSURFACE #| pygame.FULLSCREEN,
,32)
screen.fill([0,0,0])
mainloop, x,y, color, fontsize, delta = True, 25 , 0, (16,16,16), 35, 1
clock = pygame.time.Clock()
x=range(xsize)
for i in range(1, ysize):
x[i]=random.randrange(1, xsize)
## !
FPS = 500
SPEED = 0.07
dx = 0
while mainloop:
y=0
tick_time = clock.tick_busy_loop(FPS) # milliseconds since last frame
pygame.display.set_caption("press Esc to quit. FPS: %.2f" % (clock.get_fps()))
for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
mainloop = False
screen.fill([0,0,0])
for i in xrange(1, ysize):
screen.set_at((int(x[i] + 0.5), y), (255,255,255))
y=y+1
for i in range(1, xsize):
x[i]=x[i] + dx #!
for i in range(1, xsize, 2):
x[i]=x[i] + dx #!
for i in range(1, xsize, 3):
x[i]=x[i] + dx #!
for i in range(1, xsize):
if x[i]>xsize:
x[i]=0
pygame.display.update()
## !
ms = clock.get_time() # ms per frame
dx = SPEED * ms
Die Prozessorauslastung betraegt ca. 66%.
yipyip