[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[pygame] Back to the Scrolling
- To: pygame-users@seul.org
- Subject: [pygame] Back to the Scrolling
- From: Pete Shinners <pete@shinners.org>
- Date: Mon, 02 Dec 2002 23:26:31 +0000
- Delivered-To: archiver@seul.org
- Delivered-To: pygame-users-outgoing@seul.org
- Delivered-To: pygame-users@seul.org
- Delivery-Date: Tue, 03 Dec 2002 02:14:14 -0500
- Reply-To: pygame-users@seul.org
- Sender: owner-pygame-users@seul.org
- User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2) Gecko/20021201
I've been tinkering with the scrolling screens in pygame more. I've
added a test function to pygame that draws a row of images in C. I was
thinking this would make a noticeable impact in speed and still be very
flexible (since you could still do isometric engines and such by
blitting a row at a time).
in the end, it doesn't really seem to be speeding things up for me. at
this point i'm trying to determine if the extra function is worth the
effort. the function is named "pygame.draw.tilerow()". if you grab the
latest cvs pygame you can test it out.
i've attached an updated of the now popular scrolling colored blocks
example. is anyone seeing a difference between this new one and the
originals we did a couple weeks ago?
in the end i'm not so sure about this. unless it proves valuable to
someone out there, i have a feeling it will be dropped. at this point
the C code could still be optimized a bit, but i wouldn't expect much
more out of it.
note, if you do update from cvs, be sure to rebuild all the c modules,
there were some internal changes that require a rebuild. this is easy to
do, "python setup.py install build_ext --force"
everyone feel free to send in ideas on how this could be improved a bit.
if there's a nice general way to get rid of the python overhead in
scrolling, i'm all for it. the big performance problem with full
scrolling is really copying all that memory around, and SDL makes it
happen twice internally, ugh.
#!/usr/bin/env python
"""
the Map class stores all the tiles in a big list. you can lookup
any tile by calling the "tile(x,y)" method. it does a little
voodoo to speed up the drawing loop. you call the draw() method
with a surface and "map x,y" position arguements. the x,y
coordinates are in actual pixels, and that will be the position
in the center of the screen. it allows for any size tiles and map.
i admit it's not written to be clear, as much turbo quick and
semi flexible. you can run it for a simple scrolling example
with the mouse. hopefully this is quick enough for you, i don't think it can
be much quicker with just python code. I've been thinking about
a C function in pygame to blit a "row" of images. But I'm not
certain that would make a noticeable difference?
Pete Shinners, November 21, 2002
"""
import pygame, random
from pygame import *
TILESIZE = 64, 64
MAPSIZE = 30, 30
class Tile:
blocked = 0
def __init__(self):
#make a random colored block
color = map(random.randint, [0]*3, [255]*3)
self.image = pygame.Surface(TILESIZE).convert()
self.image.fill(color)
class Map:
def __init__(self):
#initialize variables
tilew, tileh = TILESIZE
self.numtilesx = 640/tilew+2
self.numtilesy = 480/tileh+2
self.tilesx, self.tilesy = MAPSIZE
self.tilew = tilew
self.tileh = tileh
#fill the map with tiles
self.tiles = [Tile() for x in range(self.tilesx*self.tilesy)]
self.outofbounds= self.tiles[0]
self.cachetilerows()
def tile(self, x, y):
if x<0 or y<0 or x>=self.tilesx or y>=self.tilesy:
return self.outofbounds
return self.tiles[y*self.tilesx+x]
def cachetilerows(self):
for y in range(self.tilesy):
for x in range(self.tilesx):
tile = self.tile(x,y)
tile.rowtiles = [self.tile(x+z,y) for z in range(self.numtilesx)]
def draw(self, screen, px, py):
#px -= screen.get_rect().centerx
#py -= screen.get_rect().centery
startx = px / self.tilew
starty = py / self.tileh
px = - (px % self.tilew)
py = - (py % self.tileh)
#rowrange = range(startx, startx+self.numtilesx)
for y in range(starty, starty + self.numtilesy):
#imgs = [self.tile(x,y).image for x in rowrange]
imgs = [t.image for t in self.tile(startx,y).rowtiles]
pygame.draw.tilerow(screen, imgs, (px, py))
py += self.tileh
def main():
import pygame
pygame.init()
flags = 0 #FULLSCREEN|DOUBLEBUF
screen = pygame.display.set_mode((640, 480), flags)
print pygame.display.Info()
print screen
posx, posy = 800, 800
map = Map()
timer = pygame.time.Clock()
pygame.time.set_timer(USEREVENT, 1000)
font = pygame.font.Font(None, 40)
message = None
while 1:
timer.tick()
for e in pygame.event.get():
if e.type == QUIT: raise SystemExit, "QUIT"
if e.type == KEYDOWN and e.key == K_ESCAPE: raise SystemExit, "ESCAPE"
if e.type == MOUSEMOTION:
posx -= e.rel[0]
posy -= e.rel[1]
elif e.type == USEREVENT:
s = "Frames Per Second: %.2f" % timer.get_fps()
message = font.render(s, 0, (255,255,255), (0,0,0)).convert()
map.draw(screen, posx, posy)
if message:
screen.blit(message, (0,0))
pygame.display.flip()
if __name__ == '__main__':
main()