2015-11-25 83 views
0

我正在製作遊戲,並且遇到碰撞檢測問題。我正在製作關卡塊的結尾,但是它無法檢測到玩家是否站在關卡上以更改爲2級。該塊的碰撞檢測可以在player.updater()中找到。除此之外,該塊是一個類,並且位於稱爲endPlatform的組中,以允許碰撞檢測工作。遊戲運行完美,但無法檢測到玩家何時碰到Endplatform。我沒有得到任何出現的錯誤。碰撞檢測不能在pygame中工作

EndPlatform:

class EndPlatform(pygame.sprite.Sprite): 
    def __init__(self, display): 
     super().__init__() 
     self.image = pygame.image.load("endPlatform.png") 
     self.rect = self.image.get_rect() 
     display.blit(self.image, self.rect) 

球員:

class Player(pygame.sprite.Sprite): 
    def __init__(self): 
     super().__init__() 
     # Is it touching the floor? 
     self.standing = True 
     # Rendering image and creating some variables 
     self.image = pygame.image.load("Slime.png") 
     self.sprite_x_change = 0 
     self.sprite_y_change = 0 
     self.rect = self.image.get_rect() 
     self.rect.y = 460 
     self.rect.x = 120 
    # Mobility: Left, right, up and stop 
    def move_right(self): 
     self.sprite_x_change = 8 

    def move_left(self): 
     self.sprite_x_change = -8 

    def move_up(self, platform): 
     if self.standing == True: 
      self.sprite_y_change = -25 
      self.standing = False 
    def stop(self): 
     self.sprite_x_change = 0 

    def sprint(self): 
     self.sprite_x_change += 10 

    def updater(self, platforms, powerups, score, endPlatform): 
     self.gravity() 
     self.rect.x += self.sprite_x_change 
     self.standing = False 
     platforms_hit = pygame.sprite.spritecollide(self, platforms, False) 
     for blocks in platforms_hit: 
      if self.sprite_x_change > 0: 
       self.rect.right = blocks.rect.left 

      elif self.sprite_x_change < 0: 
       self.rect.left = blocks.rect.right 

     self.rect.y += self.sprite_y_change 

     platforms_hit = pygame.sprite.spritecollide(self, platforms, False) 
     for blocks in platforms_hit: 
      # Going down 
      if self.sprite_y_change > 0: 
       self.rect.bottom = blocks.rect.top - 1 
       self.standing = True 
      # Going up 
      elif self.sprite_y_change < 0: 
       self.rect.top = blocks.rect.bottom 
       self.standing = False 

      self.sprite_y_change = 0 

     coins_hit = pygame.sprite.spritecollide(self, powerups, True) 
     if len(coins_hit) > 0: 
      score.add() 
     endLevel = pygame.sprite.spritecollide(self, endPlatform, True) 
     if len(endLevel) > 0: 
      score.add() 

所有代碼:

import pygame 
import random 

pygame.font.init() 
# Colours + Global constants 
WHITE = (255, 255, 255) 
RED = (255, 0, 0) 
GREEN = (0, 255, 0) 
BLUE = (0, 0, 255) 
BLACK = (0, 0, 0) 
RANDOM = (12, 211, 123) 
WIDTH = 800 
HEIGHT = 600 
SIZE = (WIDTH, HEIGHT) 
AGENT = pygame.font.SysFont("Agent Orange", 30) 


# CLASSES 
# Block is the common platform 
class EndPlatform(pygame.sprite.Sprite): 
    def __init__(self, display): 
     super().__init__() 
     self.image = pygame.image.load("endPlatform.png") 
     self.rect = self.image.get_rect() 
     display.blit(self.image, self.rect) 




class Coins(pygame.sprite.Sprite): 
    def __init__(self, display): 
     super().__init__() 
     self.image = pygame.image.load("hud_coins.png") 
     self.rect = self.image.get_rect() 
     display.blit(self.image, self.rect) 



class Score: 
    def __init__(self): 
     self.score = 0 

    def msgs(self, msg, colour, display): 
     screen_text = AGENT.render(msg, True, colour) 
     display.blit(screen_text, [0, 0]) 

    def add(self): 
     self.score += 1 


class Monster(pygame.sprite.Sprite): 
    def __init__(self, length, height, colour): 
     super().__init__() 
     self.image = pygame.Surface([length, height]) 
     self.image.fill(colour) 
     self.rect = self.image.get_rect() 
     # Setting Y coordinates 
     self.rect.y = HEIGHT - 80 

    def jump(self): 
     self.rect.y = -10 


class Block(pygame.sprite.Sprite): 
    def __init__(self, length, height, colour): 
     super().__init__() 
     # Making image 
     self.image = pygame.Surface([length, height]) 
     self.image.fill(colour) 
     self.rect = self.image.get_rect() 
     # Setting Y coordinates 
     self.rect.y = 468 


