群组碰撞在Pygame的平台滚动条上不起作用

问题描述 投票:0回答:1

我跟随此tutorial,并且我已将class Opponent()添加到class Platform(),如图here所示。接下来,我一直试图将groupcollide_and_loop_for添加到完整的代码中,以便在被子弹击中时将对手移除。我一直在研究question本身中使用groupcollide的方法。我尝试了几种方法来在class Opponent()groupcollide内部调用def main,但是没有得到任何结果或任何错误,只是没有用。

groupcollide_and_loop_for:

while not done

将上面的groupcollide和for循环部署到下面的代码:

    collided_opponents = pygame.sprite.groupcollide(opponents, bullet_list, False, True)
    for opponent, bullets in collided_opponents.items():
        for bullet in bullets:
            score += 1  # Increment the score.
            opponent.lives -= 1  # Decrement the lives.
            pygame.display.set_caption(str(score))

我遵循了本教程,并且在类Platform()中添加了Opponent()类,如下所示。接下来,我一直在尝试将groupcollide_and_loop_for添加到完整的代码中,以便对手是...

python class pygame main bullet
1个回答
0
投票

我使用import pygame # Global constants bulletpicture = pygame.image.load("bullet.png") # Colors BLACK = (0, 0, 0) WHITE = (255, 255, 255) GREEN = (0, 255, 0) RED = (255, 0, 0) BLUE = (0, 0, 255) # Screen dimensions SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 class Player(pygame.sprite.Sprite): """ This class represents the bar at the bottom that the player controls. """ # -- Methods def __init__(self): """ Constructor function """ # Call the parent's constructor super().__init__() # Create an image of the block, and fill it with a color. # This could also be an image loaded from the disk. width = 40 height = 60 self.image = pygame.Surface([width, height]) self.image.fill(RED) # Set a referance to the image rect. self.rect = self.image.get_rect() # Set speed vector of player self.change_x = 0 self.change_y = 0 # List of sprites we can bump against self.level = None def update(self): """ Move the player. """ # Gravity self.calc_grav() # Move left/right self.rect.x += self.change_x # See if we hit anything block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False) for block in block_hit_list: # If we are moving right, # set our right side to the left side of the item we hit if self.change_x > 0: self.rect.right = block.rect.left elif self.change_x < 0: # Otherwise if we are moving left, do the opposite. self.rect.left = block.rect.right # Move up/down self.rect.y += self.change_y # Check and see if we hit anything block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False) for block in block_hit_list: # Reset our position based on the top/bottom of the object. if self.change_y > 0: self.rect.bottom = block.rect.top elif self.change_y < 0: self.rect.top = block.rect.bottom # Stop our vertical movement self.change_y = 0 def calc_grav(self): """ Calculate effect of gravity. """ if self.change_y == 0: self.change_y = 1 else: self.change_y += .35 # See if we are on the ground. if self.rect.y >= SCREEN_HEIGHT - self.rect.height and self.change_y >= 0: self.change_y = 0 self.rect.y = SCREEN_HEIGHT - self.rect.height def jump(self): """ Called when user hits 'jump' button. """ # move down a bit and see if there is a platform below us. # Move down 2 pixels because it doesn't work well if we only move down 1 # when working with a platform moving down. self.rect.y += 2 platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False) self.rect.y -= 2 # If it is ok to jump, set our speed upwards if len(platform_hit_list) > 0 or self.rect.bottom >= SCREEN_HEIGHT: self.change_y = -10 # Player-controlled movement: def go_left(self): """ Called when the user hits the left arrow. """ self.change_x = -6 def go_right(self): """ Called when the user hits the right arrow. """ self.change_x = 6 def stop(self): """ Called when the user lets off the keyboard. """ self.change_x = 0 class Platform(pygame.sprite.Sprite): """ Platform the user can jump on """ def __init__(self, width, height): """ Platform constructor. Assumes constructed with user passing in an array of 5 numbers like what's defined at the top of this code. """ super().__init__() self.image = pygame.Surface([width, height]) self.image.fill(GREEN) self.rect = self.image.get_rect() class Level(): """ This is a generic super-class used to define a level. Create a child class for each level with level-specific info. """ def __init__(self, player): """ Constructor. Pass in a handle to player. Needed for when moving platforms collide with the player. """ self.platform_list = pygame.sprite.Group() self.enemy_list = pygame.sprite.Group() self.player = player # How far this world has been scrolled left/right self.world_shift = 0 # Update everythign on this level def update(self): """ Update everything in this level.""" self.platform_list.update() self.enemy_list.update() def draw(self, screen): """ Draw everything on this level. """ # Draw the background screen.fill(BLUE) # Draw all the sprite lists that we have self.platform_list.draw(screen) self.enemy_list.draw(screen) def shift_world(self, shift_x): """ When the user moves left/right and we need to scroll everything: """ # Keep track of the shift amount self.world_shift += shift_x # Go through all the sprite lists and shift for platform in self.platform_list: platform.rect.x += shift_x for enemy in self.enemy_list: enemy.rect.x += shift_x class Bullet(pygame.sprite.Sprite): """This class represents the bullet.""" def __init__(self,x,y): super().__init__() self.image = bulletpicture self.image.set_colorkey(BLACK) self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y def update(self): """Move the bullet.""" self.rect.y -= 5 # Remove the bullet if it flies up off the screen if self.rect.y < -12: self.kill() # Remove the sprite from all sprite groups. class Opponent(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.image.load("cowboy.png") #.convert() self.rect = self.image.get_rect() self.lives = 1 self.rect.x = 50 self.rect.y = 280 self.change_x = 1 self.change_y = 0 # List of sprites we can bump against self.level = None pass def update(self): if self.lives <= 0: self.kill() # Remove the sprite from all sprite groups. self.rect.x += self.change_x if self.rect.x > 280: self.change_x *= -1 self.rect.x += self.change_x if self.rect.x < 0: self.change_x *= -1 self.rect.x += self.change_x pass # Create platforms for the level class Level_01(Level): """ Definition for level 1. """ def __init__(self, player): """ Create level 1. """ # Call the parent constructor Level.__init__(self, player) self.level_limit = -1000 # Array with width, height, x, and y of platform level = [[210, 70, 500, 500], [210, 70, 800, 400], [210, 70, 1000, 500], [210, 70, 1120, 280], ] # Go through the array above and add platforms for platform in level: block = Platform(platform[0], platform[1]) block.rect.x = platform[2] block.rect.y = platform[3] block.player = self.player self.platform_list.add(block) for enemy in level: opponent = Opponent() opponent.rect.x = 150 opponent.rect.y = 280 opponent.player = self.player self.enemy_list.add(opponent) # Create platforms for the level class Level_02(Level): """ Definition for level 2. """ def __init__(self, player): """ Create level 1. """ # Call the parent constructor Level.__init__(self, player) self.level_limit = -1000 # Array with type of platform, and x, y location of the platform. level = [[210, 30, 450, 570], [210, 30, 850, 420], [210, 30, 1000, 520], [210, 30, 1120, 280], ] # Go through the array above and add platforms for platform in level: block = Platform(platform[0], platform[1]) block.rect.x = platform[2] block.rect.y = platform[3] block.player = self.player self.platform_list.add(block) def main(): """ Main Program """ pygame.init() # Set the height and width of the screen size = [SCREEN_WIDTH, SCREEN_HEIGHT] screen = pygame.display.set_mode(size) pygame.display.set_caption("Side-scrolling Platformer") # Create the player player = Player() # Create all the levels level_list = [] level_list.append(Level_01(player)) level_list.append(Level_02(player)) # Set the current level current_level_no = 0 current_level = level_list[current_level_no] active_sprite_list = pygame.sprite.Group() player.level = current_level player.rect.x = 340 player.rect.y = SCREEN_HEIGHT - player.rect.height active_sprite_list.add(player) # --- NEW bullet_list = pygame.sprite.Group() player_list = pygame.sprite.Group() player_list.add(player) opponent = Opponent() opponents = pygame.sprite.Group() opponents.add(opponent) score = 0 # Loop until the user clicks the close button. done = False # Used to manage how fast the screen updates clock = pygame.time.Clock() # -------- Main Program Loop ----------- while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True elif event.type == pygame.MOUSEBUTTONDOWN: # Click a mouse button to instantiate a bullet. bullet = Bullet(player.rect.x,player.rect.y) bullet_list.add(bullet) active_sprite_list.add(bullet) if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: player.go_left() if event.key == pygame.K_RIGHT: player.go_right() if event.key == pygame.K_UP: player.jump() if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT and player.change_x < 0: player.stop() if event.key == pygame.K_RIGHT and player.change_x > 0: player.stop() # Update the player. active_sprite_list.update() # ----- The code commented below is what I tried in many ways #collided_opponents = pygame.sprite.groupcollide(opponents, bullet_list, False, True) #for opponent, bullets in collided_opponents.items(): # for bullet in bullets: # score += 1 # Increment the score. # opponent.lives -= 1 # Decrement the lives. # pygame.display.set_caption(str(score)) # Update items in the level current_level.update() # If the player gets near the right side, shift the world left (-x) if player.rect.right >= 500: diff = player.rect.right - 500 player.rect.right = 500 current_level.shift_world(-diff) # If the player gets near the left side, shift the world right (+x) if player.rect.left <= 120: diff = 120 - player.rect.left player.rect.left = 120 current_level.shift_world(diff) # If the player gets to the end of the level, go to the next level current_position = player.rect.x + current_level.world_shift if current_position < current_level.level_limit: player.rect.x = 120 if current_level_no < len(level_list)-1: current_level_no += 1 current_level = level_list[current_level_no] player.level = current_level # ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT current_level.draw(screen) active_sprite_list.draw(screen) # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT # Limit to 60 frames per second clock.tick(60) # Go ahead and update the screen with what we've drawn. pygame.display.flip() # Be IDLE friendly. If you forget this line, the program will 'hang' # on exit. pygame.quit() if __name__ == "__main__": main() 查看print()opponent的位置。而且我发现bullet从不改变位置。

© www.soinside.com 2019 - 2024. All rights reserved.