[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [pygame] Testing vector graphics
Leonardo Santagada wrote:
> Here is my test to make sure pygame could do a good job drawing
> vectors. It is not very well documented, nor it's finished. But I want
> to know from you all if I'm doing everything right and fast, because I'm
> getting 99 fps just drawing one spaceship and I am using a PIII-850
> 384mb ram and a nvidia TNT2 card running the nvidia accelerated drivers
> for linux.
a couple things.. first, i like what you've done to the sprite
classes. i think it's a good start. here's the biggest things i see.
first, you are clearing and flipping the entire screen for each
frame. on my p2-300 at work the program runs at 35fps. not that the
vector graphics are too slow, that is simply the maximum speed this
computer can fill/flip an entire screen surface with software rendering.
with some minor changes i've got "teste" only updating the parts of
the screen that are drawn to, and a cheap fix to only fill the parts
of the screen that have a ship on them.
on my machine the framerate jumps up to over 800fps. now in the end
this may not have such a benefit for you. if the real game has the
entire screen filled with vector effects, you'll be at the same
speed as the fullscreen fill/flip. i guess it just depends what the
game is going to be if this will really benefit you or not.
also, the graphics card and driver will really not make much
difference for you with this type of program. it is basically all
software based, and the line rendering in pygame is done with
software, so probably works best on regular software surfaces. it's
really just a test of how quick the cpu can move pixels around in
memory.
actually, i suppose with accelerated displays the fill and flip are
done in hardware, so it could be a bit faster. i'm just unsure the
speed of software line rendering on hardware surfaces...
hmm, actually, instead of filling the vector areas with black, you
might be better off redrawing the lines with black? it might be
worth trying.
#!/usr/bin/env python
#rotação(cartesiana) Escala(cart.)
# ([cos(x),-sen(x)], ([],
# [sen(x),cos(x))
import pygame,pygame.draw,pygame.time
from pygame.locals import *
from pygame.sprite import *
from Numeric import *
#constants
rotations=180 #how many rotations to generate
konstant=-5 #a costant for inverting and scaling all game objects
#create a cos and sin table
cost=[]
sint=[]
pirot=2*pi/rotations
for rotation in arange(0,rotations*pirot,pirot):
cost.append(ceil(cos(rotation)*1000)/1000)
sint.append(ceil(sin(rotation)*1000)/1000)
def rotate(data,rot):
"""rotate the matrix passed as data,
and returns the new rotated matrix"""
mrot=array([[cost[rot],-sint[rot]],
[sint[rot],cost[rot]]])
temp=matrixmultiply(mrot,data)
return temp
def create_rotations(data):
"""Create the needed rotations for
all vecobj"""
rotlist=[]
m=array([[konstant,0],
[0,konstant]])
tdata=matrixmultiply(m,data)
for rot in range(rotations):
rotlist.append(rotate(tdata,rot))
return rotlist
class vecobj(Sprite):
"""Main descendant from sprite with
support for vector graphics"""
def __init__(self,pos,rot=0,color=(255,255,255)):
Sprite.__init__(self, self.containers)
self.color=color
self.pos=pos
self.data=self.images[rot%rotations]
self.rot=rot%rotations
def rotate(self,rot):
self.data=self.images[rot%rotations]
self.rot=rot%rotations
class naves(vecobj):
pass
class RenderVectorPlain(Group):
"""Group used to draw vector objects"""
def draw(self, surface):
"""draw(surface)
draw all sprites onto a surface
Draws all the sprites onto the given surface."""
spritedict = self.spritedict
surface_blit = draw_vecobj
dirty = []
for s in spritedict.keys():
dirty.append(surface_blit(surface, s))
return dirty
def draw_vecobj(surface,vecobj):
"""Draw objects in the screen"""
tcolor=vecobj.color
rect = pygame.draw.lines(surface, tcolor, 0, transpose(vecobj.data+vecobj.pos))
return rect.inflate(4, 4)
def main():
pygame.init()
screen = pygame.display.set_mode((640,480),1|DOUBLEBUF,16)
#data for some objects
anave=array([[0,1,3,3,0,-3,-3,-1,0],[5,0,2,-2,-1,-2,2,0,5]])
acasa=array([[5,5,-5,-5,5,4,4,2,2,5,5,0,-5],[-5,5,5,-5,-5,-5,-1,-1,-5,-5,5,8,5]])
#Group and Sprite stuff
vectors=RenderVectorPlain()
naves.containers= vectors
naves.images=create_rotations(anave)
nave1=naves(array([[160],[100]]))
frames=0
ticks=pygame.time.get_ticks()
while 1:
event = pygame.event.poll()
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
break
keystate = pygame.key.get_pressed()
directionx = keystate[K_RIGHT] - keystate[K_LEFT]
directiony = keystate[K_DOWN] - keystate[K_UP]
nave1.pos[1]+=directiony
nave1.rotate(nave1.rot+directionx)
dirty = vectors.draw(screen)
pygame.display.update(dirty)
for d in dirty:
screen.fill(0, d)
frames = frames+1
print "fps: %d" % ((frames*1000)/(pygame.time.get_ticks()-ticks))
#this is the python code to quickstart the program if not imported
if __name__ == '__main__': main()