Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
781 views
in Technique[技术] by (71.8m points)

python - How Can I Improve My Terrain Generator Performance I Get 40 FPS

I Made a Terrain Generator I want My Game To Be At FullScreen, But When I Change The Block Size The FPS Decrease. I Don't Have Any Idea How to Fix This Problem.

Here Is my Code:

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 The Terrain When Player Is Moving But My FPS is Still Low And When I stop Moving Player Screen Gets White.

Thank you For Reading.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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)

    # [...]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...