Спрайт игрока Pygame не появляется - PullRequest
0 голосов
/ 26 апреля 2018

Я работал над этим проектом для школьного компьютерного класса и не могу заставить спрайт игрока появляться, кто-нибудь может помочь? Когда я запускаю основной игровой цикл, все отображается правильно, кроме спрайта игрока. Предполагается, что он перемещается по экрану в результате ввода стрелок и зависит от силы тяжести. Код также работает, когда я удаляю изображение и использую только класс объекта и прямоугольник.

import os
import random
import pygame

#start pygame
pygame.init()

#set up display
pygame.display.set_caption("Jump to escape!")
width = 720
height = 540
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
img = pygame.image.load('img.jpg')


#PLayer class
class Player(pygame.sprite.Sprite):
    #My sprite is going to be a player

    def __init__(self):
        super().__init__()

        self.image = pygame.image.load("player.png").convert_alpha()
        self.image.set_colorkey([255,255,255])

        self.rect = self.image.get_rect()
        #We have added a class variable called self.currentWalls.
        #This is blank initially but as soon as the game loop is called it will store the currently displayed walls.
        #It's effectively a copy of the walls variable within the game loop itself.
        self.currentWalls =[]

    def move(self,dx,dy, walls):

        #Every time the 'move' function is called, we update self.currentWalls with the walls passed to the function.
        self.currentWalls = walls

        if dx!=0:
            self.move_single_axis(dx,0)
        if dy!=0:
            self.move_single_axis(0,dy)

    def move_single_axis(self, dx, dy):

        self.rect.x += dx
        self.rect.y += dy

        #This is where we actually use self.currentWalls.
        #It is used for collision detection.
        #The code remains pretty much the same, however it is now referencing self.currentWalls instead of just walls.
        for wall in self.currentWalls:
            if self.rect.colliderect(wall.rect):
                if dx > 0:
                    self.rect.right = wall.rect.left
                if dx < 0:
                    self.rect.left = wall.rect.right
                if dy > 0:
                    self.rect.bottom = wall.rect.top
                if dy < 0:
                    self.rect.top = wall.rect.bottom




#a new class for walls / blocks to jump onto
class Wall(object):

    #Whenever this class is instantiated, an item with a property 'item.rect' is created.
    #We append copies of this class to the walls array later in the program.
    def __init__(self, wx, wy):
        self.rect = pygame.Rect(wx,wy,30,30)

    def reset_wall(self):
        self.active = False

#Start of the menu implementation.

#Function that, when called will quit pygame.
def quitgame():
    pygame.quit()
    quit()

#Function that creates a button to the required parameters.
def button(msg,x,y,w,h,ic,ac,action=None):
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()

    if x+w > mouse[0] > x and y+h > mouse[1] > y:
        pygame.draw.rect(screen, ac,(x,y,w,h))
        if click[0] == 1 and action != None:
            action()
    else:
        pygame.draw.rect(screen, ic,(x,y,w,h))
    smallText = pygame.font.SysFont("arialBold",20)
    textSurf, textRect = text_objects(msg, smallText)
    textRect.center = ( (x+(w/2)), (y+(h/2)) )
    screen.blit(textSurf, textRect)

#Function that creates a text object to the specified parameters.
def text_objects(text, font):
    textSurface = font.render(text, True, (0,0,0))
    return textSurface, textSurface.get_rect()




#Function that, when called, makes a menu appear.
#It makes use of the above few functions.
def game_intro():

    intro = True

    while intro:
        for event in pygame.event.get():
            #print(event)
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        screen.fill((255,255,255))
        screen.blit(img,(0,0))
        largeText = pygame.font.SysFont("Segoe UI Black",115)
        TextSurf, TextRect = text_objects("Pixel Dash", largeText)
        TextRect.center = ((width/2),(height/2))
        screen.blit(TextSurf, TextRect)


        button("GO!",150,450,100,50,(0,150,0),(0,255,0),game_loop)
        button("Quit",450,450,100,50,(150,0,0),(255,0,0),False)

        pygame.display.update()
        clock.tick(60)





