2016-04-27 7 views
0

こんにちは、これは私のフォーラムの最初の投稿です。私は通常、ブラウズして自分自身で問題を解決していますが、私の頭は壁にぶち壊してしまいます。Python(pygame)クラスのインポートスコープの問題

私は約6週間の私の名前の周りで遊んでプログラミングには非常に新しいです。 私はpython3.5でLinuxを使用しています。

すなわちトラブル私のメインモジュールのサイズを小さくしようとしているを持っ

は、私は別のモジュールに私のクラスを削除しようとしていると私はいくつかの部分で成功している:私はにプレイヤーのクラスを置くことができますlibフォルダに移動し、メインのプレーヤーをハッシュアウトして、うまく動いて、プレイヤーを洞窟やショップに移動するまで、この段階のゲームがクラッシュします。

これは私が多くの読書から得た範囲の問題であると理解していますが、私は他の人が同様の問題を抱えているのを見ることができます。

私はprint(globals())を使用して異なる場所にある問題を見つけようとしましたが、これは最初の呼び出しが原因であると仮定しています。プレイヤーはメインスクリプトの中にプレーヤークラスを持っていたときのように、グローバルとして定義されていません。ここ

#!/usr/bin/env pyhton 

import pygame 
from Lib.Colours import * 
import random 
import os 
#imports player class when its in different module 
#from Lib.Player import * 

# used for importing, when player class is in different module    
#from RPGv1_TryModule import * 


class Player (pygame.sprite.Sprite): 
    #player class blue print 
    def __init__(self): 

     super(Player, self).__init__() 
     self.image = pygame.image.load(os.path.join("Data/Images",'player1.png')).convert_alpha() 
     self.image.get_rect() 
     #gets players properites and stats 
     self.set_properites() 
     self.set_herostats() 
     #set variable for H and V speed 
     self.vertical_speed = 0 
     self.horizontal_speed = 0 
     #variables for area(map) and if in shop 
     self.area = 0 
     self.shop = 0 

    def set_herostats(self): 
     #players stats when first created 
     self.lvl = 1 
     self.hp = 100 
     self.maxhp = 100 
     self.att = [5, 10] 
     self.defence = 1 
     self.combatspeed = 1 
     self.exp = 0 
     self.maxexp = 100 

    def set_properites(self): 
     #gets size of player and sets center point 
     self.rect = self.image.get_rect() 
     self.origin_x = self.rect.centerx 
     self.origin_y = self.rect.centery 
     #sets movement speed 
     self.speed = 2 

    def set_position(self, x, y): 
     #tracks players position 
     self.rect.x = x - self.origin_x 
     self.rect.y = y - self.origin_y 

    def set_area(self, area): 
     #start positon set by area 
     self.area = area 
     self.set_position(area.player_start_x, area.player_start_y) 

    def update(self, collide = pygame.sprite.Group, interact = pygame.sprite.Group, event=None): 
     #player movement in x axis 
     self.rect.x += self.horizontal_speed 
     collision_list = pygame.sprite.spritecollide(self, collide, False) 
     # collision detaction and making blocks in passable in x axis 
     for collided_object in collision_list: 
      if (self.horizontal_speed > 0): 
       self.rect.right = collided_object.rect.left 

      elif (self.horizontal_speed < 0): 
       self.rect.left = collided_object.rect.right 
     #player movement in Y axis 
     self.rect.y += self.vertical_speed 
     collision_list = pygame.sprite.spritecollide(self, collide, False) 
     # collision detaction and making blocks in passable in Y axis 
     for collided_object in collision_list: 
      if (self.vertical_speed > 0): 
       self.vertical_speed = 0 
       self.rect.bottom = collided_object.rect.top 

      elif (self.vertical_speed < 0): 
       self.vertical_speed = 0 
       self.rect.top = collided_object.rect.bottom 
     #interactive block collision detection 
     interaction_list = pygame.sprite.spritecollide(self, interact, False) 
     # interactive block events 
     for interaction in interaction_list: 
      print(interaction.name) 
      self.vertical_speed = 0 
      self.horizontal_speed = 0 
      if interaction.name == 'cave1': 
       change_area(1) 
      if interaction.name == 'Town': 
       change_area() 
      if interaction.name == 'shops': 
       shopping() 

     # key commands such as movement keys 
     if not (event == None): 
      if (event.type == pygame.KEYDOWN): 

       if (event.key == pygame.K_UP): 
        self.vertical_speed += -self.speed 

       if (event.key == pygame.K_DOWN): 
        self.vertical_speed += self.speed 

       if (event.key == pygame.K_LEFT): 
        self.horizontal_speed += -self.speed 

       if (event.key == pygame.K_RIGHT): 
        self.horizontal_speed += self.speed 

       #key up sets speed back to 0 = player stop moving 
      if (event.type == pygame.KEYUP): 

       if (event.key == pygame.K_UP): 
        self.vertical_speed = 0 

       if (event.key == pygame.K_DOWN): 
        self.vertical_speed = 0 

       if (event.key == pygame.K_LEFT): 
        self.horizontal_speed = 0 

       if (event.key == pygame.K_RIGHT): 
        self.horizontal_speed = 0 
     # random battle logic (currently in construction) 
     #if current_area.areatype == 'Cave': 
      #0.1% chance to spawn mob while moving 
     # chance = random.randint(1,1000) 
      # if chance in range(1,2): 
      #  if self.horizontal_speed != 0 or self.vertical_speed != 0: 
      #  print('SpawnMob') 


