[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()