2017-12-11 1 views
1

私はこれを修正するためにすべてを試しましたが、見つけられないようです。私はそれがおそらく簡単な修正だと知っていますが、これが起こっていることを見つけることができません。私はそれはおそらく簡単だ知っpygameで画像を渡そうとすると、 'pygame.Surface'に属性がありません。

File "C:\Python32\Project3\proj3pt2.py", line 220, in handle_event 
self.image = self.image_down.get_rect() 
AttributeError: 'pygame.Surface' object has no attribute 'image_down' 

:これは私のコードの最初の部分である:

import pygame, sys, time 
from pygame.locals import * 
pygame.init() 
WINDOWWIDTH = 900 
WINDOWHEIGHT = 400 
MOVERATE = 5 
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT)) 
TEXTCOLOR = (255, 255, 255) 
BACKGROUNDCOLOR = (0, 0, 0) 
FPS = 40 
clock = pygame.time.Clock() 
x = 200 
y = 150 
class player(pygame.sprite.Sprite): 
def __init__(self, x, y): 
    super(player, self).__init__() 

    temp_image = pygame.image.load("stand_down.png").convert_alpha() 
    self.image_down = pygame.transform.scale(temp_image, (100, 200)) 

    temp_image = pygame.image.load("standleft.png").convert_alpha() 
    self.image_left = pygame.transform.scale(temp_image, (100, 200)) 

    temp_image = pygame.image.load("standright.png").convert_alpha() 
    self.image_right = pygame.transform.scale(temp_image, (100, 200)) 

    self.image = self.image_down 

    # keep position and size in pygame.Rect() 
    # to use it in collision checking 
    self.rect = self.image.get_rect(x=x, y=y) 
def draw(self, x, y): 
    screen.blit(self.image, self.rect)    
def handle_event(self):#, event) 
    self.image = self.image_down.get_rect() 
    self.image = pygame.Surface((x, y)) 
    key = pygame.key.get_pressed() 
    if key[K_LEFT]: 
     self.rect.x -= 50 
     self.image = self.image_left 
    if key[K_RIGHT]: 
     self.rect.x += 50 
     self.image = self.image_right 
class room1(): 
#bedroom 
    def __init__(self): 
     self.x, self.y = 16, WINDOWHEIGHT/2 
     self.speed = 3 
    def draw(self): 
     background = pygame.image.load("bedroom.jpg").convert() 
     background = pygame.transform.scale(background, (WINDOWWIDTH, WINDOWHEIGHT)) 
     screen.blit(background, (0, 0)) 

をそして、これは私の主な機能である:私は同じエラーを取得しておく

def main(): 
    while True: 
      for event in pygame.event.get(): 
       player.handle_event.get(event) 
      player.handle_event(screen) 
    room1.draw(screen) 
    player.draw(screen, x, y) 
    pygame.display.update() 
    pygame.display.flip() 
    clock.tick(FPS) 
main() 

修正することができますが、私はそれを探すべき場所と、どうしたらどうしたのか分かりません。誰かがそれを説明することができれば、それは非常に高く評価されるだろう!

+0

あなたはどこで選手を作りますか? 'player = player.transform.scale()'やそれに類することをやっていないのですか?これは 'Sprite'を' Surface'に置き換えてしまい、問題があります。 BTW:エラーメッセージ 'self.image = self.image_down.get_rect()'の中で、 'Surface'を' Rect'に置き換えて、同様の誤りを犯します。 – furas

答えて

0

インスタンスがあり、そのメソッドの1つを呼び出すと、インスタンスは自動的に最初の引数のselfとして渡されます。したがって、クラスMyClassとインスタンスmy_instanceがあり、そのhandle_eventメソッドを呼び出す場合は、MyClass.handle_event(my_instance)を呼び出すのと同じです。あなたのプログラムで

あなたがplayerクラスのインスタンスを作成することはありませんので、あなたがクラスに直接self引数としてscreenを渡している(screenは実際pygame.Surfaceです)。つまり、handle_eventメソッドのselfは実際にscreenのサーフェスを参照し、サーフェスにはimage_downという属性がないため、self.image_down.get_rect()に到達するとエラーが発生します。 (あなたはメソッドに複数のパラメータを追加しない限り)

あなたは playerクラスのインスタンス(とも呼ばれるオブジェクト)を作成する必要があり、この問題を解決するにして handle_eventに引数を渡してはいけません。

player_instance = player(x_position, y_position) 

その後しばらくしてイベントループの内部でインスタンスを使用して:あなたはまた、直接クラスを使用するのではなくroom1クラスのインスタンスを作成する必要が