class Block(pygame.sprite.Sprite): 
    #none passable objects blueprint 
    def __init__(self, x, y, width, height, colour = black): 

     super(Block, self).__init__() 
     self.image = pygame.Surface((width, height)) 

     self.image.fill (colour) 

     self.rect = self.image.get_rect() 

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

class Interactive_block(pygame.sprite.Sprite): 
    #interactive blocks blueprint(interactive event set in player class) 
    def __init__(self, name, x, y, image): 
     super(Interactive_block, self).__init__() 
     self.image = pygame.image.load(os.path.join('Data/Images', image)) 
     self.name = name 

     self.rect = self.image.get_rect() 

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


class Area (object): 

    def __init__(self, player_object): 
     #adding to sprite groups 
     self.block_list = pygame.sprite.Group() 
     self.interactiveblock_list = pygame.sprite.Group() 

     self.player_object = player_object 

     self.player_start = self.player_start_x, self.player_start_y = \ 
          0, 0 
     #mob spawn variable 
     self.areatype = None 
     #world shift start variable 
     self.world_shift_x = self.world_shift_y = 0 
     #camera settings 
     self.left_viewbox = display_width/2 
     self.right_viewbox = display_width/2 

     self.up_viewbox = display_height/2 
     self.down_viewbox = display_height/2 

    def shift_world(self, shift_x, shift_y): 
     #shifts blocks in area 
     self.world_shift_x += shift_x 
     self.world_shift_y += shift_y 

     for each_object in self.interactiveblock_list: 
       each_object.rect.x += shift_x 
       each_object.rect.y += shift_y 

     for each_object1 in self.block_list: 
       each_object1.rect.x += shift_x 
       each_object1.rect.y += shift_y 

    def run_viewbox(self): 
     #basic camera to follow player 
     if (self.player_object.rect.x <= self.left_viewbox): 
      view_difference = self.left_viewbox - self.player_object.rect.x 
      self.player_object.rect.x = self.left_viewbox 
      self.shift_world (view_difference, 0) 

     if (self.player_object.rect.x >= self.right_viewbox): 
      view_difference = self.right_viewbox - self.player_object.rect.x 
      self.player_object.rect.x = self.right_viewbox 
      self.shift_world (view_difference, 0) 

     if (self.player_object.rect.y <= self.up_viewbox): 
      view_difference = self.up_viewbox - self.player_object.rect.y 
      self.player_object.rect.y = self.up_viewbox 
      self.shift_world (0, view_difference) 

     if (self.player_object.rect.y >= self.down_viewbox): 
      view_difference = self.down_viewbox - self.player_object.rect.y 
      self.player_object.rect.y = self.down_viewbox 
      self.shift_world (0, view_difference) 

    def update(self): 
     #update function for areas 
     window.fill(self.backcolour) 

     self.block_list.update() 
     self.interactiveblock_list.update() 

    def draw(self, window): 
     #draw function for areas 
     self.block_list.draw(window) 
     self.interactiveblock_list.draw(window) 