#Function that, when called, will run the main game.
#It uses the other functions that the menu system doesn't.
def game_loop():

    #Create an empty list called walls.
    #At any point during the game this list will store the walls that are currently being displayed.
    walls = []

    player = Player() #create a player object using the class above
    colour = (0,128,255)
    wall_colour = (255,255,255)

    #In the level, W means wall & E means exit
    level = [
    "WWWWWWWWWWWWWWWWWWWWWWWW",
    "W                      W",
    "W        WWW           W",
    "W                      W",
    "W                   E  W",
    "W        W     WWWWWW  W",
    "W       WW             W",
    "W      WW              W",
    "W     WWWWW            W",
    "W                      W",
    "W        WW         WWWW",
    "W                      W",
    "W                      W",
    "W         WWWWWW       W",
    "W      WWW             W",
    "W                      W",
    "W                      W",
    "WWWWWWWWWWWWWWWWWWWWWWWW",
    ]

    levels = [[
    "WWWWWWWWWWWWWWWWWWWWWWWW",
    "W                      W",
    "W                      W",
    "W                      W",
    "W                   E  W",
    "W              WWWWWW  W",
    "W                      W",
    "W                      W",
    "W     WWWWW            W",
    "W                      W",
    "W                   WWWW",
    "W                      W",
    "W                      W",
    "W         WWWWWW       W",
    "W                      W",
    "W                      W",
    "W                      W",
    "WWWWWWWWWWWWWWWWWWWWWWWW",
    ],[
    "WWWWWWWWWWWWWWWWWWWWWWWW",
    "W                      W",
    "W E                    W",
    "W WWWWW                W",
    "W        WWW           W",
    "W                      W",
    "W                      W",
    "W            WWWWW     W",
    "W                      W",
    "W                      W",
    "W                      W",
    "W                      W",
    "W                      W",
    "W         WWWWWW       W",
    "W                      W",
    "W                      W",
    "W                      W",
    "WWWWWWWWWWWWWWWWWWWWWWWW",
    ],[
    "WWWWWWWWWWWWWWWWWWWWWWWW",
    "W                      W",
    "W                W     W",
    "W           WWW  W    WW",
    "W                W E WWW",
    "W  WWWW                W",
    "W                      W",
    "W            WWWWW     W",
    "W                      W",
    "W                      W",
    "W    W                 W",
    "W                      W",
    "W                      W",
    "W            WWW       W",
    "W                      W",
    "W   W                  W",
    "W                      W",
    "WWWWWWWWWWWWWWWWWWWWWWWW",
    ]]


    x = y = 0
    for row in level:
        for col in row:
            if col == "W":
                #For each wall, create a new instance of the 'Wall' class and append it to the list 'walls'
                walls.append(Wall(x, y))
            if col == "E":
                end_rect = pygame.Rect(x,y,30,30)
            x += 30
        y += 30
        x=0

    #start the game play!
    running = True

    while running:
        clock.tick(60)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            if (event.type == pygame.KEYDOWN) and (event.key == pygame.K_SPACE):
                if colour == (0,128,255):
                    colour = (255,100,0)
                else:
                    colour = (0,128,255)


        #allow the player to move
        user_input = pygame.key.get_pressed()

        #Whenever we call the player.move function, we have added another parameter.
        #We pass the walls list in to the function so that it keeps the variable player.currentWalls up to date.
        if user_input[pygame.K_UP]:
            player.move(0,-5, walls)
        elif player.rect.y < (height -60):
            player.move(0,5, walls)

        if user_input[pygame.K_DOWN]:
            player.move(0,5, walls)

        if user_input[pygame.K_LEFT]:
            player.move(-5,0, walls)
            if player.rect.x < 0:
                player.rect.x= width -1

        if user_input[pygame.K_RIGHT]:
            player.move(5,0, walls)
            if player.rect.x > width:
                player.rect.x= -59


        if player.rect.colliderect(end_rect):
            #Clear the walls array.
            #Gets rid of all walls that are currently being drawn.
            del walls[:]

            level = random.choice(levels)
            wall_colour = (random.randint(0,255),random.randint(0,255),random.randint(0,255))
            x = y = 0
            for row in level:
                for col in row:
                    if col == "W":
                        #For each wall, create a new instance of the 'Wall' class and append it to the list 'walls'
                        walls.append(Wall(x, y))
                    if col == "E":
                        end_rect = pygame.Rect(x,y,30,30)
                    x += 30
                y += 30
                x=0


        #draw the screen
        screen.fill((0,0,0))
        for wall in walls:
            pygame.draw.rect(screen,wall_colour,wall.rect)
        pygame.draw.rect(screen,(255,0,0),end_rect)
        pygame.draw.rect(screen,colour,player.rect)
        pygame.display.flip()

game_intro()
game_loop()
pygame.quit()

1 Ответ

0 голосов
/ 26 апреля 2018

В методе __init__ вашего Player вы создаете прямоугольник, но не устанавливаете его координаты, поэтому он располагается в координатах по умолчанию (0, 0). Тогда ваш код обнаружения столкновений, кажется, выдвигает его выше уровня, и вы не можете ввести его снова.

Установите координаты прямоугольника в точку внутри вашего уровня, например ::10000

self.rect = self.image.get_rect(topleft=(400, 300))
# Or
self.rect.x = 400
self.rect.y = 300
# Or
self.rect.topleft = (400, 300)

Вы также можете передать положение методу __init__, а затем назначить его прямоугольнику или установить его при изменении уровня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...