Pygame中用于简单2D Platformer的碰撞检测问题

seanie5011

这是我的第一篇文章,所以请让我知道是否应该更改任何内容。

我正在尝试创建一个简单的2D测试平台游戏,这是我在没有教程的情况下进行的第一个pygame项目。我遇到的问题是由于此can_jump变量。我正在使用此变量来阻止播放器不在平台或屏幕底部时无法跳转。我尝试了其他方法,但这就是我的最终选择。我觉得我已经接近了。

目前的问题似乎是,当站在平台上时,变量在平台循环self.can_jump1之间TrueFalse在平台循环中连续交换我注意到的时间恰好是3 Falses True),所以我将其隔离到中的注释部分collision_check()我不知道为什么会这样,据我所知,其余代码可以按我的意愿工作。

如果需要,我很乐意提供任何其他信息/说明。

这是我的代码:

import pygame, sys, random

#---Classes----------------------------------------#
class Block(pygame.sprite.Sprite): #inherited by rest of classes
    def __init__(self,path,x_pos,y_pos,size_x,size_y):
        super().__init__()
        self.image = pygame.transform.scale(pygame.image.load(path).convert_alpha(),(size_x,size_y))
        self.rect = self.image.get_rect(center = (x_pos,y_pos))

class PlatformRect(pygame.sprite.Sprite):
    def __init__(self,x_pos,y_pos,size_x,size_y,colour,players):
        super().__init__()
        self.center_x = x_pos
        self.center_y = y_pos
        self.size_x = size_x
        self.size_y = size_y
        self.colour = colour
        self.players = players
        self.can_jump1 = None

        self.image = pygame.Surface((self.size_x,self.size_y))
        self.image.fill(self.colour)
        self.rect = self.image.get_rect(center = (self.center_x,self.center_y))

    def collision_check(self):
        if pygame.sprite.spritecollide(self,self.players,False):
            collision_paddle = pygame.sprite.spritecollide(self,self.players,False)[0].rect
            if abs(self.rect.top - collision_paddle.bottom) < 10:
                collision_paddle.bottom = self.rect.top
                player.movement_y = 0
                self.can_jump1 = True
        else: #error isolated to here,consistently fluctuates between True and False, not sure why
            self.can_jump1 = False
        print(self.can_jump1) #if standing on platform should only produce True, everywhere else produce False

    def can_jump_check(self):
        return self.can_jump1

    def update(self):
        self.collision_check()


class Player(Block):
    def __init__(self,path,x_pos,y_pos,size_x,size_y,speed_x,acceleration_y):
        super().__init__(path,x_pos,y_pos,size_x,size_y)
        self.size_x = size_x
        self.size_y = size_y
        self.speed_x = speed_x
        self.acceleration_y = acceleration_y
        self.movement_x = 0
        self.movement_y = 0

    def screen_constrain(self):
        if self.rect.bottom >= sresy:
            self.rect.bottom = sresy
        if self.rect.left <= 0:
            self.rect.left = 0
        if self.rect.right >= sresx:
            self.rect.right = sresx

    def update(self):
        if abs(self.movement_y) <= 9:
            self.movement_y += GRAVITY
        self.rect.centery += self.movement_y
        self.rect.centerx += self.movement_x
        self.screen_constrain()

class GameManager:
    def __init__(self,player_group,platform_group):
        self.player_group = player_group
        self.platform_group = platform_group
        self.can_jump = True

    def run_game(self):
        #---drawing---#
        self.player_group.draw(screen)
        self.platform_group.draw(screen)

        #---updating---#
        self.player_group.update()
        self.platform_group.update()

    def game_checking(self):
        #---checking---#
        for sprite_platform in self.platform_group.sprites():
            if not sprite_platform.can_jump_check() == True:
                self.can_jump = False
            else:
                self.can_jump = True
            return self.can_jump




#---Setup------------------------------------------#
#---constants-----#
global GRAVITY
GRAVITY = 0.25

#---Gamevariables-----#
can_jump = True

#---colour---#
bg_colour = (50,50,50)
white_colour = (255,255,255)
black_colour = (0,0,0)

#---res---#
resx = 900
resy = 675
sresx = resx - 50
sresy = resy - 50


#---start window-----#
clock = pygame.time.Clock()

screendisplay = pygame.display.set_mode((resx,resy))
screendisplay.fill(bg_colour)
pygame.display.set_caption("PlatformerGame1 started 09/02/2021")

screen = pygame.Surface((sresx,sresy))
screen.fill(white_colour)

#---startgame-----#
player = Player("assets\\pics\\TestPlayerFigure1_256512.png",100,100,32,64,10,30)
player_group = pygame.sprite.GroupSingle()
player_group.add(player)

platform1 = PlatformRect(100,550,100,10,black_colour,player_group)
platform_group = pygame.sprite.Group()
platform_group.add(platform1)

game_manager = GameManager(player_group,platform_group)

#---Loop--------------------------------------------#
while True:
    #---events-----#
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()

            if event.key == pygame.K_SPACE:
                if can_jump == True:
                    player.movement_y = 0
                    player.movement_y -= player.acceleration_y * GRAVITY
            if event.key == pygame.K_a:
                player.movement_x -= player.speed_x
            if event.key == pygame.K_d:
                player.movement_x += player.speed_x

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_SPACE:
                if player.movement_y < 0:
                    player.movement_y = 0
            if event.key == pygame.K_a:
                player.movement_x += player.speed_x
            if event.key == pygame.K_d:
                player.movement_x -= player.speed_x

    #---background---#
    screendisplay.blit(screen,(25,25))
    screen.fill(white_colour)

    #---running---#
    game_manager.run_game()
    if not game_manager.game_checking() == True and player.rect.bottom < sresy:
        can_jump = False
    else:
        can_jump = True
    #print(can_jump)

    #---updating-----#
    pygame.display.update()
    clock.tick(60)
拉比德76

当播放器站在平台上时,播放器不会与平台发生碰撞self.can_jump1并被固定False测试如果玩家当球员不与平台发生碰撞的平台:

self.can_jump1 = False

self.can_jump1 = self.rect.top == self.players.sprites()[0].rect.bottom

方法collision_check

class PlatformRect(pygame.sprite.Sprite):
    # [...]

    def collision_check(self):
        collide_list = pygame.sprite.spritecollide(self,self.players,False)
        if collide_list: 
            collision_paddle = collide_list[0].rect
            if abs(self.rect.top - collision_paddle.bottom) < 10:
                collision_paddle.bottom = self.rect.top
                player.movement_y = 0
                self.can_jump1 = True
        else:
            self.can_jump1 = self.rect.top == self.players.sprites()[0].rect.bottom

GameManager.game_checking 需要检查折叠机是否与任何平台发生碰撞:

class GameManager:
    # [...]

    def game_checking(self):
        #---checking---#
        self.can_jump = False
        for sprite_platform in self.platform_group.sprites():
            if sprite_platform.can_jump_check() == True:
                self.can_jump = True
        return self.can_jump

可以使用以下any功能简化此操作

class PlatformRect(pygame.sprite.Sprite):
    # [...]

    def game_checking(self):
        #---checking---#
        self.can_jump = any(p.can_jump_check() for p in self.platform_group)
        return self.can_jump

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章