[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [pygame] Fast Scrolling
As promised I included my version... I am curious to know which of
Pete or mine is quicker...
And I would be greatful to anybody who can optimise that ... to death :)
Guillaume
import pygame
from pygame.locals import *
class TileLevel:
def __init__(self,tiles,tilesize,dataarray,rect,displayablerect):
self.tiles = tiles
self.dataarray = dataarray
(self.tw,self.th) = tilesize
(self.w,self.h)=rect
(self.dw,self.dh)=displayablerect
def prepareAtCameraPos(self,x,y,dx=0,dy=0):
self.x = x
self.y = y
self.dx = dx
self.dy = dy
leveldata=self.dataarray
tiles=self.tiles
tw=self.tw
th=self.th
dw=self.dw
dh=self.dh
buffer=self.buffer=pygame.Surface(((1+dw+1)*tw,(1+dh+1)*th)).convert()
ysurfpos=0
for j in range(y,y+dh+2):
xsurfpos=0
for i in range(x,x+dw+2):
buffer.blit(tiles[leveldata[i][j]],(xsurfpos,ysurfpos))
xsurfpos=xsurfpos+tw
ysurfpos=ysurfpos+th
def moveCamera(self,mx,my):
newx=x=self.x
newy=y=self.y
dx=self.dx
dy=self.dy
dw=self.dw
dh=self.dh
tw=self.tw
th=self.th
newdx=dx+mx
newdy=dy+my
dx=newdx%tw
newx=x+(newdx/tw)
if newdx<0:
dx=dx-tw
newx=newx+1
dy=newdy%th
newy=y+(newdy/th)
if newdy<0:
dy=dy-th
newy=newy+1
# make sure we don't go over our limits
if newx<1:
newx=1
dx=-tw
elif newx>self.w-dw-2:
newx=self.w-dw-2
dx=tw
if newy<1:
newy=1
dy=-th
elif newy>self.h-dh-2:
newy=self.h-dh-2
dy=th
# update the subdeplacement
self.dx=dx
self.dy=dy
# update the underlying bitmap
if self.x != newx or self.y !=newy:
self.moveUpdate(newx,newy)
def moveUpdate(self,newx,newy):
diffx=self.x-newx
diffy=self.y-newy
self.x=newx
self.y=newy
dwreal=self.dw+2
dhreal=self.dh+2
tw=self.tw
th=self.th
tiles=self.tiles
data=self.dataarray
# first let's move the picture around
self.buffer.blit(self.buffer,(diffx*tw,diffy*th))
# then we rebuilt around the messed picture
# first we rebuilt the vertical tiles
if diffx != 0:
if diffx<0:
r=range(newx+dwreal+diffx,newx+dwreal)
startposx=(dwreal+diffx)*tw
else:
r=range(newx,newx+diffx)
startposx=0
tposy=0
for j in range(newy,newy+dhreal):
tposx=startposx
for i in r:
self.buffer.blit(tiles[data[i][j]],(tposx,tposy))
tposx=tposx+tw
tposy=tposy+th
# then the horizontal tiles
if diffy != 0:
if diffy<0:
jr=range(newy+dhreal+diffy,newy+dhreal)
startposy=(dhreal+diffy)*th
else:
jr=range(newy,newy+diffy)
startposy=0
if diffx <= 0:
ir=range(newx,newx+dwreal+diffx)
startposx=0
else:
ir=range(newx+diffx,newx+dwreal)
startposx=diffx
posx=startposx*tw
for i in ir:
posy=startposy
for j in jr:
self.buffer.blit(tiles[data[i][j]],(posx,posy))
posy=posy+th
posx=posx+tw
def paint(self,screen,coords):
screen.blit(self.buffer,coords,(self.tw+self.dx,self.th+self.dy,self.tw*self.dw,self.dh*self.th))
import random
class Bob:
def __init__(self,surf,x,y,vx,vy,w,h):
self.surf=surf
self.x=x
self.y=y
self.vx=vx
self.vy=vy
self.w=w
self.h=h
def runpaint(self,dc,x,y):
self.x=self.x+self.vx
self.y=self.y+self.vy
if self.x<0 or self.x>=self.w:
self.vx=-self.vx
self.x=max(min(self.x,self.w-1),0)
if self.y<0 or self.y>=self.h:
self.vy=-self.vy
self.y=max(min(self.y,self.h-1),0)
dc.blit(self.surf,(x+self.x,y+self.y))
def main():
global frame
leveldata=[]
for j in range(0,400):
new=[]
for i in range(0,40):
new.append(random.randrange(100))
leveldata.append(new)
pygame.init()
flag=FULLSCREEN|DOUBLEBUF|HWSURFACE
screen=pygame.display.set_mode((640,480),flag,16)
print pygame.display.get_driver()
print pygame.display.Info()
tiles=[]
for i in range(0,100):
color = map(random.randint, [0]*3, [255]*3)
s=pygame.Surface((64,64)).convert()
s.fill(color)
tiles.append(s)
level=TileLevel(tiles,(64,64),leveldata,(60,40),(10,7))
level.prepareAtCameraPos(20,20)
clock=pygame.time.Clock()
frame=0
bobs=[]
for i in range(0,26):
bobs.append(Bob(tiles[i],random.randrange(576),random.randrange(576),random.randrange(6)-3,random.randrange(6)-3,640-64,64*6))
x=y=0
vx=3
vy=2
(mouseposxold,mouseposyold)=pygame.mouse.get_pos()
while 1:
clock.tick()
level.paint(screen,(0,0))
for b in bobs:
b.runpaint(screen,0,0)
pygame.display.flip()
(mouseposxnew,mouseposynew)=pygame.mouse.get_pos()
level.moveCamera(mouseposxnew-mouseposxold,mouseposynew-mouseposyold)
mouseposxold,mouseposyold=mouseposxnew,mouseposynew
frame=(frame+1)&127
if frame == 0:
print clock.get_fps()
l=pygame.event.get()
if len(l) and l[0].type == KEYDOWN:
break
main()