2016-06-03 4 views
0

나는에 땜질하고있어 게임 엔진에서 다음 코드는 날이 오류를 제공합니다 반환을 누르십시오.파이 게임 UnboundLocalError

game_intro() 함수를 만들고 마지막 두 줄에서 실행되도록 main_loop() 함수 앞에 엔진을 배치했습니다. 나는 2 가지 기능으로 스스로 놀아 내려고 노력했다. 또한 339 행의 player.update 명령문 위의 340 행에 event = None을 입력하면 소개에서 다른 루프로 전환 할 수 있지만 동작 제어가 작동을 멈 춥니 다.

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

Welcome to Stackoverflow. – DomTomCat

+0

당신이 들여 쓰기를 망쳤다면 [Minimal, Complete, Verifiable example] (http://stackoverflow.com/help/mcve)을 제공해야합니다. 'if event.type == ... '조건문 만 이벤트 루프 안에 있고, 플레이어에게 이벤트를 전달하려면'player.update'가 있어야합니다. – molbdnilo

+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() 
+0

환상적입니다. 게임 루프가 소개 기능을 구현하는 것과 같은 구조를 변경하지 않을 것이라고 기대하지 않았습니다. 오늘 새 걸 가르쳐 줘서 고마워! –