Detecting walls or floors in pygame
- by Serial
I am trying to make bullets bounce of walls, but I can't figure out how to correctly do the collision detection. What I am currently doing is iterating through all the solid blocks and if the bullet hits the bottom, top or sides, its vector is adjusted accordingly. However, sometimes when I shoot, the bullet doesn't bounce, I think it's when I shoot at a border between two blocks.
Here is the update method for my Bullet class:
def update(self, dt):
if self.can_bounce:
#if the bullet hasnt bounced find its vector using the mousclick pos and player pos
speed = -10.
range = 200
distance = [self.mouse_x - self.player[0], self.mouse_y - self.player[1]]
norm = math.sqrt(distance[0] ** 2 + distance[1] ** 2)
direction = [distance[0] / norm, distance[1 ] / norm]
bullet_vector = [direction[0] * speed, direction[1] * speed]
self.dx = bullet_vector[0]
self.dy = bullet_vector[1]
#check each block for collision
for block in self.game.solid_blocks:
last = self.rect.copy()
if self.rect.colliderect(block):
topcheck = self.rect.top < block.rect.bottom and self.rect.top > block.rect.top
bottomcheck = self.rect.bottom > block.rect.top and self.rect.bottom < block.rect.bottom
rightcheck = self.rect.right > block.rect.left and self.rect.right < block.rect.right
leftcheck = self.rect.left < block.rect.right and self.rect.left > block.rect.left
each test tests if it hit the top bottom left or right side of the block its colliding with
if self.can_bounce:
if topcheck:
self.rect = last
self.dy *= -1
self.can_bounce = False
print "top"
if bottomcheck:
self.rect = last
self.dy *= -1 #Bottom check
self.can_bounce = False
print "bottom"
if rightcheck:
self.rect = last
self.dx *= -1 #right check
self.can_bounce = False
print "right"
if leftcheck:
self.rect = last
self.dx *= -1 #left check
self.can_bounce = False
print "left"
else:
# if it has already bounced and colliding again kill it
self.kill()
for enemy in self.game.enemies_list:
if self.rect.colliderect(enemy):
self.kill()
#update position
self.rect.x -= self.dx
self.rect.y -= self.dy
This definitely isn't the best way to do it but I can't think of another way. If anyone has done this or can help that would be awesome!