class Main_town(Area): 
    #start area 
    def __init__(self, Player_object): 

     super(Main_town, self).__init__(Player_object) 

     self.backcolour = green 

     boarder_colour = water 

     self.player_start = self.player_start_x, self.player_start_y = \ 
          752, 711 
     # used for no mob spawn 
     self.areatype = 'Town' 
     #none passable objects 
     boarders = [ 
       [0, 2, 153, 997, boarder_colour ], 
       [12, 851, 1841, 148, boarder_colour ], 
       [1669, 0, 185, 988, boarder_colour ], 
       [0, 0, 1834, 119, boarder_colour ], 
       [194, 144, 1443, 33, wall ], 
       [1600, 177, 37, 633, wall ], 
       [196, 768, 1404, 42, wall ], 
       [196, 171, 39, 597, wall ], 
       [504, 408, 29, 362, wall ], 
       [669, 173, 32, 166, wall ], 
       [898, 167, 29, 169, wall ], 
       [1047, 414, 35, 358, wall ], 
       [1256, 172, 27, 194, wall ], 
       [1421, 568, 185, 30, wall ], 
       [1287, 611, 23, 157, wall ], 
       [1442, 175, 17, 189, wall ], 
       ] 

     for block in boarders: 
      block = Block(block[0], block[1], block[2], block[3], block[4]) 
      self.block_list.add(block) 

     #list of rough coords for objects, created with basic map editor 
     #shops coords (371, 688) 
     #shops coords (323, 248) 
     #shops coords (548, 249) 
     #shops coords (809, 260) 
     #caves coords (1364, 241) 
     #caves coords (1529, 241) 
     #caves coords (1503, 692) 
     #caves coords (1200, 683) 

     #interactive objects 
     interactive_block = [ 
       ['cave1',1114,236,'Cave.png'], 
       ['shops',240,175,'building.png'], 
       ] 

     for block in interactive_block: 
      block = Interactive_block(block[0], block[1], block[2], block[3]) 
      self.interactiveblock_list.add(block) 


class Cave1(Area): 
    # first cave map (created with basic map editor) 
    def __init__(self, Player_object): 

     super(Cave1, self).__init__(Player_object) 

     self.backcolour = grey 

     boarder_colour = black 

     self.player_start = self.player_start_x, self.player_start_y = \ 
          193, 795 
     # used for mob spawns 
     self.areatype = 'Cave' 
     # None passable objects 
     boarders = [ 
      [0, 1, 159, 998, boarder_colour ], 
      [148, 848, 1705, 151, boarder_colour ], 
      [1725, 0, 128, 849, boarder_colour ], 
      [61, 0, 1665, 81, boarder_colour ], 
      [256, 641, 45, 214, boarder_colour ], 
      [261, 77, 41, 197, boarder_colour ], 
      [257, 366, 51, 115, boarder_colour ], 
      [302, 421, 314, 33, boarder_colour ], 
      [285, 643, 291, 33, boarder_colour ], 
      [550, 672, 25, 58, boarder_colour ], 
      [428, 198, 40, 226, boarder_colour ], 
      [583, 75, 36, 346, boarder_colour ], 
      [610, 418, 268, 39, boarder_colour ], 
      [583, 442, 46, 129, boarder_colour ], 
      [560, 714, 285, 17, boarder_colour ], 
      [824, 567, 30, 151, boarder_colour ], 
      [832, 701, 20, 68, boarder_colour ], 
      [963, 291, 62, 566, boarder_colour ], 
      [720, 222, 303, 70, boarder_colour ], 
      [1011, 226, 274, 63, boarder_colour ], 
      [1522, 78, 30, 148, boarder_colour ], 
      [1551, 193, 53, 33, boarder_colour ], 
      [1598, 194, 35, 495, boarder_colour ], 
      [1350, 640, 247, 49, boarder_colour ], 
      [1148, 448, 64, 311, boarder_colour ], 
      [1388, 81, 36, 434, boarder_colour ],    
       ] 

     for block in boarders: 
      block = Block(block[0], block[1], block[2], block[3], block[4]) 
      self.block_list.add(block)    
     # Interactive objects 
     interactive_block = [ 
       ['Town',1668, 98,'Cave.png'], 
       ] 

     for block in interactive_block: 
      block = Interactive_block(block[0], block[1], block[2], block[3]) 
      self.interactiveblock_list.add(block) 

def change_area(area=0): 
    # used to change area's possible improvement here 
     global current_area 
     area_list = [] 
     area_list.append(Main_town(Player.player)) 
     area_list.append(Cave1(Player.player)) 
     current_area_number = area 
     current_area = area_list[ current_area_number ] 
     Player.player.set_area(current_area) 

# general text template 
def text(text, font): 
    textSurface = font.render(text, True, black) 
    return textSurface, textSurface.get_rect() 

