碰撞检测在 pygame 中不起作用 [英] Collision detection not working in pygame

查看:53
本文介绍了碰撞检测在 pygame 中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在制作游戏,但遇到碰撞检测问题.我正在结束关卡块,但它无法检测到玩家是否站在它上面以更改为 2 级.块的碰撞检测在 player.updater() 中找到.除此之外,该块是一个类,并在一个名为 endPlatform 的组中,以允许碰撞检测工作.游戏运行良好,但无法检测到玩家何时点击 Endplatform.我没有收到任何显示的错误.

I am making a game at the moment and I am experiencing problems with collision detection. I am making an end of level block but it can not detect if the player is standing on it to change to level 2. The collision detection for the block is found in player.updater(). As well as this the block is a class and in a group called endPlatform to allow the collision detection to work. The game runs perfectly fine however it can not detect when the Player hits Endplatform. I get no errors which show up.

结束平台:

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()

推荐答案

看来我发现了问题,出于某种愚蠢的原因,您不能对同一个对象使用两次碰撞检测.我用过一次是为了让玩家可以站在方块上,另一次是为了你可以进入下一个关卡!

It seems I found the problem, for some daft reason you can't use collision detection twice on the same object. I used it once so that the player could stand on the block and another time so that you could go on to the next level!

这篇关于碰撞检测在 pygame 中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