What is a "direct style object" and how do I implement it in my code?
I am trying to learn python by creating a space game where you travel around the map fighting enemies (drones) that are randomly placed around the map. So far I've been able to move the game spaceship around the map (with rotation), shoot lasers and beating drones around the map (drones follow the spaceship). While I don't quite understand the classes, I seem to have managed to pull this off so far.
Now I want to inject enemy hp with Laser / Drone collision. I gave the Drone class self.rect = self.image.get_rect()
and called its Laser1 class instance with self.c = pygame.Rect.colliderect(drone.rect)
, but it just gives me this:
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
I've searched a lot online to find a way to fix this, but I don't really understand and nothing works for me. Any help would be greatly appreciated!
Here is my code:
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))
Also, this is my first question to ask here. If there is anything I can do to better understand this question. I will exclude any feedback!
source to share
To answer the title: A forward style object is pygame.Rect
, a tuple or a list of 4 elements. So, you can usually pass a 4-tuple or list to methods expecting as well pygame.Rect
.
As Paul Cornelius pointed out, the exception is thrown because you are using a colliderect
class methodpygame.Rect
but must use an colliderect
self.rect
instance instead .
self.c = self.rect.colliderect(drone.rect)
In fact, you can directly use pygame.Rect.colliderect
and pass the two rectangles that you want to check, but this is unusual and will be a little confusing for everyone else.
# `self.rect` is passed as the `self` argument.
self.c = pygame.Rect.colliderect(self.rect, drone.rect)
source to share
You have no experience with Pygame, but with a little digging it seems that the problem you are having is the result of passing the wrong argument to yours pygame.Rect.colliderect()
on line 79. The object you are passing the pygame.Rect.colliderect()
method with is not readable as an object Rectangle
. Try to print data and object type drone.rect
to see where the problem might be.
source to share
Paul Cornelius is in the right direction. Since you are learning python, I will explain briefly. The colliderect method is implemented in 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));
}
Since you were calling it through a class definition and not an instance, it drone.rect
was tied to the oself
python shell to this method, and args
probably some equivalent was assigned NULL
. Therefore, you saw the error message (not the "missing required positional argument" as you might expect).
source to share