什么是'rect style object',如何在我的代码中实现它?

时间:2017-08-09 00:28:05

标签: python pygame

我正在尝试通过制作一个太空游戏来学习python,你可以在地图周围与地图上随机放置的敌人(无人机)进行战斗。到目前为止,我已经成功地将可玩太空船移动到地图周围(旋转),发射激光和地图周围的无人机(无人机跟随飞船周围)。虽然我并不完全理解课程,但到目前为止我似乎能够完成课程。

现在,我想用激光/无人机碰撞输入敌人的hp。我给了Drone类self.rect = self.image.get_rect()并使用self.c = pygame.Rect.colliderect(drone.rect)在Laser1类中调用了它的一个实例,但它只是给了我这个:

Traceback (most recent call last):
  File "space.py", line 85, in <module>
    blist.append(Laser1 (beamx, beamy))
  File "space.py", line 79, in __init__
    self.c = pygame.Rect.colliderect(drone.rect)
TypeError: Argument must be rect style object

我已经在网上搜索了很多方法来解决这个问题,但我对此并不了解,似乎没有什么对我有用。任何帮助将不胜感激!

这是我的代码:

class Drone:

    def __init__(self, dronex, droney):
        self.x = dronex
        self.y = droney
        self.hp = dronehp
        self.image = pygame.image.load("Androne.png").convert_alpha()
        self.rect = self.image.get_rect()

dlist = []
for i in range(10):
    dronex = random.randint(0, 7700)
    droney = random.randint(0, 4520)
    dronehp = 3
    dlist.append(Drone (dronex, droney))

drone = Drone(dronex, droney) #-----------instance i think...

class Roid:

    def __init__(self, roidx, roidy):
        self.x = roidx
        self.y = roidy
        self.type = random.randint(0, 2)

rlist = []
for i in range(811):
    roidx = random.randint(-1000, 9104)
    roidy = random.randint(-800, 7200)
    rlist.append(Roid (roidx, roidy))

class Laser1:

    def __init__(self, beamx, beamy):
        self.x = beamx
        self.y = beamy
        self.laser1 = pygame.image.load("laser1.png").convert_alpha()
        self.rect = self.laser1.get_rect()
        self.c = pygame.Rect.colliderect(drone.rect) #---line 79...

blist = []
for i in range(2):
    beamx = batx
    beamy = baty
    blist.append(Laser1 (beamx, beamy)) #---line 85...

class Laser2:

    def __init__(self, beamx2, beamy2):
        self.x2 = beamx2
        self.y2 = beamy2
        self.laser1 = pygame.image.load("laser1.png").convert_alpha()
        self.rect = self.laser1.get_rect()
        self.c = pygame.Rect.colliderect(drone.rect)

b2list = []
for i in range(2):
    beamx2 = batx
    beamy2 = baty
    b2list.append(Laser2 (beamx2, beamy2))

此外,这是我在这里提出的第一个问题。如果有什么我可以做的就是让这个问题变得更好。我将除了任何和所有的反馈!

3 个答案:

答案 0 :(得分:1)

没有任何关于Pygame的经验,但是通过一点点搜索,你所遇到的问题似乎是在第79行将不正确的参数传递给你的pygame.Rect.colliderect()。你传递的对象pygame.Rect.colliderect()方法未被读取为Rectangle对象。尝试打印对象drone.rect数据和对象类型以查看问题所在。

答案 1 :(得分:1)

Paul Cornelius正朝着正确的方向前进。由于您正在学习python,我将简要解释一下。 colliderect方法在C:

中实现
static PyObject*
rect_colliderect (PyObject* oself, PyObject* args)
{
    PyRectObject* self = (PyRectObject*)oself;
    GAME_Rect *argrect, temp;
    if (!(argrect = GameRect_FromObject (args, &temp)))
        return RAISE (PyExc_TypeError, "Argument must be rect style object");

    return PyInt_FromLong (DoRectsIntersect (&self->r, argrect));
}

由于您是通过类定义调用它而不是实例,因此drone.rect被此方法的python包装器分配给oself,并且args可能被分配了一些等效的NULL {1}}。因此,您看到的错误消息(而不是缺少必要的位置参数&#39;正如人们所期望的那样)。

答案 2 :(得分:1)

回答标题:rect样式对象是pygame.Rect,元组或包含4个元素的列表。因此,您通常可以将4元组或列表传递给期望pygame.Rect的方法。

正如Paul Cornelius所提到的,由于您使用了colliderect pygame.Rect方法,因此会引发异常,但应该使用colliderect的{​​{1}} self.rect 实例

self.c = self.rect.colliderect(drone.rect)

您实际上可以直接使用pygame.Rect.colliderect并传递您要检查的两个部分,但这种情况并不常见,对其他人来说会有点混乱。

# `self.rect` is passed as the `self` argument.
self.c = pygame.Rect.colliderect(self.rect, drone.rect)