Displaying platforms using strings (Pygame)

2019-09-04 20:02发布

问题:

I'm having troubling getting a platform to display in areas that I have 'P' string in. I'm trying to create a level in pygame using strings instead of set coordinates for every platform. Here's a sample...

class Level_01(Level):

    def __init__(self, player):

        self.background = forest_bg

        Level.__init__(self, player)

        platforms = []

        x = y = 0
        level = ['            ',
                 'P           ',
                 '            ',
                 '  P         ',
                 '            ',
                 'PPPPPPPPPPPP',]

        # build the level
        for row in level:
            for col in row:
                if col == 'P':
                    P = Platform(x, y)
                    platforms.append(P)
                x += 90
            y += 90
            x = 0

Here is the whole project...

import pygame

pygame.init()

#Screen Size
screen_size = 1024, 576
screen_width = 1024
screen_height = 576

#Display Window
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption('The Adventures of Fresco the Explorer')

#Clock
clock = pygame.time.Clock()

#Colors
black = (0,0,0)
white = (255,255,255)

#Game Start
gameStart = False

#Forest Background
forest_bg = pygame.image.load('forest.png')

#Player Assets and Variables
fresco = pygame.image.load('fresco v2.png').convert()
fresco = pygame.transform.scale(fresco,(32,136))

velocity = 6

move_left = False
move_right = False

#Grass
grass = pygame.image.load('grass.png')
grass = pygame.transform.scale(grass, (90, 90))


#Player Class
class Player(pygame.sprite.Sprite):

    def __init__(self, x, y):

        pygame.sprite.Sprite.__init__(self)

        self.x = 0
        self.y = 0
        self.image = fresco
        self.rect = self.image.get_rect()

    def handle_keys(self):

        key = pygame.key.get_pressed()
        velocity = 8

        #Move Right
        if key[pygame.K_d]:
            self.rect.x += velocity

        #Move Left
        elif key[pygame.K_a]:
            self.rect.x -= velocity
            pygame.transform.flip(self.image, True, False)

    def draw (self, surface):
        surface.blit(self.image, self.rect)

player = Player(0,0)


class Platform(pygame.sprite.Sprite):

    def __init__(self, x, y):
        super().__init__()

        self.image = grass
        self.rect = self.image.get_rect()


class Level(object):
    """ 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.player = player

        # Background image
        self.background = None

    # Update everything on this level
    def update(self):
        """ Update everything in this level."""
        self.platform_list.update()

        #self.enemy_list.update() <--- NOTE: Use this late :3

    def draw(self, screen):
        """ Draw everything on this level. """

        # Draw all the sprite lists that we have
        self.platform_list.draw(screen)
        #self.enemy_list.draw(screen) <--- Use it later :3


class Level_01(Level):

    def __init__(self, player):

        self.background = forest_bg

        Level.__init__(self, player)

        platforms = []

        x = y = 0
        level = ['            ',
                 'P           ',
                 '            ',
                 '  P         ',
                 '            ',
                 'PPPPPPPPPPPP',]

        # build the level
        for row in level:
            for col in row:
                if col == 'P':
                    P = Platform(x, y)
                    platforms.append(P)
                x += 90
            y += 90
            x = 0

level_list = []
level_list.append(Level_01(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

#Game Loop
while not gameStart:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameStart = True


    #Background
    screen.blit(forest_bg,(0,0))

    #Player Updates
    player.handle_keys()
    player.draw(screen)

    #Level Updates
    current_level.update()
    current_level.draw(screen)
    active_sprite_list.draw(screen)
    # Updates Screen
    pygame.display.update()

    #FPS
    clock.tick(60)

pygame.quit()

回答1:

Your problem is because you create Platform() with argumenst x,y

 P = Platform(x, y)

but you do nothing with this information.

You have to remeber this values in __init__

self.rect.x = x
self.rect.y = y

or shorter

self.rect = self.image.get_rect(x=x, y=y)

And you have the same problem in class Player()


BTW: better use self.rect.x, self.rect.y instead of self.x, self.y in all classes because you can use it to check collisions - player.rect.colliderect(some_element.rect) or player.rect.collidepoint(mouse_pos)

Even pygame.sprite.Group() expects that all elements have position and size in self.rect because it use self.image and self.rect to draw them.



标签: python pygame