# button template that uses mouse events 
def button(msg,x,y,w,h,ic,ac,action=None): 
    mouse = pygame.mouse.get_pos() 
    click = pygame.mouse.get_pressed() 
    #print(click) 
    if x+w > mouse[0] > x and y+h > mouse[1] > y: 
     pygame.draw.rect(window, ac,(x,y,w,h)) 
     if click[0] == 1 and action != None: 
      action() 
    else: 
     pygame.draw.rect(window, ic,(x,y,w,h)) 
    smallText = pygame.font.SysFont("comicsansms", 18) 
    textSurf, textRect = text(msg, smallText) 
    textRect.center = ((x+(w/2)), (y+(h/2))) 
    window.blit(textSurf, textRect) 

def shopping(): 
    # .shop used to break while loop 
    Player.player.shop = 0 
    shop = True 
    while (shop): 
     for event in pygame.event.get(): 
      if (event.type == pygame.QUIT) or \ 
      (event.type == pygame.KEYDOWN and \ 
      (event.key == pygame.K_ESCAPE)): 
       shop = False 
       pygame.quit() 
     if Player.player.shop == 1: 
      break 

     # shop interface     
     window.fill(white) 
     largeText = pygame.font.SysFont('arial' ,55) 
     TextSurf, TextRect = text("What would you like to do?", largeText) 
     TextRect.center = ((display_width/2),(display_height/1.5)) 
     window.blit(TextSurf, TextRect) 

     #shop buttons 
     button("Potion Store",display_width*0.16,display_height*0.85,display_width*0.13,display_height*0.09,green,bright_green,potionshop) 
     button("Return to Town",display_width*0.68,display_height*0.85,display_width*0.13,display_height*0.09,red,bright_red,end_shop) 

     clock.tick(15) 

     pygame.display.update() 

def potionshop(): 
    # .shop used to break while loop 
    Player.player.shop = 0 
    shop = True 
    while (shop): 
     for event in pygame.event.get(): 
      if (event.type == pygame.QUIT) or \ 
      (event.type == pygame.KEYDOWN and \ 
      (event.key == pygame.K_ESCAPE)): 
       shop = False 
       pygame.quit() 
     if Player.player.shop == 1: 
      break 

     # shop interface 
     window.fill(grey) 
     largeText = pygame.font.SysFont('arial' ,55) 
     TextSurf, TextRect = text("Welcome to the potion store", largeText) 
     TextRect.center = ((display_width/2),(display_height/1.5)) 
     window.blit(TextSurf, TextRect) 

     #shop buttons 
     button("Small potion",display_width*0.14,display_height*0.75,display_width*0.13,display_height*0.09,green,bright_green,None) 
     button("medium potion",display_width*0.28,display_height*0.75,display_width*0.13,display_height*0.09,green,bright_green,None) 
     button("large potion",display_width*0.42,display_height*0.75,display_width*0.13,display_height*0.09,green,bright_green,None) 
     button("massive potion",display_width*0.56,display_height*0.75,display_width*0.13,display_height*0.09,green,bright_green,None) 
     button("Return to Store",display_width*0.70,display_height*0.75,display_width*0.13,display_height*0.09,blue,bright_blue,go_shopping) 
     button("Return to Town",display_width*0.42,display_height*0.85,display_width*0.13,display_height*0.09,red,bright_red,end_shop) 

     clock.tick(15)     

     pygame.display.update() 

def go_shopping(): 
    # .shop used to break while loop 
    Player.player.shop = 1 
    shopping() 

def end_shop(): 
    # .shop used to break while loop 
    Player.player.shop = 1 
    change_area() 

if (__name__ == "__main__"): 
    pygame.init() 

    boarder = 20 
    display_size = display_width, display_height = 700, 350 
    window = pygame.display.set_mode(display_size) 

    pygame.display.set_caption ("Battle RPG ") 

    Player.player = Player() 
    Player.player.set_herostats() 
    active_object_list = pygame.sprite.Group() 
    active_object_list.add(Player.player) 

    change_area() 

    clock = pygame.time.Clock() 
    frames_per_second = 60 

    running = True 
    while (running): 
     for event in pygame.event.get(): 
      if (event.type == pygame.QUIT) or \ 
      (event.type == pygame.KEYDOWN and \ 
      (event.key == pygame.K_ESCAPE)): 
       running = False 


     # Update Functions 
     Player.player.update(current_area.block_list,current_area.interactiveblock_list, event) 
     event = None 
     current_area.update() 

     # Logic Testing 
     current_area.run_viewbox() 


     # Draw everything 
     current_area.draw(window) 

     active_object_list.draw(window) 

     # Delay Framerate 

     clock.tick(frames_per_second) 


     # Update the screen      

     pygame.display.update() 

    pygame.quit() 

