こんにちは、これは私のフォーラムの最初の投稿です。私は通常、ブラウズして自分自身で問題を解決していますが、私の頭は壁にぶち壊してしまいます。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の結果を期待しています。とにかく私の主な目標は:
- プレーヤクラスをメインスクリプトから除外し、それ自身のモジュールに、まだ領域を通過させることができます。
、その後 2.ゆっくり 3.私はcurrent_areaのために使用していますグローバル取り除く(それは同じソリューションがします希望に満ちた)残りのコードを削除します。
読んでいただきありがとうございました。私がこれを解読するまで、私は壁に突き当たり続けて、自分が見つけた解決策を投稿します。
Player変数になるCurrent_areaが不思議になりました。私はそれを見ました。私はまだプレーヤークラスを移動し、メインファイルとplayer.pyファイルにインポートを行った後も、インポートには問題があります。私はまだ洞窟や店に入るときにクラッシュする(私は場所を変更すると)私はNameErrorを得る:name 'player'は定義されていない。私は、プレイヤーがメインスクリプトのすべての関数とクラスを介してアクセスできるようにプレーヤーを定義する必要がある場所を理解していません。お返事ありがとうございました。 – JimmyMac