Python Pygame属性错误

Python Pygame属性错误,python,attributes,pygame,Python,Attributes,Pygame,我有一个pygame程序,其中main.py导入player.py模块,如下所示: import pygame import random from walls import Wall class Player(pygame.sprite.Sprite): #-------------------Define Variables here speed=0 #------------------Initialise Constructor def __init_

我有一个pygame程序,其中main.py导入player.py模块,如下所示:

import pygame
import random
from walls import Wall

class Player(pygame.sprite.Sprite): 
    #-------------------Define Variables here
    speed=0
    #------------------Initialise Constructor
    def __init__(self): 
        pygame.sprite.Sprite.__init__(self)
        self.image=pygame.image.load("player.png") 
        self.rect = self.image.get_rect() 

        #--------------Fetch the rectangle object that has the dimensions of the image
        self.rect =self.image.get_rect()
        #---------------Define movement
    def moveRight(self,pixels):
        self.rect.x+=pixels
    def moveLeft(self,pixels):
        self.rect.x-=pixels
    def moveUp(self,pixels):
        self.rect.y-=pixels
    def moveDown(self,pixels):
        self.rect.y+=pixels

    # Make our top-left corner the passed-in location.
    def settopleft():
        self.rect = self.image.get_rect()
        self.rect.y = y
        self.rect.x = x

        # Set speed vector
        self.change_x = 0
        self.change_y = 0
        self.walls = None

    def changespeed(self, x, y):
        """ Change the speed of the player. """
        self.change_x += x
        self.change_y += y


    def update(self):
        # Did this update cause us to hit a wall?
        block_hit_list = pygame.sprite.spritecollide(self, self.walls, 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
            else:
                # 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.walls, 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
            else:
                self.rect.top = block.rect.bottom
#Create walls that the player can run into
import pygame
import random
from player import Player
from collectable import Collectable
from walls import Wall

pygame.init()
BLACK=(0,0,0) 
WHITE=(255,255,255) 
RED=(255,0,0) 
GREEN =(0,255,0)

BLUE=(0,0,255) 
GOLD=(255,215,0)
WIDTH=500
HEIGHT=500
size= (WIDTH,HEIGHT) 
screen=pygame.display.set_mode(size)
pygame.display.set_caption("The Life Game")


done = False
clock=pygame.time.Clock()
wall_list=pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
enemy_list  = pygame.sprite.Group() 
player=Player()
player.walls=wall_list

all_sprites.add(player)


for i in range(random.randrange(100,200)):
        whiteStar = Collectable(WHITE, 3, 3, "White Star", "Rect")
        whiteStar.rect.x = random.randrange(size[0])
        whiteStar.rect.y = random.randrange(size[1])
        all_sprites.add(whiteStar)

for i in range(50):

    enemy = Collectable(RED,6, 6,"Enemy","Ellipse")
    enemy.rect.x = random.randrange(300)
    enemy.rect.y = random.randrange(300)
    enemy_list.add(enemy)
    all_sprites.add(enemy)

coin1 = Collectable(GOLD,50,50,"Coin","Ellipse") 
coin1.rect.x=440
coin1.rect.y=0
all_sprites.add(coin1)

coin2 = Collectable(GOLD,50,50,"Coin","Ellipse")
coin2.rect.x=0
coin2.rect.y=440
all_sprites.add(coin2)

enemy = Collectable(RED,100,100,"Enemy","Ellipse")
enemy.rect.x=70
enemy.rect.y=230
all_sprites.add(enemy)

#Make the walls (x_pos,y_pos, width, height,colour)



wall=Wall(0,0,10,600,GREEN)
wall_list.add(wall)
all_sprites.add(wall_list)

wall = Wall(50, 300, 400, 10,RED)
wall_list.add(wall)
all_sprites.add(wall_list)

wall = Wall(10, 200, 100, 10,BLUE)
wall_list.add(wall)
all_sprites.add(wall_list)


score=0
health=100

#- - - - - - - - - - - - - -Main Program Loop - - - - - - - - - - - - - - - -
def main():
        done=False
        score=0
        health=100
        while not done:


                  #- - - - - - Main event loop (this is where code for handling keyboard and mouse clicks will go)
        #Loop until the user clicks the 'x' button (to close program)
                  for event in pygame.event.get(): #User does something
                            if event.type == pygame.QUIT: #If the user clicked close
                                      done = True  #set the done flag to 'true' to exit the loop

                  keys = pygame.key.get_pressed() #checking pressed keys
                  if keys[pygame.K_LEFT]:
                     player.moveLeft(5)
                  if keys[pygame.K_RIGHT]:
                     player.moveRight(5)
                  if keys[pygame.K_UP]:
                     player.moveUp(5)
                  if keys[pygame.K_DOWN]:
                     player.moveDown(5)                


                 #>>----------DRAW SECTION -----------------------------------
                  #Clear the screen to BLACK. Any drawing commands should be put BELOW this or they will be reased with this command
                  screen.fill(BLACK)



                  #Select the font to be used (size, bold, italics, etc)
                  font_score = pygame.font.SysFont('Calibri',20,True,False)
                  font_health = pygame.font.SysFont('Calibri',20,True,False)
                #Printing a variable (score or health) to the screen involves converting the score (if integer) to a string first.score_label = font_score.render("Score: " + str(score),True,BLACK)
                  health_label = font_health.render("Health: "+str(health),True,WHITE)
                  score_label = font_score.render("Score: " + str(score),True, WHITE)
                #Now we can use this line of code to put the image of the text on the screen at a given position
                  screen.blit(score_label,[100,480])
                  screen.blit(health_label,[190,480])


                   #>>---------UPDATE SECTION / Put the logic of your game here (i.e. how objects move, when to fire them, etc)


                  all_sprites.update()

                  if coin1.collision_with(player):
                         score=score+1
                         coin1.kill()
                         coin1.rect.x=-20
                         coin1.rect.y=-330

                  if coin2.collision_with(player):
                         score=score+1
                         coin2.kill()
                         coin2.rect.x=-20
                         coin2.rect.y=-330

                  if enemy.collision_with(player):
                        health=health-25
                        enemy.kill()
                        enemy.rect.x=-20
                        enemy.rect.y=-330

                  enemy.update()





         #-------------PRINTING VARIABLES LIKE SCORE TO SCREEN
                  #Any drawing/graphics code should go here
                  all_sprites.draw(screen)

                  #Update the screen to show whatever you have drawn
                  pygame.display.flip()

                  #Set the frames per second (e.g. 30, 60 etc)
                  clock.tick(120)

main()
main.py程序如下所示:

import pygame
import random
from walls import Wall

class Player(pygame.sprite.Sprite): 
    #-------------------Define Variables here
    speed=0
    #------------------Initialise Constructor
    def __init__(self): 
        pygame.sprite.Sprite.__init__(self)
        self.image=pygame.image.load("player.png") 
        self.rect = self.image.get_rect() 

        #--------------Fetch the rectangle object that has the dimensions of the image
        self.rect =self.image.get_rect()
        #---------------Define movement
    def moveRight(self,pixels):
        self.rect.x+=pixels
    def moveLeft(self,pixels):
        self.rect.x-=pixels
    def moveUp(self,pixels):
        self.rect.y-=pixels
    def moveDown(self,pixels):
        self.rect.y+=pixels

    # Make our top-left corner the passed-in location.
    def settopleft():
        self.rect = self.image.get_rect()
        self.rect.y = y
        self.rect.x = x

        # Set speed vector
        self.change_x = 0
        self.change_y = 0
        self.walls = None

    def changespeed(self, x, y):
        """ Change the speed of the player. """
        self.change_x += x
        self.change_y += y


    def update(self):
        # Did this update cause us to hit a wall?
        block_hit_list = pygame.sprite.spritecollide(self, self.walls, 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
            else:
                # 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.walls, 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
            else:
                self.rect.top = block.rect.bottom
#Create walls that the player can run into
import pygame
import random
from player import Player
from collectable import Collectable
from walls import Wall

pygame.init()
BLACK=(0,0,0) 
WHITE=(255,255,255) 
RED=(255,0,0) 
GREEN =(0,255,0)

BLUE=(0,0,255) 
GOLD=(255,215,0)
WIDTH=500
HEIGHT=500
size= (WIDTH,HEIGHT) 
screen=pygame.display.set_mode(size)
pygame.display.set_caption("The Life Game")


done = False
clock=pygame.time.Clock()
wall_list=pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
enemy_list  = pygame.sprite.Group() 
player=Player()
player.walls=wall_list

all_sprites.add(player)


for i in range(random.randrange(100,200)):
        whiteStar = Collectable(WHITE, 3, 3, "White Star", "Rect")
        whiteStar.rect.x = random.randrange(size[0])
        whiteStar.rect.y = random.randrange(size[1])
        all_sprites.add(whiteStar)

for i in range(50):

    enemy = Collectable(RED,6, 6,"Enemy","Ellipse")
    enemy.rect.x = random.randrange(300)
    enemy.rect.y = random.randrange(300)
    enemy_list.add(enemy)
    all_sprites.add(enemy)

coin1 = Collectable(GOLD,50,50,"Coin","Ellipse") 
coin1.rect.x=440
coin1.rect.y=0
all_sprites.add(coin1)

coin2 = Collectable(GOLD,50,50,"Coin","Ellipse")
coin2.rect.x=0
coin2.rect.y=440
all_sprites.add(coin2)

enemy = Collectable(RED,100,100,"Enemy","Ellipse")
enemy.rect.x=70
enemy.rect.y=230
all_sprites.add(enemy)

#Make the walls (x_pos,y_pos, width, height,colour)



wall=Wall(0,0,10,600,GREEN)
wall_list.add(wall)
all_sprites.add(wall_list)

wall = Wall(50, 300, 400, 10,RED)
wall_list.add(wall)
all_sprites.add(wall_list)

wall = Wall(10, 200, 100, 10,BLUE)
wall_list.add(wall)
all_sprites.add(wall_list)


score=0
health=100

#- - - - - - - - - - - - - -Main Program Loop - - - - - - - - - - - - - - - -
def main():
        done=False
        score=0
        health=100
        while not done:


                  #- - - - - - Main event loop (this is where code for handling keyboard and mouse clicks will go)
        #Loop until the user clicks the 'x' button (to close program)
                  for event in pygame.event.get(): #User does something
                            if event.type == pygame.QUIT: #If the user clicked close
                                      done = True  #set the done flag to 'true' to exit the loop

                  keys = pygame.key.get_pressed() #checking pressed keys
                  if keys[pygame.K_LEFT]:
                     player.moveLeft(5)
                  if keys[pygame.K_RIGHT]:
                     player.moveRight(5)
                  if keys[pygame.K_UP]:
                     player.moveUp(5)
                  if keys[pygame.K_DOWN]:
                     player.moveDown(5)                


                 #>>----------DRAW SECTION -----------------------------------
                  #Clear the screen to BLACK. Any drawing commands should be put BELOW this or they will be reased with this command
                  screen.fill(BLACK)



                  #Select the font to be used (size, bold, italics, etc)
                  font_score = pygame.font.SysFont('Calibri',20,True,False)
                  font_health = pygame.font.SysFont('Calibri',20,True,False)
                #Printing a variable (score or health) to the screen involves converting the score (if integer) to a string first.score_label = font_score.render("Score: " + str(score),True,BLACK)
                  health_label = font_health.render("Health: "+str(health),True,WHITE)
                  score_label = font_score.render("Score: " + str(score),True, WHITE)
                #Now we can use this line of code to put the image of the text on the screen at a given position
                  screen.blit(score_label,[100,480])
                  screen.blit(health_label,[190,480])


                   #>>---------UPDATE SECTION / Put the logic of your game here (i.e. how objects move, when to fire them, etc)


                  all_sprites.update()

                  if coin1.collision_with(player):
                         score=score+1
                         coin1.kill()
                         coin1.rect.x=-20
                         coin1.rect.y=-330

                  if coin2.collision_with(player):
                         score=score+1
                         coin2.kill()
                         coin2.rect.x=-20
                         coin2.rect.y=-330

                  if enemy.collision_with(player):
                        health=health-25
                        enemy.kill()
                        enemy.rect.x=-20
                        enemy.rect.y=-330

                  enemy.update()





         #-------------PRINTING VARIABLES LIKE SCORE TO SCREEN
                  #Any drawing/graphics code should go here
                  all_sprites.draw(screen)

                  #Update the screen to show whatever you have drawn
                  pygame.display.flip()

                  #Set the frames per second (e.g. 30, 60 etc)
                  clock.tick(120)

main()
运行程序时,出现以下错误:

Traceback (most recent call last):
  File "N:\pygame\working_on_30\main.py", line 164, in <module>
    main()
  File "N:\pygame\working_on_30\main.py", line 128, in main
    all_sprites.update()
  File "C:\Python 3.6\lib\site-packages\pygame\sprite.py", line 462, in update
    s.update(*args)
  File "N:\pygame\working_on_30\player.py", line 49, in update
    if self.change_x > 0:
AttributeError: 'Player' object has no attribute 'change_x'
回溯(最近一次呼叫最后一次):
文件“N:\pygame\working\u on_30\main.py”,第164行,在
main()
文件“N:\pygame\working\u on\u 30\main.py”,第128行,main
所有精灵更新()
更新中第462行的文件“C:\Python 3.6\lib\site packages\pygame\sprite.py”
s、 更新(*args)
更新中第49行的文件“N:\pygame\working\u on\u 30\player.py”
如果self.change_x>0:
AttributeError:“玩家”对象没有属性“更改”
我尝试过改变各种事情,但都没能成功。有人可以吗 a) 解释错误
b) 提供解决方案修复程序;dr-将
self.change\u x=0
self.change\u y=0
添加到玩家类中的
\uuuu init\uuuu

