导入类时未定义错误全局变量

时间:2016-04-23 17:48:41

标签: python-2.7 methods arguments global-variables

我正在尝试实现一个移动系统,让玩家向点击位置移动。但是我一直在讨论运动方法的一些问题。

移动方法当前需要将所有变量作为参数:

此代码有效:

def move(self,event,mouse_pos, screen, background):
        if event.type == MOUSEBUTTONDOWN:
            if mouse_pos[1] > self.pos[1]:
                screen.blit(background, self.pos, self.pos) #erases players by bliting bg 
                self.speed = 1
                self.move_south() #moves player
            if mouse_pos[0] > self.pos[0]:
                screen.blit(background, self.pos, self.pos) #erases players by bliting bg 
                self.speed = 1
                self.move_east() #moves player
            screen.blit(self.image, self.pos) #draws player  

此代码无效:

def move(self,event):
        if event.type == MOUSEBUTTONDOWN:
            if mouse_pos[1] > self.pos[1]:
                screen.blit(background, self.pos, self.pos) #erases players by bliting bg 
                self.speed = 1
                self.move_south() #moves player
            if mouse_pos[0] > self.pos[0]:
                screen.blit(background, self.pos, self.pos) #erases players by bliting bg 
                self.speed = 1
                self.move_east() #moves player
            screen.blit(self.image, self.pos) #draws player   

全班代码:

import pygame, sys
from pygame.locals import *

class GameObject:
    def __init__(self, image, height, speed):
        self.speed = speed
        self.image = image
        self.pos = image.get_rect().move(0, height) #initial placement

    def move_south(self):
        self.pos = self.pos.move(0, self.speed)
        if self.pos.right > 600:
            self.pos.left = 0

    def move_east(self):
        self.pos = self.pos.move(self.speed , 0)
        if self.pos.right > 600:
            self.pos.left = 0

    def move(self,event,mouse_pos, screen, background):
            if event.type == MOUSEBUTTONDOWN:
                if mouse_pos[1] > self.pos[1]:
                    screen.blit(background, self.pos, self.pos) #erases players by bliting bg 
                    self.speed = 1
                    self.move_south() #moves player
                if mouse_pos[0] > self.pos[0]:
                    screen.blit(background, self.pos, self.pos) #erases players by bliting bg 
                    self.speed = 1
                    self.move_east() #moves player
                screen.blit(self.image, self.pos) #draws player      

主要脚本代码:

import pygame, sys
from pygame.locals import *
from classes import *

screen = pygame.display.set_mode((640, 480))
#Importing Chars
player = pygame.image.load('green_hunter_small.png').convert()
#player.set_alpha(100) #makes whole player transparent
player.set_colorkey((0,0,0)) #sets background colour to transparent

ennemi =  pygame.image.load('red_hunter_small.png').convert()
ennemi.set_colorkey((0,0,0))

background = pygame.image.load('grass_map_640x640.png').convert()
screen.blit(background, (0, 0))
objects = []
mouse_pos = (320, 240)
objects.append(GameObject(player, 80, 0))
for x in range(2):      #create 2 objects
    o = GameObject(ennemi, x*40, 0)
    objects.append(o)
while True:
    for event in pygame.event.get(): #setting up quit
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == MOUSEBUTTONDOWN :
            mouse_pos = pygame.mouse.get_pos()
            print mouse_pos
            for o in objects:
                screen.blit(background, o.pos, o.pos) #erases players by bliting bg 
            for o in objects:
                o.move(event,mouse_pos,screen,background)
    pygame.display.update()
    pygame.time.delay(100)

我有两个问题: 1)如何减少我的方法的参数数量? 2)如何让我的玩家不断向点击位置移动而不是每次点击一次?

2 个答案:

答案 0 :(得分:1)

因此,经过一些工作,我找到了解决问题的方法。

我只有两个互相导入的python文件。

我必须创建第三个文件以避免这种“循环”输入。

我使用名为main.py的主代码创建了一个文件,导入了classes.py文件和variables.py文件。

main.py:

import pygame, sys, variables
from pygame.locals import *
from classes import *

#Creating the characters
objects = []
objects.append(GameObject(variables.player, 80, 0))
for x in range(2):      #create 2 objects
    o = GameObject(variables.ennemi, x*40, 0)
    objects.append(o)

#game loop    
while True:
    for event in pygame.event.get(): #setting up quit
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == MOUSEBUTTONDOWN : #initiating movement on click

            for o in objects:
                variables.screen.blit(variables.background, o.pos, o.pos) #erases players by bliting bg 
            for o in objects:
                o.move(event)
    pygame.display.update()
    pygame.time.delay(20)

classes.py:

import pygame, sys, variables
from pygame.locals import *

class GameObject:
    def __init__(self, image, height, speed):
        self.speed = speed
        self.image = image
        self.pos = image.get_rect().move(0, height) #initial placement

    def move_NS(self):
        self.pos = self.pos.move(0, self.speed)
        if self.pos.right > 600:
            self.pos.left = 0

    def move_EW(self):
        self.pos = self.pos.move(self.speed , 0)
        if self.pos.right > 600:
            self.pos.left = 0


    def move(self,event):#,mouse_pos, screen, background
            if event.type == MOUSEBUTTONDOWN:
                if pygame.mouse.get_pos()[1] > self.pos[1]:
                    variables.screen.blit(variables.background, self.pos, self.pos) #erases players by bliting bg 
                    self.speed = 1
                    self.move_NS() #moves player
                if pygame.mouse.get_pos()[0] > self.pos[0]:
                    variables.screen.blit(variables.background, self.pos, self.pos) #erases players by bliting bg 
                    self.speed = 1
                    self.move_EW() #moves player
                if pygame.mouse.get_pos()[1] < self.pos[1]:
                    variables.screen.blit(variables.background, self.pos, self.pos) #erases players by bliting bg 
                    self.speed = -1
                    self.move_NS() #moves player
                if pygame.mouse.get_pos()[0] < self.pos[0]:
                    variables.screen.blit(variables.background, self.pos, self.pos) #erases players by bliting bg 
                    self.speed = -1
                    self.move_EW() #moves player

                variables.screen.blit(self.image, self.pos) #draws player     

variables.py:

import pygame, sys
from pygame.locals import *
#Variables
screen = pygame.display.set_mode((640, 480))

#Importing Chars
player = pygame.image.load('green_hunter_small.png').convert()
player.set_colorkey((0,0,0)) #sets background colour to transparent

ennemi =  pygame.image.load('red_hunter_small.png').convert()
ennemi.set_colorkey((0,0,0))

#importing background
background = pygame.image.load('grass_map_640x640.png').convert()
screen.blit(background, (0, 0))

希望它有所帮助!

答案 1 :(得分:0)

你的问题是python中的“全局”变量实际上并不是全局变量,而是定义它们的模块的本地变量。因此,你不能在main.py文件中引用十进制全局变量classes.py 1}}文件。

有三种可能的解决方案:

  1. (不推荐)将screenbackground的声明移至classes.py文件,这会使它们看起来不合适。

  2. (也不建议)在from main import screen, background文件中添加classes.py,这会产生循环导入问题,迫使main.py模块执行from classes import * < strong> 后定义screenbackground

  3. 添加第三个display.pyscreen.py文件,其中screenbackground变量已定义,并从main.pyclasses.py导入
  4. mouse_pos变量完全没必要且误用:

    1. 您可以直接在pygame.mouse.get_pos()文件中使用classes.py,但
    2. 使用pygame.mouse.get_pos()本身是绝对的,因为pygame.MOUSEBUTTONDOWN事件的pos属性指向事件被触发时鼠标的位置。