在pygame中这样分层的好方法是什么?

时间:2017-06-16 04:21:23

标签: python pygame python-2.x

我一直在pygame上开展一个小项目。它是一个高架2D游戏,但如果一个玩家在一个物体后面,我需要玩家在它后面一层。如果玩家位于对象前面,则需要在其前面一层。

    for image, imagerect, imageypos in zip(blitimages, blitrects, blitypositions):

    if realy < imageypos:
        screen.blit(playerimage, playerimagerect)
        screen.blit(image, imagerect)
    if realy > imageypos:
        screen.blit(image, imagerect)
        screen.blit(playerimage, playerimagerect)

    if realy == imageypos:
        screen.blit(playerimage, playerimagerect)
        screen.blit(image, imagerect)

这就是我尝试过的,但它不起作用。它始终将玩家展示在前面。

供参考:

blitrects = [house1imagerect, house2imagerect, rock1imagerect]
blitimages = [house1image, house2image, rock1image]
blitypositions = [house1y, house2y, rock1y]

我主要需要一种方法来正确地做到这一点(这也很快),以及为什么这种方式不起作用。如果需要答案,我愿意发布更多部分代码,只需发表评论即可!提前谢谢!

编辑:

整个代码:

import sys, pygame, math, random
pygame.init()

size = width, height = 1000,720
x = 0
y = 0




house1x = 500
house1y = 360

house2x = 1470
house2y = 360


rock1x = -100
rock1y = 300


scrollx = 0
scrolly = 0
screen = pygame.display.set_mode(size, pygame.DOUBLEBUF)
counter = 0


playercollideRect =  pygame.rect.Rect((0, 0), (75, 25))

house1collideRect = pygame.rect.Rect((0, 0), (870, 605))
house2collideRect = pygame.rect.Rect((0, 0), (870, 605))

rock1collideRect = pygame.rect.Rect((0, 0), (140, 100))



collision = False


lastkey = 'down'
animationdirection = 'down'



playerimage = pygame.image.load("img/player/player0.png").convert_alpha()
playerimagerect = playerimage.get_rect()


house1image = pygame.image.load("img/structures/house1.png").convert_alpha()
house1imagerect = house1image.get_rect()

house2image = pygame.image.load("img/structures/house2.png").convert_alpha()
house2imagerect = house2image.get_rect()


rock1image = pygame.image.load("img/objects/rock1.png").convert_alpha()
rock1imagerect = rock1image.get_rect()



clock = pygame.time.Clock()

screencolor = 0, 155, 20
gamefont = pygame.font.SysFont("arial", 30)

playeranimationdown = ['img/player/player1.png','img/player/player0.png','img/player/player2.png','img/player/player0.png']
playeranimationup = ['img/player/playerback1.png','img/player/playerback0.png','img/player/playerback2.png','img/player/playerback0.png']
playeranimationleft = ['img/player/playerleft1.png','img/player/playerleft0.png','img/player/playerleft2.png','img/player/playerleft0.png']
playeranimationright = ['img/player/playerright1.png','img/player/playerright0.png','img/player/playerright2.png','img/player/playerright0.png']


pygame.mixer.music.load('audio/music/ambient.mp3')
pygame.mixer.music.set_endevent(pygame.constants.USEREVENT)
pygame.mixer.music.play()
pygame.display.set_caption('Game')
pygame.event.set_allowed([pygame.QUIT, pygame.KEYDOWN, pygame.KEYUP])

colliders = [house1collideRect, house2collideRect, rock1collideRect]
blitrects = [house1imagerect, house2imagerect, rock1imagerect]
blitimages = [house1image, house2image, rock1image]
blitypositions = [house1y, house2y, rock1y]