class Platform(pygame.sprite.Sprite): 
    def __init__(self, display, x_screen, y_screen, x_sheet, y_sheet, height, length): 
     super().__init__() 

     self.tiles = pygame.image.load("tiles_spritesheet.png") 

     self.image = self.tiles.subsurface(pygame.Rect(x_sheet, y_sheet, height, length)) 
     self.rect = self.image.get_rect(x=x_screen, y=y_screen) 



class Player(pygame.sprite.Sprite): 
    def __init__(self): 
     super().__init__() 
     # Is it touching the floor? 
     self.standing = True 
     # Rendering image and creating some variables 
     self.image = pygame.image.load("Slime.png") 
     self.sprite_x_change = 0 
     self.sprite_y_change = 0 
     self.rect = self.image.get_rect() 
     self.rect.y = 460 
     self.rect.x = 120 
    # Mobility: Left, right, up and stop 
    def move_right(self): 
     self.sprite_x_change = 8 

    def move_left(self): 
     self.sprite_x_change = -8 

    def move_up(self, platform): 
     if self.standing == True: 
      self.sprite_y_change = -25 
      self.standing = False 
    def stop(self): 
     self.sprite_x_change = 0 

    def sprint(self): 
     self.sprite_x_change += 10 

    def updater(self, platforms, powerups, score, endPlatform): 
     self.gravity() 
     self.rect.x += self.sprite_x_change 
     self.standing = False 
     platforms_hit = pygame.sprite.spritecollide(self, platforms, False) 
     for blocks in platforms_hit: 
      if self.sprite_x_change > 0: 
       self.rect.right = blocks.rect.left 

      elif self.sprite_x_change < 0: 
       self.rect.left = blocks.rect.right 

     self.rect.y += self.sprite_y_change 

     platforms_hit = pygame.sprite.spritecollide(self, platforms, False) 
     for blocks in platforms_hit: 
      # Going down 
      if self.sprite_y_change > 0: 
       self.rect.bottom = blocks.rect.top - 1 
       self.standing = True 
      # Going up 
      elif self.sprite_y_change < 0: 
       self.rect.top = blocks.rect.bottom 
       self.standing = False 

      self.sprite_y_change = 0 

     coins_hit = pygame.sprite.spritecollide(self, powerups, True) 
     if len(coins_hit) > 0: 
      score.add() 
     endLevel = pygame.sprite.spritecollide(self, endPlatform, True) 
     if len(endLevel) > 0: 
      score.add() 

    def gravity(self): 
     self.sprite_y_change += 3 


class Level: 
    def __init__(self): 
     # Creating groups 
     self.endPlatform = pygame.sprite.Group() 
     self.powerups = pygame.sprite.Group() 
     self.sprites = pygame.sprite.Group() 
     self.all_things = pygame.sprite.Group() 
     self.platforms = pygame.sprite.Group() 
     self.entities = pygame.sprite.Group() 
     self.shift_x = 0 
     self.shift_y = 0 

    def updater(self, display, score): 
     self.all_things.draw(display) 
     score.msgs("Score: " + str(score.score), RED, display) 


    def scroll_x(self, shift_x_change): 
     self.shift_x += shift_x_change 
     for platform in self.entities: 
      platform.rect.x += shift_x_change 

    def scroll_y(self, shift_y_change): 
     self.shift_y += shift_y_change 
     for platform in self.entities: 
      platform.rect.y += shift_y_change 



class Level01(Level): 
    def __init__(self, player1, monster, display): 
     # Initialise level1 
     super().__init__() 
     # Level01 things 
     block = Block(245, 3, BLACK) 
     Level.all_things = self.all_things 
     self.sprites.add(player1, monster) 
     self.platforms.add(block) 
     self.all_things.add(player1, block, monster) 
     self.entities.add(block) 

     theLevel = [] 

     level = [[600, 400, 648, 0, 70, 70], 
       [740, 320, 648, 0, 70, 70], 
       [380, 400, 648, 0, 70, 70], 
       [900, 280, 648, 0, 70, 70], 
       [1200, 530, 648, 0, 70, 70], 
       [1350, 450, 648, 0, 70, 70], 
       [1500, 550, 648, 0, 70, 70], 
       [1680, 500, 648, 0, 70, 70], 
       ] 

     for platform in theLevel: 
      block = Block(platform[0], platform[1], RED) 
      block.rect.x = platform[2] 
      block.rect.y = platform[3] 
      self.platforms.add(block) 
      self.all_things.add(block) 
      self.entities.add(block) 
     for goodPlatform in level: 
      platform = Platform(display, goodPlatform[0], goodPlatform[1], goodPlatform[2], goodPlatform[3], goodPlatform[4], goodPlatform[5]) 
      self.platforms.add(platform) 
      self.all_things.add(platform) 
      self.entities.add(platform) 
     for n in range(1): 
      coin = Coins(display) 
      coin.rect.x = random.randint(0, WIDTH*3) 
      coin.rect.y = 400 
      self.all_things.add(coin) 
      self.entities.add(coin) 
      self.powerups.add(coin) 
      platforms_hit = pygame.sprite.spritecollide(coin, self.entities, False) 
      for hit in platforms_hit: 
       coin.rect.x = random.randrange(0, WIDTH*3) 
     finalPlatform = EndPlatform(display) 
     finalPlatform.rect.x = 1900 
     finalPlatform.rect.y = 420 
     self.all_things.add(finalPlatform) 
     self.entities.add(finalPlatform) 
     self.platforms.add(finalPlatform) 
     self.endPlatform.add(finalPlatform) 


