当前房间中精灵的碰撞检测

时间:2018-07-23 05:16:07

标签: python pygame collision

不久前,我问了一个关于岩石碰撞检测的类似问题。我有多个房间,每个房间都有一组岩石。这些岩石的碰撞检测在玩家类中。我的问题是,如何设置这些碰撞检测功能以使其适合这些房间中的岩石?

当我运行脚本并尝试移动角色时,会出现此错误:

line 34, in move_single_axis
    for rock in current_room.rock_list:
NameError: name 'current_room' is not defined

这是分成多个文件的代码。

播放器类文件

import pygame


BLACK = (0, 0, 0)
WHITE = (255, 255, 255)


class Player(pygame.sprite.Sprite):


    def __init__(self, filename, x, y):

        super().__init__()

        self.image = pygame.image.load(filename).convert()
        self.image.set_colorkey(BLACK)

        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y


    def changespeed(self, x, y):
        if x != 0:
            self.move_single_axis(x, 0)
        if y != 0:
            self.move_single_axis(0, y)

    def move_single_axis(self, x, y):
        self.rect.x += x
        self.rect.y += y

        for rock in current_room.rock_list:

            if self.rect.colliderect(rock.rect):
                if x > 0:
                    self.rect.right = rock.rect.left
                if x < 0:
                    self.rect.left = rock.rect.right
                if y > 0:
                    self.rect.bottom = rock.rect.top
                if y < 0:
                    self.rect.top = rock.rect.bottom

房间类文件

import Player
import pygame
from Rock import *


BLACK = (0, 0, 0)
WHITE = (255, 255, 255)


class Room(object):
    rock_list = None

    def __init__(self):

        self.rock_list = pygame.sprite.Group()


class Room0(Room):
    def __init__(self):
        super().__init__()

        rock = Rock("Rock.png", 200, 200)
        self.rock_list.add(rock)

        self.background_position = [0, 0]
        self.background_image = pygame.image.load("Floor.png").convert()

摇滚类文件

import pygame


BLACK = (0, 0, 0)
WHITE = (255, 255, 255)



class Rock(pygame.sprite.Sprite):

    def __init__(self, filename, x, y):

        super().__init__()    

        self.image = pygame.image.load(filename).convert()
        self.image.set_colorkey(BLACK)

        self.rect = self.image.get_rect().inflate(1, 1)
        self.rect.y = y
        self.rect.x = x

主循环文件

import Rock
from Rooms import *
from Player import *
import pygame


BLACK = (0, 0, 0)
WHITE = (255, 255, 255)


pygame.init()

screen_width = 1080
screen_height = 607
screen = pygame.display.set_mode([screen_width, screen_height])

pygame.display.set_caption('Labyrinth')

block_list = pygame.sprite.Group()
all_sprites_list = pygame.sprite.Group()
rock_list = pygame.sprite.Group()

player = Player("Isaac.png", 420, 150)
all_sprites_list.add(player)

rooms = []

room = Room0()
rooms.append(room)

current_room_no = 0
current_room = rooms[current_room_no]

clock = pygame.time.Clock()


done = False


# -- MAIN PROGRAM LOOP -- #

# -- Event processing --

while not done:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

# Player controls

    key = pygame.key.get_pressed()
    if key[ord('a')]:
        player.changespeed(-7, 0)
    if key[ord('d')]:
        player.changespeed(7, 0)
    if key[ord('w')]:
        player.changespeed(0, -7)
    if key[ord('s')]:
        player.changespeed(0, 7)

# -- Game Logic --

    all_sprites_list.update()

# Hit detection 

    blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True)

    screen.blit(current_room.background_image, current_room.background_position)

    all_sprites_list.draw(screen)
    current_room.rock_list.draw(screen)

    pygame.display.flip()

    clock.tick(60)

pygame.quit()

2 个答案:

答案 0 :(得分:2)

发生错误是因为您试图在current_room类中使用全局Player变量,但是该变量在此模块中不存在,仅存在于MAIN LOOP FILE中。我认为最简单的解决方案是将房间传递给玩家并将其添加为属性:

# In the main loop file.
# Pass the current_room to the Player's __init__ method.
player = Player("Isaac.png", 420, 150, current_room)


class Player(pygame.sprite.Sprite):

    def __init__(self, filename, x, y, current_room):
        super().__init__()
        # Add the room as an attribute.
        self.current_room = current_room
        # ...

    def move_single_axis(self, x, y):
        self.rect.x += x
        self.rect.y += y
        # Use the `self.current_room` attribute.
        for rock in self.current_room.rock_list:
            # ...

更改房间后,还必须更改player.current_room属性。

答案 1 :(得分:1)

您总是可以将current_room作为参数传递给播放器类中的set函数,以便播放器存储当前房间的引用。

  1. 为播放器创建一个新的变量。

  2. 创建一个设置函数并传入当前房间。

  3. 在播放器move_single_axis函数中使用该引用。