任意の方法は、コード(申し訳ありません、その長い)で、私はそれはおそらく、私は私が通じつまずいた残りを、その後のチュートリアルから一部を得た状態であることを知っています。皆さんはほとんどすべてのGoogle検索を知らなくても私をたくさん助けてくれました。そして、私はstackoverflowの結果を期待しています。とにかく私の主な目標は:

  1. プレーヤクラスをメインスクリプトから除外し、それ自身のモジュールに、まだ領域を通過させることができます。

、その後 2.ゆっくり 3.私はcurrent_areaのために使用していますグローバル取り除く(それは同じソリューションがします希望に満ちた)残りのコードを削除します。

読んでいただきありがとうございました。私がこれを解読するまで、私は壁に突き当たり続けて、自分が見つけた解決策を投稿します。

答えて

0

Playerをplayer.pyというファイルに入れ、blocksとInteractiveBlockをblocks.pyというファイルに入れ、Area.pyにAreaのものを入れます。各クラスの最上部で、それが使用するクラスをインポートするので、Areaクラスでplayerが使用されている場合は、import playerのいずれかを実行できます。この場合は、the_player = payer.Player()またはfrom player import Playerと書く必要があります。その場合はthe_player = Player()と書くだけです。

残りをmain.pyというファイルに入れ、そこにあるすべてのもの、プレーヤー、領域、ブロックをインポートします。

他のクラスと同じように参照します。

Current_areaは必ずPlayerクラス変数である必要があります。

+0

Player変数になるCurrent_areaが不思議になりました。私はそれを見ました。私はまだプレーヤークラスを移動し、メインファイルとplayer.pyファイルにインポートを行った後も、インポートには問題があります。私はまだ洞窟や店に入るときにクラッシュする(私は場所を変更すると)私はNameErrorを得る:name 'player'は定義されていない。私は、プレイヤーがメインスクリプトのすべての関数とクラスを介してアクセスできるようにプレーヤーを定義する必要がある場所を理解していません。お返事ありがとうございました。 – JimmyMac

0

彼の投稿からmarienbadの助けを借りて、私はissuseが何であるかを考え出しました。 marienbadがポートクラスをインポートする方法について提案したように、私はすべてのクラスをそこからモジュールを削除しました。私は仕事のための清掃作業スペースを残しました。私はいくつかのことを試み、私のAreaクラスで私はプレーヤーのオブジェクトを渡していたので、私はchange_area関数で同じことをしようとしました、そして、変更されたコードは、他の誰もが彼の問題に苦しんでいるようになります。

interaction_list = pygame.sprite.spritecollide(self, interact, False) 
# interactive block events 
for interaction in interaction_list: 
    print(interaction.name) 
    self.vertical_speed = 0 
    self.horizontal_speed = 0 
    if interaction.name == 'cave1': 
     change_area(player, 1) 
    if interaction.name == 'Town': 
     change_area(player) 
    if interaction.name == 'shops': 
     shopping(player) 

これは私が今、プレイヤーを渡し、関数に

def shopping(player_object): 
    # .shop used to break while loop 
    player = player_object 
    clock = pygame.time.Clock() 
    player.shop = 0 
    shop = True 
    while (shop): 
     for event in pygame.event.get(): 
      if (event.type == pygame.QUIT) or \ 
      (event.type == pygame.KEYDOWN and \ 
      (event.key == pygame.K_ESCAPE)): 
       shop = False 
       pygame.quit() 
     if player.shop == 1: 
      break 

そして、これは、機能は、このようにそれが定義されて維持、プレイヤーのクラスをどのように受け取るかあるのですかです。今これは私が多分よりよい解決策を意図しているように機能しますが、それはうまく動作し、理解するものです。ありがとうすべて

0

私はここにエラーがあると思います:Player.player - プレーヤーはクラスであり、プレーヤー変数はありません。プレーヤーのオブジェクトをインスタンス化するには、上記の答えに従ってPlayerクラスからPlayerクラスをどのようにインポートするかに応じて、メインにthe_player = Player()またはthe_player = player.Player()を実行するだけです。変数にモジュールと同じ名前を付けないようにしてください。 Player_objectとは何ですか?

+0

私はコード内でこれを変更しました。現在、プレイヤーはplayer.playerではありません。これは私が問題を解決したかもしれないと思ったのでコード内にありました。 Player_objectは、私がAreaクラスに渡す変数の名前です。理解を容易にするため、プレーヤーに変更することができます。また、私は私の問題を解決した解決策は以下のとおりです。あなたの時間と努力に感謝します – JimmyMac