My terrain generator I want to be fullscreen, but when I change block size, FPS decreases. How to fix this?
pygame.init()
scsizeX = 600
scsizeY = 400
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
scX, scY = screen.get_size()
clock = pygame.time.Clock ()
plrX = 300
plrY = 200
speed = 3
plrOri = "Right"
cameraX = 0
cameraY = 0
genSize = 100
gen = []
fonts = [pygame.font.SysFont("Arial", 24)]
FPS = 1024
playerSize = 36
blockSize = 64
plrMoved = False
background_colour = (255,255,255)
clo = (255,255,0)
pygame.mouse.set_visible(False)
playerimg = pygame.image.load('assets/player.png')
mouseimg = pygame.image.load('assets/mouse.png')
grassimg = pygame.image.load('assets/grass.png')
stoneimg = pygame.image.load('assets/stone.png')
grassimg = pygame.transform.scale(grassimg, (blockSize, blockSize))
stoneimg = pygame.transform.scale(stoneimg, (blockSize, blockSize))
mouseimg = pygame.transform.scale(mouseimg, (48, 48))
playerimg = pygame.transform.scale(playerimg, (playerSize * 2, playerSize * 2))
screen.fill(background_colour)
player = screen.blit(playerimg, (300, 200))
mouse = screen.blit(mouseimg, (300, 200))
for x in range(genSize):
for y in range(genSize):
g = random.randint(1,2)
gen.append(g)
def block(tp, posX, posY):
if tp == "grass":
return screen.blit(grassimg, (posX - cameraX - playerSize, posY - cameraY - playerSize))
elif tp == "stone":
return screen.blit(stoneimg, (posX - cameraX - playerSize, posY - cameraY - playerSize))
def render(fnt, what, color, where):
"Renders the fonts as passed from display_fps"
text_to_show = fnt.render(what, 0, pygame.Color(color))
screen.blit(text_to_show, where)
game = True
while game:
screen.fill(background_colour)
plrMoved = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
game = False
if event.type == pygame.MOUSEBUTTONDOWN:
mouseimg = pygame.transform.scale(mouseimg, (44, 44))
if event.type == pygame.MOUSEBUTTONUP:
mouseimg = pygame.image.load('assets/mouse.png')
mouseimg = pygame.transform.scale(mouseimg, (48, 48))
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
plrY -= speed
plrMoved = True
if keys[pygame.K_a]:
plrX -= speed
plrMoved = True
plrOri = "Left"
if keys[pygame.K_s]:
plrY += speed
plrMoved = True
if keys[pygame.K_d]:
plrX += speed
plrMoved = True
plrOri = "Right"
cameraX = plrX - (scsizeX / 2)
cameraY = plrY - (scsizeY / 2)
#player = screen.blit(playerimg, (plrX, plrY))
#if plrMoved:
for x in range(int(scX / blockSize) + 2):
for y in range(int(scY / blockSize) + 3):
g = gen[(floor(cameraX / blockSize) + x) + (floor(cameraY / blockSize) + y)]
if g == 1:
block("grass", (floor(cameraX / blockSize) + x) * blockSize, (floor(cameraY / blockSize) + y) * blockSize)
elif g == 2:
block("stone", (floor(cameraX / blockSize) + x) * blockSize, (floor(cameraY / blockSize) + y) * blockSize)
p_pos = plrX - cameraX - playerSize, plrY - cameraY - playerSize,
if plrOri == "Right":
player = screen.blit(playerimg, p_pos)
elif plrOri == "Left":
player = screen.blit(pygame.transform.flip(playerimg, True, False), p_pos)
Mx, My = pygame.mouse.get_pos()
msrct = mouseimg.get_rect()
msrct = msrct.move((Mx, My))
mouse = screen.blit(mouseimg, msrct)
render(
fonts[0],
what=str(int(clock.get_fps())),
color="white",
where=(0, 0))
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
I tried to only update terrain when player is moving but FPS is still low and when I stop moving the screen gets white.
Ensure that the background Surface has the same format as the display Surface. Use convert()
(or convert_alpha()
) to create a Surface that has the same pixel format. This improves performance when the background is, when the background is blit
on the display, because the formats are compatible and blit
does not need to perform an implicit transformation:
playerimg = pygame.image.load('assets/player.png').convert_alpha()
mouseimg = pygame.image.load('assets/mouse.png').convert_alpha()
grassimg = pygame.image.load('assets/grass.png').convert_alpha()
stoneimg = pygame.image.load('assets/stone.png').convert_alpha()
You can buy performance by paying with memory usage. Create a large Surface
with the complete map:
game_map = pygame.Surface((genSize * 64, genSize*64))
for x in range(genSize):
for y in range(genSize):
g = random.randint(1,2)
if g == 1:
game_map.blit(grassimg, (x * 64, y * 64))
elif g == 2:
game_map.blit(stoneimg, (x * 64, y * 64))
blit
the area which is currently visible on the screen:
while game:
# [...]
map_sub_rect = screen.get_rect(topleft = (cameraX, cameraY))
screen.blit(game_map, (0, 0), map_sub_rect)
# [...]