Reputation: 1267
I am attempting to make a platformer game, in which there are no slopes. I am trying to get collision detection down, but I can't find a way in pygame to get which side collided with the other sprite. Can anyone give me a good way to do this, that isn't too bulky, but would also work well in my situation?
Here is my player class:
class Player(pg.sprite.Sprite):
def __init__(self,game):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((30, 40))
self.game = game
self.image.fill(YELLOW)
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
self.pos = vec(WIDTH / 2, HEIGHT / 2)
self.vel = vec(0, 0)
self.acc = vec(0, 0)
def jump(self):
self.rect.y += 1
hits = pg.sprite.spritecollide(self, self.game.platforms, False)
self.rect.y -= 1
if hits:
self.vel.y = -15
def update(self):
self.acc = vec(0, PLAYER_GRAV)
keys = pg.key.get_pressed()
if keys[pg.K_LEFT]:
self.acc.x = -PLAYER_ACC
if keys[pg.K_RIGHT]:
self.acc.x = PLAYER_ACC
self.acc.x += self.vel.x * PLAYER_FRICTION
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
self.rect.midbottom = self.pos
Here is my platform class:
class Platform(pg.sprite.Sprite):
def __init__(self, x, y ,w, h):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((w,h))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.centerx = x+(w/2)
self.centery = y+(h/2)
And here is how I currently do collisions (which only works on the top of the platform)
hits = pg.sprite.spritecollide(self.player,self.platforms, False)
if hits:
self.player.pos.y = hits[0].rect.top+1
self.player.vel.y = 0
EDIT:
I've added this to my player class and I run it every time the player updates, and it works... almost.
def wall_collisions(self):
self.rect.centerx = self.pos.x
for wall in pg.sprite.spritecollide(self, self.walls, False):
if self.vel.x > 0:
self.rect.right = wall.rect.left
self.vel.x = 0
elif self.vel.x < 0:
self.rect.left = wall.rect.right
self.vel.x = 0
self.pos.x = self.rect.centerx
self.rect.centery = self.pos.y
for wall in pg.sprite.spritecollide(self, self.walls, False):
if self.vel.y > 0:
self.rect.bottom = wall.rect.top
self.vel.y = 0
elif self.vel.y < 0:
self.rect.top = wall.rect.bottom
self.vel.y = 0
self.pos.y = self.rect.centery
The collisions on the top of the platformer work, and the collisions on the side ALMOST always work, except for if I press the player against them then jump. If I try to hit the player on the bottom of the platform, it shoots me to either side of the platform. Any help?
Upvotes: 2
Views: 259
Reputation: 1267
I've found a working solution to this. The following code works very well.
def wall_collisions(self):
self.rect.centerx = self.pos.x
for wall in pg.sprite.spritecollide(self, self.walls, False):
if self.vel.x > 0:
self.rect.right = wall.rect.left
self.vel.x = 0
elif self.vel.x < 0:
self.rect.left = wall.rect.right
self.vel.x = 0
self.pos.x = self.rect.centerx
self.rect.centery = self.pos.y
for wall in pg.sprite.spritecollide(self, self.walls, False):
if self.vel.y > 0:
self.rect.bottom = wall.rect.top
self.vel.y = 0
elif self.vel.y < 0:
self.rect.top = wall.rect.bottom
self.vel.y = 0
self.pos.y = self.rect.centery
Upvotes: 0