Maartenww
Maartenww

Reputation: 33

How do I create sprite collision in PyGame using vectors?

https://github.com/maartenww/100daysOfCode_projectOne/tree/StackOverflow (For reference here is the Repo to my code with a branch to code with the error, (so it's still readable for other people))

Hi, I'm creating a platformer and i'm stuck with a problem where I try to make collision between two sprites work using the pygame library.

class Game:

    def sprite_col(self, player_1, platform_list):
        sprites_hit = pygame.sprite.spritecollide(player_1, platform_list, False)

The sprites position is calculated with the use of pygame vectors

vec = pygame.math.Vector2

class Player(pygame.sprite.Sprite):

    # Player Constructor
    def __init__(self, player_width, player_height, player_color):
        pygame.sprite.Sprite.__init__(self)
        self.rect = self.image.get_rect()
        self.player_pos = vec(screen_width / 2, screen_height / 2)
        self.rect.x = self.player_pos.x
        self.rect.y = self.player_pos.y

I have no idea why the top code block doesn't run however. I've googled my problem and looked at this video that I'm using for reference :

https://www.youtube.com/watch?v=pN9pBx5ln40&list=PLsk-HSGFjnaG-BwZkuAOcVwWldfCLu1pq&index=3 (Skip to 8:40)

It gives me the following error:

Traceback (most recent call last): File "C:/ScrewAround/100DaysOfCodeProject1/main.py", line 81, in main()

File "C:/ScrewAround/100DaysOfCodeProject1/main.py", line 76, in main g.run(Player_1)

File "C:/ScrewAround/100DaysOfCodeProject1/main.py", line 65, in run self.update_game(player_1)

File "C:/ScrewAround/100DaysOfCodeProject1/main.py", line 58, in update_game self.sprite_col(player_1)

File "C:/ScrewAround/100DaysOfCodeProject1/main.py", line 41, in sprite_col sprites_hit = pygame.sprite.spritecollide(player_1, platform_sprites, False)

File "C:\ScrewAround\100DaysOfCodeProject1\venv\lib\site-packages\pygame\sprite.py", line 1524, in spritecollide spritecollide = sprite.rect.colliderect

AttributeError: 'pygame.math.Vector2' object has no attribute 'colliderect'

As you can see it's an AttributeError with Vectors and colliderect. However I have no clue how this is relevant to my code and therefore have no idea where the error is referring to.

Upvotes: 0

Views: 805

Answers (1)

sloth
sloth

Reputation: 101072

In your Player class, you have the following function:

def update_player(self):
    # Gravity
    self.player_vel.y += self.player_acc.y
    self.player_pos.y += self.player_vel.y + self.player_acc.y * .5
    # Acceleration
    self.rect = self.player_pos
    self.player_vel.x += self.player_acc.x
    self.player_pos.x += self.player_vel.x + self.player_acc.x * .5
    # Friction
    self.player_acc.x += (self.player_vel.x * -PLAYER_FRIC) / 1000
    if (self.player_vel.x > -.1) and (.1 > self.player_vel.x):
        self.player_acc.x = 0
        self.player_vel.x = 0
    elif(self.player_vel.x > 15) and (-15 > self.player_vel.x):
        self.player_vel.x = 15
        self.player_acc.x = 15

Note the line

self.rect = self.player_pos

player_pos is a Vector2. So, after this line, self.rect will be a Vector2, too.

But every function in the pygame library that deals with Sprites expects the Sprite to have a rect field of type Rect. Hence the error: spritecollide want to use Rect.colliderect.

You could use a custom collide function and use it in spritecollide, but IMHO it would be better if you would get rid of player_pos and just use the rect field to store the position of the Sprite.

Another way would be to just change the Rect to the position stored in the Vector, like you already to in the __init__ function:

 self.rect.x = self.player_pos.x
 self.rect.y = self.player_pos.y

Upvotes: 2

Related Questions