I've been working on collisions in Pygame and the issue is that when the player moves lands of the top of the tile they are immediately blitted onto either the left or the right. How would I make it so that it the player lands on top of the platform that they aren't blitted to the left or the right? In the code below between the lines of ////// is where the collision issues seems to be occurring.
import pygame
pygame.init()
pygame.mixer.init()
clock = pygame.time.Clock()
running = True
# game properties
WIDTH = 800
HEIGHT = 600
FPS = 60
# colors
BLACK = (0, 0, 0)
BLUE = (0, 255, 255)
GREEN = (0, 255, 0)
# physics
GRAVITY = 0.3
ACCEL = 1
FRICTION = -0.12
window = pygame.display.set_mode((WIDTH, HEIGHT))
# Platform properties
SMALL = (100, 50)
MEDIUM = (20000, 200)
GROUND = (100000, 100)
vec = pygame.math.Vector2
class Sonic(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT - 51)
self.pos = vec(WIDTH / 2 , HEIGHT - 51)
self.vel = vec(0, 0)
self.acc = vec(0, 0)
self.last_update = 0
self.time_passed = 0
def update(self):
self.acc = vec(0, GRAVITY)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.acc.x = -ACCEL - 2
if keys[pygame.K_RIGHT]:
self.acc.x = ACCEL
if keys[pygame.K_UP]:
self.acc.y = -ACCEL
# friction check
self.acc.x += self.vel.x * FRICTION
if self.vel.x < -2:
self.vel.x = -2
# equations of motion
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
self.rect.midbottom = self.pos
class Ground(pygame.sprite.Sprite):
def __init__(self, x, y, plat):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((GROUND))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, plat):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((plat))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
# player sprites
s = Sonic()
# floor sprites
ground = Ground(0, HEIGHT - 50, GROUND)
floor = pygame.sprite.Group()
floor.add(ground)
# platform sprites
platforms = [Platform(WIDTH - 200, HEIGHT - 100, SMALL)]
plats = pygame.sprite.Group()
for i in platforms:
plats.add(i)
# all sprites
sprites = pygame.sprite.Group()
sprites.add(s)
sprites.add(plats)
sprites.add(ground)
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# update
sprites.update()
if s.vel.y > 0:
collisions = pygame.sprite.spritecollide(s, floor, False)
if collisions:
for collision in collisions:
if s.pos.y > collision.rect.top:
s.pos.y = collision.rect.top
s.rect.bottom = s.pos.y
s.vel.y = 0
"""
where the collision issue seems to be happening (CODE BELOW)
"""
////////////////////////////////////////////////////////////////////////////////////////////////////////
if s.vel.x > 0:
hits = pygame.sprite.spritecollide(s, plats, False)
if hits:
for hit in hits:
if s.pos.x > hit.rect.left:
s.pos.x = (hit.rect.left - (s.rect.width / 2) - 1)
s.rect.right = s.pos.x
s.vel.x = 0
if s.vel.x < 0:
hits = pygame.sprite.spritecollide(s, plats, False)
if hits:
for hit in hits:
if s.pos.x < hit.rect.right:
s.pos.x = (hit.rect.right + (s.rect.width / 2) + 1)
s.rect.left = s.pos.x
s.vel.x = 0
"""
when player lands on a tile they are blitted to either side of the tile (how do I fix this?)
"""
if s.vel.y > 0:
hits = pygame.sprite.spritecollide(s, plats, False)
if hits:
for hit in hits:
if s.pos.y > hit.rect.top:
s.pos.x = (hit.rect.top - (s.rect.width / 2) + 1)
s.rect.bottom = s.pos.y
s.vel.x = 0
////////////////////////////////////////////////////////////////////////////////////////////////////////
# draw
window.fill(BLACK)
sprites.draw(window)
# double buffering
pygame.display.flip()