你的玩家类有一个属性
player.change_x
,你可以在不同的点上指定它,但不能在你的init中。如果在调用(例如)
player.settopleft()
之前调用
player.update()
,那么当
update()
方法执行时,行
If self.change\u x>0:
会出错,因为尚未定义
self.change\u x

如果将
self.change\u x=0
添加到init,则确保始终为
Player
的实例设置变量


通过请求澄清:

您可以在player.py中定义类player。类方法之一是
\uuuu init\uuuu
。当您创建一个类为
Player
(即当您的代码执行main.py中类似
Player=Player()
的操作时,这将调用
\uuuu init\uuuu
方法,您可以使用该方法确保所有对象都正确初始化

您的错误是由
self.change\u x
未定义引起的,因此您应该在类的
\uuuu init\uuuu
中定义它,以确保此错误不会发生。我建议:

class Player(pygame.sprite.Sprite): 
    #-------------------Define Variables here
    speed=0
    #------------------Initialise Constructor
    def __init__(self): 
        pygame.sprite.Sprite.__init__(self)
        self.image=pygame.image.load("player.png") 
        self.rect = self.image.get_rect()

        # - CHANGE HERE! - sets initial speed to 0
        self.change_x = 0
        self.change_y = 0
        # - END OF CHANGE 

        #--------------Fetch the rectangle object that has the dimensions of the image
        self.rect =self.image.get_rect()
        #---------------Define movement

两个问题。1.什么是“tl;dr”太长了,读不下去了。2,你能回答你的答案吗?你能在SoFix.x的0中加入一个例子吗?我对这个结构不太自信。我可以给这个问题回答问题,回答状态!非常感谢你的建议,在这里,“太长了,没有读过”。我会编辑我的帖子。你会因为我没有选择答案而否决我吗?!我现在正在尝试…@MissComputing不,我还没有对你的问题投票。这还不错,所以我不会否决它,但我无法想象这会帮助下一个“Pygame属性错误”的人否决它,为什么?当然y他们应该控制随机的否决票,这是完全不公平的。非常感谢你的回答!