while 1:

    clock.tick(500)

    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()

    if y > 720-75-100:
        y = 720-75-100
        scrolly -= 1
    if y < 0+75+100:
        y = 0+75+100
        scrolly += 1
    if x > 1000-37-100:
        x=1000-37-100
        scrollx -=1
    if x < 0+37+100:
        x = 0+37+100
        scrollx +=1


    for collider in colliders:
        if playercollideRect.colliderect(collider):
            if lastkey == 'left':
                x += 1
            if lastkey == 'right':
                x -= 1
            if lastkey == 'up':
                y += 1
            if lastkey == 'down':
                y -= 1
            collision = True
        else:
            collision = False


    keys = pygame.key.get_pressed()
    if keys[pygame.K_UP] or keys[pygame.K_DOWN] or keys[pygame.K_LEFT] or keys[pygame.K_RIGHT]:
        if keys[pygame.K_UP]:
            y -= 1

            if not collision == True:
                playerimage = pygame.image.load(playeranimationup[int(math.floor(counter/50))]).convert_alpha()
                counter = (counter + 1) % 200
            lastkey = 'up'


        elif keys[pygame.K_DOWN]:
            y += 1
            if not collision == True:
                playerimage = pygame.image.load(playeranimationdown[int(math.floor(counter/50))]).convert_alpha()
                counter = (counter + 1) % 200
            lastkey = 'down'


        elif keys[pygame.K_RIGHT]:
            x += 1
            if not collision == True:
                playerimage = pygame.image.load(playeranimationright[int(math.floor(counter/50))]).convert_alpha()

                counter = (counter + 1) % 200
            lastkey = 'right'

        elif keys[pygame.K_LEFT]:
            x -= 1

            if not collision == True:
                playerimage = pygame.image.load(playeranimationleft[int(math.floor(counter/50))]).convert_alpha()

                counter = (counter + 1) % 200
            lastkey = 'left'




    playerimagerect.centerx = x
    playerimagerect.centery = y


    house1imagerect.centerx = house1x+scrollx
    house1imagerect.centery = house1y+scrolly

    house2imagerect.centerx = house2x+scrollx
    house2imagerect.centery = house2y+scrolly

    rock1imagerect.centerx = rock1x+scrollx
    rock1imagerect.centery = rock1y+scrolly



    playercollideRect.midbottom = playerimagerect.midbottom

    house1collideRect.midbottom = house1imagerect.midbottom
    house2collideRect.midbottom = house2imagerect.midbottom

    rock1collideRect.midbottom = rock1imagerect.midbottom


    realx = x-scrollx
    realy = y-scrolly



    for image, imagerect, imageypos in zip(blitimages, blitrects, blitypositions):

        if realy < imageypos:
            screen.blit(playerimage, playerimagerect)
            screen.blit(image, imagerect)
        if realy > imageypos:
            screen.blit(image, imagerect)
            screen.blit(playerimage, playerimagerect)

        if realy == imageypos:
            screen.blit(playerimage, playerimagerect)
            screen.blit(image, imagerect)





    label = gamefont.render(str('FPS: '+str(clock.get_fps())), 1, (255,255,0))
    screen.blit(label, (50, 50))

    pygame.display.flip()
    screen.fill(screencolor)

2 个答案:

答案 0 :(得分:4)

不要直接使用Surfaces。使用pygame的Sprite类。

然后,您可以简单地为您的Sprit提供_layer属性,并使用LayeredUpdates组来管理它们,该小组将负责blitting的顺序。

以下是一个例子:

import pygame
pygame.init()
screen = pygame.display.set_mode((300, 300))

class Actor(pygame.sprite.Sprite):
    def __init__(self, group, color, layer, pos):
        self.image = pygame.Surface((30, 30))
        self.image.fill(color)
        self.rect = self.image.get_rect(center=pos)
        self._layer = layer
        pygame.sprite.Sprite.__init__(self, group)

group = pygame.sprite.LayeredUpdates()
Actor(group, (255, 255, 255), 0, (100, 100))
Actor(group, (255, 0, 255),   1, (110, 110))
Actor(group, (0, 255, 255),   0, (120, 120))
Actor(group, (255, 255, 0),   3, (130, 130))
Actor(group, (0, 0, 255),     2, (140, 140))

run = True
while run:
    for e in pygame.event.get():
        if e.type ==pygame.QUIT:
            run = False
    screen.fill((0,0,0))
    group.update()
    group.draw(screen)
    pygame.display.flip()

请注意精灵的顺序是由_layer属性的值决定的。

enter image description here

答案 1 :(得分:1)

我尝试使用此代码(很可能有效)

当红色表面位于绿色后面时,绿色将重叠,这就是为什么我保持它有点透明的原因。当红色超车时,它将在绿色上显示。代码和你一样。 IDK为什么你的工作

import pygame

pygame.init()
clock = pygame.time.Clock()

screen = pygame.display.set_mode((800,600))

surface1 = pygame.Surface((50,50))
surface1.fill((255,0,0))

surface2 = pygame.Surface((50,50))
surface2.fill((0,255,0))
surface2.set_alpha(196)

surface1X = 0
surface1Y = 275

surface2X = 400
surface2Y = 275

x_change = 0
y_change = 0

speed = 2

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change = -speed
            if event.key == pygame.K_RIGHT:
                x_change = speed
            if event.key == pygame.K_UP:
                y_change = -speed
            if event.key == pygame.K_DOWN:
                y_change = speed

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                x_change = 0
                y_change = 0

    surface1X += x_change
    surface1Y += y_change

    screen.fill((255,255,255))

    if (surface1X < surface2X):
        screen.blit(surface1, (surface1X, surface1Y))
        screen.blit(surface2, (surface2X, surface2Y))

    else:
        screen.blit(surface2, (surface2X, surface2Y))
        screen.blit(surface1, (surface1X, surface1Y))

    pygame.display.update()
    clock.tick(60)