Pygame 玩家精灵未出现 [英] Pygame player sprite not appearing

查看:38
本文介绍了Pygame 玩家精灵未出现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在为学校计算机课做这个项目,无法让玩家精灵出现,有人可以帮忙吗?当我运行主游戏循环时,除了玩家精灵之外,一切都正确显示.它应该由于箭头输入而在屏幕上移动并受重力影响.当我删除图像并仅使用对象类和矩形时,该代码也有效.

I've been working on this project for school computing class, and can't make the player sprite appear, can anybody help? When I run the main game loop, everything appears correctly besides the player sprite. It is supposed to move around the screen as a result of arrow inputs and be affected by gravity. The code also works when I remove the image and use just a object class and a rectangle.

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

推荐答案

Player__init__ 方法中,您创建了一个矩形但不设置其坐标,所以它位于默认坐标 (0, 0).然后您的碰撞检测代码似乎将其推到了水平之上,您无法再次输入它.

In the __init__ method of your Player you create a rect but don't set its coordinates, so it's positioned at the default coordinates (0, 0). Then your collision detection code seems to push it above the level and you can't enter it again.

将矩形的坐标设置为关卡内的一个点,例如:

Set the coordinates of the rect to a point inside your level, e.g.:

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__ 方法,然后将其分配给矩形,或者在级别更改时设置它.

You could also pass the position to the __init__ method and then assign it to the rect, or set it when the level gets changed.

这篇关于Pygame 玩家精灵未出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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