[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [pygame] How fast is pygame meant to be?
Christian Perfect wrote:
> I'm a Blitz Basic (www.blitzbasic.com) user who's been playing
> aroudn with pygame, so the first thing I decided to do was to make a pygame
> version of the "firepaint" demo that comes with BB. It's a simple demo that
> shoots sparks from your mouse cursor that fall to the screen when you click
> the mouse. I'm no good at optimising, so the code just follows the BB
> firepaint demo pretty closely. When I ran the demo, it ran *much* slower
> than the BB demo, at 8fps, whereas in BB it runs at my refresh rate (80fps+)
> Is pygame just not meant to be used for this kind of thing, and just
> blitting a few images and playing some sounds, or is there some secret
> different way of doing things I haven't found yet? :)
this big difference you are seeing is the difference between
hardware accelerated graphics and not. i'm guessing blitzbasic only
works with directx, therefore you probably only get hardware
accelerated graphics.
in pygame you can also get hardware acceleration, but it's not
always the case. i've made a couple changes to your code. it should
now get hardware accelerated if it is supported on your system. i
tested it on a NT4 machine with no directx. at 300mhz the program
ran at 26fps with no frags, and 23fps with a couple explosions
onscreen. with hardware acceleration i'm guessing you will also be
at 80fps like bb.
here's the main set of changes i made (attached is the slightly new
version)
first, you were assembling your 'set_mode()' flags slightly wrong.
you had "HWSURFACE and DOUBLEBUF and FULLSCREEN". this is using
python's "logical and" operation. what you need is the "bitwise or"
operation. so this should become "HWSURFACE|DOUBLEBUF|FULLSCREEN".
second, i wrapped all the code into a function named "main". the
main reason for this was so the game didn't need to access "global
variables" when it is running. in python global vars are a little
slower than normal local variables. in code that is called very
frequently (like frag.update) you can start to notice this difference.
i changed the "pygame.draw.rect" code to "Surface.fill" which will
do the same thing here for you. the Surface.fill has the benefit of
being hardware accelerated when it can be.
that's pretty much it. i believe with the acceleration enabled this
will run plenty quick for you. if not it could definitely be
rearranged to run faster. if you want to explore that road let me know.
#Firepaint demo by Christian Perfect
#Based on the Blitz Basic firepaint demo by Mark Sibly
#This one's much slower :(
#Imports
import pygame
from pygame.locals import *
from random import *
from math import sin,cos
#frag class
class frag:
#Create a frag, give it a random velocity
def __init__(self,pos):
self.pos=pos[:]
an=randrange(1000)
vel=randrange(3,4)
self.move=[sin(an)*vel,cos(an)*vel]
self.r=255
self.g=255
self.b=255
#Update and draw frag
def update(self, gravity, screen, frags):
self.move[1]+=gravity
self.pos[0]+=self.move[0]
self.pos[1]+=self.move[1]
if self.r <= 0 or self.pos[0]<0 or self.pos[0]>640 or self.pos[1]<0 or self.pos[1]>480:
frags.remove(self)
return
if self.b>0:
self.b-=5
if self.g>0:
self.g-=3
if self.r>0:
self.r-=1
col=(self.r,self.g,self.b)
screen.fill(col, (self.pos, (3,3)))
def main():
#Init pygame
pygame.init()
pygame.font.init()
myfont=pygame.font.Font(None,24)
screen = pygame.display.set_mode([640,480], HWSURFACE|FULLSCREEN|DOUBLEBUF)
hardware = ("software", "hardware")[screen.get_flags() & HWSURFACE == HWSURFACE]
pygame.display.set_caption('Pygame Test')
black = 0, 0, 0
screen.fill(black)
#Some variables
frags=[]
intensity=20 #Increase this for more frags!
mousedown=0
gravity=.1
black=0,0,0
white=255,255,255
done=0
clock=pygame.time.Clock()
mousepos=[0,0]
while not done:
#Update frags
for afrag in frags:
afrag.update(gravity, screen, frags)
#Check events
for e in pygame.event.get():
if e.type == QUIT or (e.type == KEYUP and e.key == K_ESCAPE):
done=1
break
elif e.type == MOUSEBUTTONDOWN:
mousedown=1
elif e.type == MOUSEBUTTONUP:
mousedown=0
elif e.type == MOUSEMOTION:
mousepos=[e.pos[0],e.pos[1]]
#Make new frags
if mousedown:
mousedown = 0
for c in range(randrange(intensity,2*intensity)):
frags.append(frag(mousepos))
#Calculate FPS
clock.tick()
fps = clock.get_fps()
#Print fps and flame count on screen
fpstext=myfont.render('%s FPS: %d'%(hardware, fps),0,white)
counttext=myfont.render('No. Flames: '+str(len(frags)),0,white)
screen.blit(fpstext,(0,0))
screen.blit(counttext,(0,26))
#Draw mouse cursor
#pygame.draw.line(screen,white,(mousepos[0],mousepos[1]-5),(mousepos[0],mousepos[1]+5))
#pygame.draw.line(screen,white,(mousepos[0]-5,mousepos[1]),(mousepos[0]+5,mousepos[1]))
#Update display
pygame.display.flip()
screen.fill(black)
main()