0

DISCLAIMER: I know other people on this site have had this error but it's been in different contexts and the fixes don't seem to work here.

Hey stackoverflow, Basically I've been making a sideways space invaders game, where your ship follows your mouse's Y position but stays on the left, and clicking shoots a bullet. Enemies spawn randomly from the right and fly to the left, and objects are removed once they each the side of the screen. This all works fine, however when I tried to implement collision detection to see when the shot hits the enemy, I get the error:

TypeError: Argument must be rect style object. 

It points to the line "return hitbox.colliderect(target.rect)". To try and work out what was causing this I made some 'print' lines below it to see what 'target.rect' was (and whether it was a proper rect object), and it seemed to be exactly the same style as the shot's own rect, so I'm completely lost as to why colliderect doesn't accept it.

I've annotated pretty much everything, sorry if it's an insult to your intelligence but it should make things easier.

Class that causes problems:

class gameObject: def __init__(self, image, height, speed): self.speed = speed self.image, self.rect = load_image("shot.dsf", -1) #Loads the image and creates rectange self.pos = image.get_rect().move(0, height) def move(self): self.pos = self.pos.move(self.speed, 0) #Moves along self.rect = [self.pos, 32, 32] #Updates the position of the rectange. Without it the rectangle just stays in the top left corner but the image moves if self. pos.right > 1400: #Checks if shot goes offscreen objects.remove(self) #Removes it def hitreg(self,target): hitbox = self.rect #Creates hitbox of it's own rectangle return hitbox.colliderect(target.rect) #SHOULD return true if hitbox collides with the rect of target, however it returns the error print("OWN RECT: ",self.rect) #Debug purposes, returns ('OWN RECT: [<rect(1350, 245, 32, 32)>, 32, 32]) print("TARGET RECT: ",target.rect) #Debug purposes, returns ('TARGET RECT: [<rect(360, 479, 128, 64)>, 128, 64]) 

Main Loop

r.drawFrame() #Renders Frame while running: sleep(0.0166) #Make sure it only renders at most 60fps rand = rnd(10,20) #Generates random number from 10 to 20 pos = pygame.mouse.get_pos() #Gets mouse position for event in pygame.event.get(): if event.type == MOUSEBUTTONUP: #Prevents hang None if event.type == MOUSEBUTTONDOWN: #Creates shot if mousebuttondown, at mouse height with random speed o = gameObject(shot, pos[1], rand) objects.append(o) if rnd(1,120) == 60: #Randomely Spawns Enemy Ships s = enemyShip(enemya, rnd(10,890), rand) #enemya is filename ships.append(s) for o in objects: #For each shot for s in ships: #For each enemy ship if o.hitreg(s): #Calls hitreg function, s being the target s.takedamage() score = score + 10 #Increases score r.drawFrame() #Renders Frame 

1 Answer 1

1

If the output shown in your source code can be trusted, your debug statements show that neither self.rect nor target.rect are "rect style" objects. They appear to be lists consisting of a rect followed by 2 integers such as this:

OWN RECT: [<rect(1350, 245, 32, 32)>, 32, 32]) TARGET RECT: [<rect(360, 479, 128, 64)>, 128, 64] 

The move() method is responsible for changing self.rect from a "normal" rect into a list as above, but this modified self.rect will not behave like a rect. Perhaps in hitreg() you should be calling hitbox = self.rect[0].

Anyway, in this case, I suspect that the output of your debug statements as shown is incorrect. Probably the value for self.rect is a rect (because lists do not have method colliderect(), but colliderect() does seem to be called), and it is target.rect that is a list. target.rect is of type enemyShip, but you don't show the code for that, so it is not possible to tell what is actually going on there (although one could guess that move() has been called on it and it's self.rect corrupted).

I suggest that you capture some real debug output and add that to your question. It would also be helpful if you could post accurate code, because there is at least 1 syntax error, e.g. in the line:

if self. pos.right > 1400: 

And what does the code for enemyShip look like?

Sign up to request clarification or add additional context in comments.

1 Comment

Strangely pygame doesn't seem to mind that space in self. pos.right, never picked up on that. But thanks, you've helped me identify the issue, which was the fact it has the two intergers on the end. This is a problem on line 8 of the gameObject class, which is due to me assuming that the self.pos was only the coordinates and didn't include the size, so I added them on manually, meaning both target.rect and self.rect were lists. I'm quite experienced in python but not so much in pygame, so I really appreciate your help :D

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.