class Level02(Level): 
    def __init__(self, player1, monster): 
     super().__init__() 
     # Level01 things 
     block = Block(245, 3, BLACK) 
     Level.all_things = self.all_things 
     self.sprites.add(player1, monster) 
     self.platforms.add(block) 
     self.all_things.add(player1, block, monster) 
def main(): 
    # Init pygame 
    pygame.init() 
    # Set screen 
    backgrounds = ["background2.jpg", "background.jpg"] 
    background = pygame.image.load(backgrounds[0]) 
    backgroundRect = background.get_rect() 
    display = pygame.display.set_mode(background.get_size()) 
    # Creating FPS thingy 
    clock = pygame.time.Clock() 
    # Making levels + Player 
    score = Score() 
    monster = Monster(30, 30, RANDOM) 
    player = Player() 
    level_1 = Level01(player, monster, display) 
    level_2 = Level02(player, monster) 
    # Choosing level 
    levelList = [] 
    levelList.append(level_1) 
    levelList.append(level_2) 
    currentLevelNumber = 0 
    # Game loop 
    loop = True 
    while loop == True: 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       pygame.quit() 
      if event.type == pygame.KEYDOWN: 
        if event.key == pygame.K_RIGHT: 
         player.move_right() 
        if event.key == pygame.K_LEFT: 
         player.move_left() 
        if event.key == pygame.K_UP: 
         player.move_up(currentLevel.platforms) 
        if event.key == pygame.KMOD_LSHIFT and event.key == pygame.K_RIGHT: 
         player.sprint() 
      if event.type == pygame.KEYUP: 
       if event.key == pygame.K_LEFT and player.sprite_x_change < 0: 
        player.stop() 
       if event.key == pygame.K_RIGHT and player.sprite_x_change > 0: 
        player.stop() 
       if event.key == pygame.KMOD_LSHIFT: 
        player.sprite_x_change -= 10 
     # Update things 
     #monster.jump() 
     if player.rect.x > 400: 
      player.rect.x = 400 
      currentLevel.scroll_x(-10) 

     if player.rect.x >= WIDTH: 
      player.rect.x = WIDTH 
      currentLevel.scroll(0) 

     if player.rect.y >= HEIGHT: 
      main() 

     if player.sprite_x_change < 0 and player.rect.x >= 120: 
      currentLevel.scroll_x(0) 


     if player.rect.left <= 120 and player.sprite_x_change < 0: 
      player.rect.x = 120 
      player.rect.left = 120 
      currentLevel.scroll_x(10) 
     ''' 
     if player.rect.y <= 300: 
      if player.standing == False and player.sprite_y_change < 0: 
       currentLevel.scroll_y(10) 

     if currentLevel.shift_y > 0: 
      y_speed = -4 
      if player.standing == True and player.rect.y < 300: 
       y_speed = 4 
      print(currentLevel.shift_y) 
      currentLevel.scroll_y(y_speed) 
     ''' 
     currentLevel = levelList[currentLevelNumber] 

     if currentLevel.shift_x > 0: 
      currentLevel.scroll_x(currentLevel.shift_x * -1) 

     display.blit(background, backgroundRect) 
     player.updater(currentLevel.platforms, currentLevel.powerups, score, currentLevel.endPlatform) 
     currentLevel.updater(display, score) 
     # Refresh screen 
     clock.tick(30) 
     pygame.display.update() 
    pygame.quit() 
    loop = False 

if __name__ == "__main__": 
    main() 
+0

確保塊和播放器的矩形值正確設置並相互碰撞。據我所知,你沒有設置結束塊的X/Y座標。 – ventsyv

+0

我在Level_01類中設置x和y座標,我確定我也是爲Player做的。 – Fabmaur

+0

你能輸出玩家的座標嗎?此外,嘗試明確設置碰撞檢測函數(pygame.sprite.collide_rect())作爲spritecolide的第四個參數 – ventsyv

回答

0

看來我發現這個問題,因爲你不能使用一些碰撞愚蠢的原因在同一個對象上檢測兩次。我曾經使用過一次,這樣玩家就可以站在這個街區上,而又一次讓你可以進入下一個級別!