Reputation: 122
So I have a tile-based game that is 216X384 units large. Each square in the cell_array is grass, which I pre-loaded with convert_alpha(). Each time it draws (I have fps at 30), it cycles through the cell_array and blits it onto the screen. If the cell_array is empty, it takes about 0.02 seconds to do this and other things, so 30 fps works just fine. but when it is filled with grass, it takes 0.08-0.1 seconds, making it lag a lot. Any tips, tricks, or ideas to help?
Here is what the cell_array code looks like.
cell_array = []
width_of_cells = 10
height_of_cells = 10
cell_Rows = 216
cell_Cols = 384
def initialize_empty_cell_board(rows, cols):
for x in range(cell_Cols):
new = []
for y in range(cell_Rows):
new.append(["NULL", False, True])
cell_array.append(new)
def add_tile(board, tile, cx, cy):
for i in range(tile.c_width):
for q in range(tile.c_height):
if cx+i < cell_Cols and cy+i < cell_Rows:
board[cx+i][cy+i] = [tile, False, tile.is_passible]
board[cx][cy] = [tile, True, tile.is_passible]
initialize_empty_cell_board(cell_Rows, cell_Cols)
And here is the blitting code:
cx = -1
cy = -1
for x in cell_array:
cy = -1
cx += 1
for y in x:
cy += 1
if y[0] != "NULL" and y[1] == True:
screen.blit(y[0].img.name, (cx*cells.width_of_cells, cy*cells.height_of_cells))
Here is what the image code looks like:
class Image(object):
def __init__(self, src):
self.name = pygame.image.load(src).convert_alpha()
Upvotes: 1
Views: 2954
Reputation: 1292
It would be much easier to process if the game didn't have to blit them every frame. I'm assuming this grass tile is the floor or a background. This means all of the grass can be pre-blitted to a surface and only the surface needs to be blitted every frame.
This example:
import pygame as py
py.init()
window = (400,400)
screen = py.display.set_mode(window)
font = py.font.Font(None,36)
clock = py.time.Clock()
def draw_onto_screen():
for i in xrange(0,200):
for j in xrange(0,200):
py.draw.rect(screen,(0,255,0),(i,j,5,5))
text = font.render(str(clock.get_fps()),1,(10,10,10))
screen.blit(text,(0,0))
done = False
while not done:
for event in py.event.get():
if event.type == py.QUIT:
done = True
draw_onto_screen()
py.display.flip()
clock.tick(60)
py.quit()
Draws 40,000 squares every frame and suffers for it displaying an average of 11fps on my machine (you can run it yourself and see the fps top left).
However if we draw all the squares onto another surface first (lets call it background) and the simply blit that surface we get:
import pygame as py
py.init()
window = (400,400)
screen = py.display.set_mode(window)
font = py.font.Font(None,36)
clock = py.time.Clock()
def draw_onto_screen():
for i in xrange(0,200):
for j in xrange(0,200):
py.draw.rect(background,(0,255,0),(i,j,5,5))
background = py.Surface(window)
draw_onto_screen() #### only called once
done = False
while not done:
for event in py.event.get():
if event.type == py.QUIT:
done = True
screen.blit(background,(0,0)) #### blit the background onto screen
text = font.render(str(clock.get_fps()),1,(10,10,10))
screen.blit(text,(0,0))
py.display.flip()
clock.tick(60)
py.quit()
Which draws exactly the same content but cruises at 62.5fps. Now when you want to move the background you simply blit it to a different location (currently (0,0))
Hope this helps.
Upvotes: 2