while True: 
    player_instance.handle_event() 

。ここで

は、他の問題に関するいくつかのコメントとの完全な例です:

import pygame 

pygame.init() 
WINDOWWIDTH = 900 
WINDOWHEIGHT = 400 
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT)) 
FPS = 40 
clock = pygame.time.Clock() 
# Load images once globally and reuse them in the program. 
background = pygame.image.load("bedroom.jpg").convert() 
background = pygame.transform.scale(background, (WINDOWWIDTH, WINDOWHEIGHT)) 
temp_image = pygame.image.load("stand_down.png").convert_alpha() 
image_down = pygame.transform.scale(temp_image, (100, 200)) 
temp_image = pygame.image.load("standleft.png").convert_alpha() 
image_left = pygame.transform.scale(temp_image, (100, 200)) 
temp_image = pygame.image.load("standright.png").convert_alpha() 
image_right = pygame.transform.scale(temp_image, (100, 200)) 


class player(pygame.sprite.Sprite): 
    def __init__(self, x, y): 
     super(player, self).__init__() 

     self.image_down = image_down 
     self.image_left = image_left 
     self.image_right = image_right 

     self.image = self.image_down 

     # keep position and size in pygame.Rect() 
     # to use it in collision checking 
     self.rect = self.image.get_rect(x=x, y=y) 

    # You don't have to pass x and y, since you already 
    # use the `self.rect` as the blit position. 
    def draw(self, screen): 
     screen.blit(self.image, self.rect) 

    def handle_event(self): 
     # These two lines don't make sense. 
     #self.image = self.image_down.get_rect() 
     #self.image = pygame.Surface((x, y)) 
     # I guess you want to switch back to image_down. 
     self.image = self.image_down 

     key = pygame.key.get_pressed() 
     if key[pygame.K_LEFT]: 
      self.rect.x -= 5 
      self.image = self.image_left 
     if key[pygame.K_RIGHT]: 
      self.rect.x += 5 
      self.image = self.image_right 

class room1(): 

    def __init__(self): 
     self.x, self.y = 16, WINDOWHEIGHT/2 
     # Reference to the background image. 
     self.background = background 

    def draw(self, screen): # Pass the screen. 
     screen.blit(self.background, (0, 0)) 


def main(): 
    # Create player and room instances. 
    player_instance = player(200, 150) 
    room1_instance = room1() 

    while True: 
     for event in pygame.event.get(): 
      # Users can press the "X" button to quit. 
      if event.type == pygame.QUIT: 
       return 

     player_instance.handle_event() 
     room1_instance.draw(screen) 
     player_instance.draw(screen) 
     # You don't need both update and flip. 
     # pygame.display.update() 
     pygame.display.flip() 
     clock.tick(FPS) 

main() 
pygame.quit() 

サイドノート:PEP 8は、クラスのための大文字の名前を推奨していますので、代わりにplayerPlayer。次にインスタンスplayerを呼び出すことができます。あなたがSurfaceSpriteを交換し、後であなたが問題を抱えている -

+0

「自己」の仕組みがはっきりしない場合は、この[回答](https://stackoverflow.com/a/6990217/6220679)をご覧ください。 – skrx

0

私はあなたがこの

player = player.transform.scale(player.image) 

playerSpriteしかしscale戻りSurfaceあるようにどこかで何かを疑います。

(ところで:私は数日前に、いくつかの質問に同じ問題を見て)

あなたがイメージを再スケールする必要がある場合は、すでにいくつかの画像と同じように、その後__init__でそれを行います。あなたがところでscale()


を使用する必要はありませんので、あなたはどんなイメージエディタを使用して、正しいサイズの画像を作成する必要があり、実際のゲームでは

handle_eventに、あなたはあなたはRect

self.image = self.image_down.get_rect() 
self.image = pygame.Surface((x, y)) 

割り当ててくださいSurfaceself.image)に変更し、後で新しいSurfaceを空にしておきます。サイズはx, yです。 Surfaceはpositonを保持せず、width, heightのみを使用します。

あなたはpositionaを保つためにself.rectを持っていて、すでに

self.rect.x -= 50 

ところで
self.rect.x += 50 

でそれを変更します。

class Player(...) 

class Room1(...) 
コードを読みやすくするためのクラスの UpperCaseNamesを使用

イベントStackoverflowはこのルールを認識しており、クラスのライトブルー色を使用してコードを読みやすくしています。

より:PEP 8 -- Style Guide for Python Codeところで


:あなたが読んで、何度も何度も画像を再スケールroom1.draw()に - それはプログラムを遅くすることができます。もう一度同じ質問をしてください。room.__init__

関連する問題