2017-06-16 107 views
1

我一直在pygame的一個小項目。這是一款架空的2D遊戲,但是如果玩家在物體後面,我需要玩家在它後面一層。如果玩家位於物體的前方,它需要位於物體之前。什麼是在pygame中像這樣分層的好方法?

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) 

回答

1

我試着用這個代碼(最有可能的作品)

當紅色的表面是綠色的綠色將重疊的身後,這就是爲什麼我保持透明一點。當紅色超過它將在綠色blitting。代碼和你一樣。 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) 
+0

我有一個感受那是因爲我正在做多次在屏幕上每一個角色。我正在尋找一種合乎邏輯的方式來做到這一點,但謝謝! – Qwerty

+0

發佈代碼。有人可能會幫助 – GLaDOS

+0

我發佈了整個代碼 – Qwerty

4

停止與Surfaces直接工作。使用pygame的Sprite類。

然後,您可以簡單地給你的精靈一個_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

+0

這是正確的答案。使用Pygame是愚蠢的,但忽略其內置的精靈和碰撞函數。不要重新發明輪子。 – Chris

+0

@sloth謝謝你的回答,但有沒有辦法用Surfaces來做到這一點?如果沒有,我會使用精靈 – Qwerty

+0

@sloth沒關係,這確實是正確的答案,謝謝你的幫助 – Qwerty

相關問題