与colliderect和类相关的Pygame问题

时间:2016-11-16 16:14:52

标签: python pygame

我有一个关于colliderect函数和嵌入在类和函数中的变量的问题。

我在我的重要元素(玩家,终点线,怪物)周围创建了“hitboxes”,我希望当这些hitbox“遇见”时触发动作。

我知道pygame中的 colliderect 函数是为了做到这一点,但不知怎的,我无法实现它。

有人可以向我解释一下,我将如何使用以下代码中的功能,特别是当我必须调用的变量嵌入到单独的类和函数中时?

非常感谢,到目前为止,这是我的代码:

#!/usr/bin/python
import sys, pygame, glob, math
from pygame import *
from random import randint
import time

pygame.init()

h = 600
w = 800
screen = pygame.display.set_mode((w, h))
clock = pygame.time.Clock()
jump_height = 0

class finish_line:
    def __init__(self):
        self.n = 600
        self.b = 200
        self.img_finish = pygame.image.load("finish.png")
        self.update_finish(0)
    def update_finish(self, pos_finish):
        screen.blit(self.img_finish, (self.n, self.b))


class player:
    def __init__(self):
        self.x = 11
        self.y = 200
        self.speed = 5
        self.ani_speed_init = 5
        self.ani_speed = self.ani_speed_init
        self.ani = glob.glob("animation/run*.png")
        self.ani.sort()
        self.ani_pos = 0
        self.ani_max = len(self.ani)-1
        self.img = pygame.image.load(self.ani[0])
        self.update(0)

    def update(self, pos):
        if pos > 0:
            if self.x >= (w - 100):
                self.x = self.x
            else:
                self.x += self.speed

            self.ani_speed -= 1
            if self.ani_speed == 0:
                self.img = pygame.image.load(self.ani[self.ani_pos])
                self.ani_speed = self.ani_speed_init
                if self.ani_pos == self.ani_max:
                    self.ani_pos = 0
                else:
                    self.ani_pos += 1

        elif pos < 0:
            if self.x <= 9:
                self.x = self.x
            else:
                self.x -= self.speed

            self.ani_speed -= 1
            if self.ani_speed == 0:
                self.img = pygame.image.load(self.ani[self.ani_pos])
                self.ani_speed = self.ani_speed_init
                if self.ani_pos == self.ani_max:
                    self.ani_pos = 0
                else:
                    self.ani_pos += 1

        if jump_height == 1:
            if self.y <= 10:
                self.y = self.y
            else:
                self.y -= self.speed
        elif jump_height == -1:
            if self.y >= 500:
                self.y = self.y
            else:
                self.y += self.speed
        rectplayer = pygame.draw.rect(screen, (0, 0, 0), ((self.x + 10), (self.y + 15), 65, 70), 1)
        screen.blit(self.img, (self.x, self.y))
        return self.x, self.y


class monster:
    rectmonster = 0
    def __init__(self):
        self.v = 650
        self.c = 200
        self.speed_monster = 0.3
        self.img_monster = pygame.image.load("orange.png")
        self.update_monster(0)

    def update_monster(self, pos_monster):
        if pos_monster == 1:
            self.v = self.v + ((randint(-5, 1)) * self.speed_monster)
            self.c = self.c + ((randint(-1, 3)) * self.speed_monster)
            if self.v >= 660:
                self.v = self.v + ((randint(-2, 0)) * self.speed_monster)
            elif self.v <= 140:
                self.v = self.v + ((randint(0, 2)) * self.speed_monster)
            if self.c <= 140:
                self.c = self.c + ((randint(0, 2)) * self.speed_monster)
            elif self.c >= 460:
                self.c = self.c + ((randint(-2, 0)) * self.speed_monster)

        rectmonster = pygame.draw.rect(screen, (0, 0, 0), ((self.v + 12), (self.c + 5), 76, 90), 1)
        screen.blit(self.img_monster, (self.v, self.c))

finish1 = finish_line()
player1 = player()
monster1 = monster()
monster2 = monster()
pos = 0
pos_monster = 1
pos_finish = 0

while 1:
    screen.fill((255, 204, 229))
    pygame.draw.rect(screen, (0,0,0,), (610, 210, 200, 180), 1)
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == KEYDOWN and event.key == K_RIGHT:
            pos = 1
        elif event.type == KEYUP and event.key == K_RIGHT:
            pos = 0
        elif event.type == KEYDOWN and event.key == K_LEFT:
            pos = -1
        elif event.type == KEYUP and event.key == K_LEFT:
            pos = 0
        elif event.type == KEYDOWN and event.key == K_UP:
            jump_height = 1
        elif event.type == KEYUP and event.key == K_UP:
            jump_height = 0
        elif event.type == KEYDOWN and event.key == K_DOWN:
            jump_height = -1
        elif event.type == KEYUP and event.key == K_DOWN:
            jump_height = 0

    finish1.update_finish(pos_finish)
    monster1.update_monster(pos_monster)
    monster2.update_monster(pos_monster)
    player1.update(pos)

    pygame.display.flip()

1 个答案:

答案 0 :(得分:0)

根据上述两条评论,这是我对问题的两分钱。

您假设pygame.draw.rect会自动为您的班级提供尺码属性,但事实并非如此 您将rect()的返回值存储在rectplayer中,如下所示:

rectplayer = pygame.draw.rect(...)

我打赌rect()首先返回None。除此之外,变量不会存储为self.rectplayer,因此它是一个本地函数变量而不是类拥有的变量 - 所以Pygame无法检查它。

这是一个容易犯的错误,如果这是问题的唯一根源,那将是一个简单的修复。

不幸的是,这里有更多的假设,例如colliderrectPygame的全局函数。

碰撞&amp;什么是精灵?

Pygame内部函数有一个关键说明:

  

所有精灵必须有一个“rect”值,这是一个矩形   精灵区域,用于计算碰撞。

这是pygame.sprite.spritecollide()调用的内部函数,它提到了你应该使用 Sprites 的事实。

这是一个精灵对象的最小例子:

class Player(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
       pygame.sprite.Sprite.__init__(self)

       self.image = pygame.Surface([width, height])
       self.image.fill(color)

       self.rect = self.image.get_rect()

在这个精灵的初始化过程的底部,我们定义了包含self.rect数据的矩形(start_x, start_y), (width, height)。这些是您在上面的示例中未定义的大小属性。

最有可能的是,您可以按照以下方式定义:

class player:
    def __init__(self):
        self.rect = ...

但请记住,您的<class player>没有名为spritecollide()collide_rect()的功能,这些功能是来自pygame.sprite.Spritepygame.Surface的继承,所以你'最好坚持将这些作为自定义类的继承对象。

请参阅我上面的class Player(...)如何执行此操作的示例。

我知道这并不能解决您的整个代码库,但希望它能让您对完成代码所需的内容有所了解。

结束记录

友情提醒,如果您认为某些事情已经为您完成了 - 请仔细检查一下。假设一个类因为你绘制了一个矩形而获得了大小属性,请检查你的类是否真的这样做了。

player1 = player()
print(dir(player1))

那里有什么东西与widthheightsizerectangle类似吗?如果没有,这应该表明某些东西很时髦。