我正在修改的游戏引擎中的以下代码给出了这个错误:
***"UnboundLocalError: local variable 'event' referenced before assignment":***
player.update(current_level.object_list, event) found in the main_loop() in line 342
main_loop() in line 364.
我在这里尝试做的唯一事情是按回车从红色介绍屏幕转换到主循环。
引擎本身运行良好,直到我创建game_intro()
函数并将其定位在main_loop()
函数之前,以便在最后几行运行。我试着玩这两个功能本身,看看有什么可以使它工作,但没有运气。同样在第340行中的player.update语句上方的第340行中放置event = None允许我从intro过渡到主循环但是移动控件停止工作。
我很确定错误必须对Player类中的update()函数执行某些操作,但不知道是什么导致它,特别是当引用函数不使用更新函数中使用的事件时(分开)来自pygame.event)它只在添加了介绍屏幕后才开始崩溃。
from pygame import *
import pygame
# from colours import *
# from textObjects import small, medium, large
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
red = pygame.Color(255, 0, 0)
green = pygame.Color(0, 255, 0)
blue = pygame.Color(0, 0, 255)
pygame.font.init()
small = pygame.font.SysFont(None, 25)
medium = pygame.font.SysFont(None, 50)
large = pygame.font.SysFont(None, 80)
class Player(pygame.sprite.Sprite):
# Initialise function
def __init__(self, color=blue, width=32, height=48, health=100):
# I assume super() inherits everything from the block class
super(Player, self).__init__()
# Set the image to a Surface of size width and height
self.image = pygame.Surface((width, height))
# Fill the image with the default color of blue
self.image.fill(color)
# Use the Surface of the image to get the rectangular co-ordinates
self.set_properties()
# Create speed for x and y
self.speed_x = 0
self.speed_y = 0
# Create health
self.health = 100
self.level = None
def set_properties(self):
self.rect = self.image.get_rect()
# Create an x and y origin position (Centered the mouse on the sprite)
self.origin_x = self.rect.centerx
self.origin_y = self.rect.centery
self.speed = 5
# Create total travel distance to check the player's position on the map
self.travel_distance_x = 0
self.travel_distance_y = 0
# Function to easily set the position of any block object on the center
def set_position(self, x, y):
self.rect.x = x - self.origin_x
self.rect.y = y - self.origin_y
# Function made to print the position on the map
def print_position(self):
self.travel_distance_x += self.speed_x
self.travel_distance_y += self.speed_y
print self.travel_distance_x, self.travel_distance_y
def set_level(self, level):
self.level = level
self.set_position(level.player_start_x, level.player_start_y)
def set_image(self, filename=None):
if filename != None:
self.image = pygame.image.load(filename).convert()
self.set_properties()
def death(self):
print "Kill"
return display_message("Vaziuojam", black)
def update(self, collidable=pygame.sprite.Group(), event=True):
self.experience_gravity()
self.event = True
self.rect.x += self.speed_x
collision_list = pygame.sprite.spritecollide(self, collidable, False)
for collided_object in collision_list:
# Right direction
if self.speed_x > 0:
self.rect.right = collided_object.rect.left
# Left direction
elif self.speed_x < 0:
self.rect.left = collided_object.rect.right
self.rect.y += self.speed_y
collision_list = pygame.sprite.spritecollide(self, collidable, False)
for collided_object in collision_list:
# Down direction
if self.speed_y > 0:
self.rect.bottom = collided_object.rect.top
self.speed_y = 0
# Up direction
elif self.speed_y < 0:
self.rect.top = collided_object.rect.bottom
self.speed_y = 0
if not event == None:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
self.speed_x = -self.speed
# self.change_speed(-self.speed, 0)
if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
self.speed_x = self.speed
# self.change_speed(self.speed, 0)
if event.key == pygame.K_UP or event.key == pygame.K_w:
if len(collision_list) >= 1:
self.speed_y = -(self.speed) * 2
# self.change_speed(0, -self.speed * 2)
if event.key == pygame.K_DOWN:
# self.change_speed(0, self.speed)
pass
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
if self.speed_x < 0:
self.speed_x = 0
if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
if self.speed_x > 0:
self.speed_x = 0
def experience_gravity(self, gravity=0.35):
if self.speed_y == 0:
self.speed_y = 1
else:
self.speed_y += gravity
class Block(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, color=blue):
# I assume super() inherits everything from the block class
super(Block, self).__init__()
# Set the image to a Surface of size width and height
self.image = pygame.Surface((width, height))
# Fill the image with the default color of blue
self.image.fill(color)
# Get rectangle object of the block
self.rect = self.image.get_rect()
# Assign x and y co-ordinates of the block
self.rect.x = x
self.rect.y = y
def experience_gravity(self, gravity=0.35):
if self.speed_y == 0:
self.speed_y = 1
else:
self.speed_y += gravity
class Level(object):
def __init__(self, player_object):
self.object_list = pygame.sprite.Group()
self.player_object = player_object
self.player_start = self.player_start_x, self.player_start_y = 80, 150
self.world_shift_x = 0
self.world_shift_y = 0
self.left_viewbox = screen_width / 2 - screen_width / 8
self.right_viewbox = screen_width / 2 + screen_width / 8
self.up_viewbox = screen_height / 3
self.down_viewbox = screen_height / 2 # + screen_height / 12
def update(self):
self.object_list.update()
def draw(self, screen):
screen.fill(white)
self.object_list.draw(screen)
def shift_world(self, shift_x, shift_y):
self.world_shift_x += shift_x
self.world_shift_y += shift_y
for each_object in self.object_list:
each_object.rect.x += shift_x
each_object.rect.y += shift_y
def scroll(self):
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)
class Level_01(Level):
def __init__(self, player_object):
super(Level_01, self).__init__(player_object)
level = [
#[x, y, width, height, color]
[0, 3, 10, 844, black],
[108, 0, 21, 730, black],
[5, 838, 325, 9, black],
[240, 815, 130, 32, black],
[316, 782, 204, 64, black],
[364, 749, 179, 96, black],
[469, 680, 84, 156, black],
[365, 805, 189, 42, black],
[410, 715, 68, 56, black],
[645, 679, 244, 18, black],
[977, 678, 265, 13, black],
[1439, 676, 93, 14, black],
[1668, 670, 222, 16, black],
[2068, 664, 359, 18, black],
[2544, 617, 11, 64, black],
[2653, 556, 11, 80, black],
[2771, 484, 15, 113, black],
[2922, 434, 277, 12, black],
[2777, 327, 138, 15, black],
[2659, 242, 20, 126, black],
[2505, 178, 17, 145, black],
[2226, 257, 176, 14, black],
[2120, 266, 10, 92, black],
[1808, 252, 213, 10, black],
[1631, 265, 8, 86, black],
[1231, 255, 293, 14, black],
[1009, 261, 169, 12, black],
[670, 259, 189, 18, black],
[116, 127, 420, 20, black],
[590, 183, 19, 95, black]
]
for block in level:
block = Block(block[0], block[1], block[2], block[3], block[4])
self.object_list.add(block)
def set_message(text):
global message, previous_message
message = font.render(text, True, black, white)
previous_message = message
def text_objects(text, color, size):
if size == 'small':
textSurface = small.render(text, True, color)
if size == 'medium':
textSurface = medium.render(text, True, color)
if size == 'large':
textSurface = large.render(text, True, color)
return textSurface, textSurface.get_rect()
def display_message(text, color, y_displacement=0, size='small'):
textSurface, textRectangle = text_objects(text, color, size)
textRectangle.center = (screen_width / 2), (screen_height / 2) + y_displacement
screen.blit(textSurface, textRectangle)
def character_message(text, color, y_displacement=0, size='small'):
textSurface, textRectangle = text_objects(text, color, size)
textRectangle = player.travel_distance_x , player.travel_distance_y + y_displacement
screen.blit(textSurface, textRectangle)
# Initialise pygame module
pygame.init()
# Initialise pygame font
pygame.font.init()
# Defining the screen size
screen_size = screen_width, screen_height = 800, 600
# Setting the display and getting the Surface object
screen = pygame.display.set_mode(screen_size)
# Getting the Clock object
clock = pygame.time.Clock()
# Setting a title to the window
pygame.display.set_caption("TODO make title")
# Defining variable for FPS
fps_limit = 60
# Clear the screen
screen.fill(white)
# Setting the FPS at which the game will run
clock.tick(fps_limit)
# Group all the currently active objects
active_object_list = pygame.sprite.Group()
# Set variable player to the Player() class
player = Player()
# Add player to the active object list
active_object_list.add(player)
# Make a list for the levels and append Level_01 to that list with player as the handler
level_list = []
level_list.append(Level_01(player))
current_level_number = 0
current_level = level_list[current_level_number]
player.set_level(current_level)
# Define our font
font = pygame.font.SysFont(None, 25)
# Define a message, we're doing this because it will be used as a surface
message = previous_message = None
set_message("")
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
run=True
intro=False
if event.key == pygame.K_ESCAPE:
pygame.quit()
quit()
screen.fill(red)
pygame.display.update()
def main_loop():
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
run = False
# Update functions
player.update(current_level.object_list, event)
event = None
current_level.update()
# Logic testing
current_level.scroll()
# Draw everything
current_level.draw(screen)
active_object_list.draw(screen)
if player.travel_distance_y > 900:
player.health = 0
display_message("Death test message", black)
# Delay fps
clock.tick(fps_limit)
# Update screen
pygame.display.update()
player.print_position()
game_intro()
main_loop()
我仍然只是想开始理解课程和范围,所以任何提示都会有很大的帮助,谢谢你提前!
答案 0 :(得分:1)
正如molbdnilo所提到的,主循环中的缩进是错误的。但是,一旦你传递了这个事件,没关系,但是如果没有事件,那么玩家就不会更新。
更好的方法是为事件创建一个全局变量,然后每帧运行一次更新函数,并在内部检查事件,但是对于快速修复,这里就去了。
def main_loop():
run = True
while run:
current_events = pygame.event.get()
if current_events:
for event in current_events:
if event.type == pygame.QUIT:
pygame.quit()
quit()
run = False
# Update functions
player.update(current_level.object_list, event)
current_level.update()
else:
player.update(current_level.object_list, None)
current_level.update()
# Logic testing
current_level.scroll()
# Draw everything
current_level.draw(screen)
active_object_list.draw(screen)
if player.travel_distance_y > 900:
player.health = 0
display_message("Death test message", black)
# Delay fps
clock.tick(fps_limit)
# Update screen
pygame.display.update()
player.print_position()