Skip to content

Commit

Permalink
Add code for collisions and explosions
Browse files Browse the repository at this point in the history
This does the dumbest thing. Collision is on rects. The debris
explodes mostly logically (some bug in generating new particles)
  • Loading branch information
BrettWitty committed Jan 12, 2020
1 parent 9ca6372 commit ece2703
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 7 deletions.
25 changes: 22 additions & 3 deletions asteroids.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ def spawn_bullet(ship, rng, objects):

def spawn_asteroid(ship, rng, objects, *, pos=None, size=None, num=1):

if size != None and size < 0:
return

if not pos:

# Get a random position in the space (away from the ship)
Expand All @@ -23,9 +26,11 @@ def spawn_asteroid(ship, rng, objects, *, pos=None, size=None, num=1):

cx += r*np.cos(theta)
cy += r*np.sin(theta)
max_vel = 0.01

else:
cx,cy = pos
max_vel = 0.5

for i in range(num):

Expand All @@ -36,15 +41,15 @@ def spawn_asteroid(ship, rng, objects, *, pos=None, size=None, num=1):
theta = 2*constants.PI * rng.random()
x = r*np.cos(theta) + cx
y = r*np.sin(theta) + cy
vx = (2*rng.random() -1) * 0.01
vy = (2*rng.random() -1) * 0.01
vx = (2*rng.random() -1) * max_vel
vy = (2*rng.random() -1) * max_vel
omega = (2*rng.random() -1) * 0.1
objects.add( Debris(size=size, x=x, y=y, vx=vx, vy=vy, omega=omega))


def main():

pygame.init()
pygame.mixer.init()

pygame.display.set_caption('BWasteroids')
screen = pygame.display.set_mode((constants.SCREEN_WIDTH,constants.SCREEN_HEIGHT), flags=pygame.SCALED)
Expand Down Expand Up @@ -126,6 +131,20 @@ def main():

# Simulate()
objects.update(tick)

# Check for collisions
collisions = pygame.sprite.groupcollide(objects, objects, False, False)

for c1 in collisions:
for c2 in collisions[c1]:
if c1 in objects and c2 in objects:
if c1 != c2:
if isinstance(c1, Bullet) and isinstance(c2, Debris):
objects.remove(c2)
spawn_asteroid(ship, rng, objects, pos=(c2.x, c2.y), size=(c2.size-1), num=rng.integers(1,4))
c2.kill()
del c2
objects.remove(c1)

# render()
rects = objects.draw(screen)
Expand Down
6 changes: 6 additions & 0 deletions bullet.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class Bullet(physics.PhysicsObject):

def __init__(self, ship):

self.name = 'Bullet'

d = constants.BULLET_SPAWN_RADIUS
x = ship.x + d*np.cos(constants.DEG_TO_RAD*ship.angle)
y = ship.y + d*np.sin(constants.DEG_TO_RAD*ship.angle)
Expand All @@ -22,6 +24,10 @@ def __init__(self, ship):
self.rect = pygame.Rect(x,y,5,5)
self.visible = 1

col_surface = self.image.copy()
pygame.draw.circle(col_surface, pygame.Color("white"), col_surface.get_rect().center, 2, 0)
self.mask = pygame.mask.from_surface(col_surface)

self.base_color = pygame.Color("#adff2fff")
self.life = constants.FIRE_LIFETIME

Expand Down
24 changes: 20 additions & 4 deletions debris.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ def __init__(self, size, x=0.0, y=0.0, vx=0.0, vy=0.0, angle=90.0, omega=0.0):

super().__init__(x=x, y=y, vx=vx, vy=vy, angle=angle)

self.name = "Debris"

self.omega = omega

self.size = size
Expand All @@ -20,15 +22,25 @@ def __init__(self, size, x=0.0, y=0.0, vx=0.0, vy=0.0, angle=90.0, omega=0.0):
self.image = pygame.Surface([px,px], flags=pygame.SRCALPHA)
self.rect = pygame.Rect(x,y,px,px)
self.visible = 1

self.base_images = [ pygame.Surface([px,px], flags=pygame.SRCALPHA) for i in range(360) ]
self.mask = None
self.collision_masks = [ None for i in range(360) ]

self.init_base_image(px)

self.explosion_sound = pygame.mixer.Sound("sounds/explosion.wav")
self.explosion_channel = pygame.mixer.Channel(constants.EXPLOSION_CHANNEL)

def kill(self):

if not self.explosion_channel.get_busy():
self.explosion_channel.play(self.explosion_sound, loops=0)

def init_base_image(self, px):

# Creates the initial images and the collision masks

# Pick 3 vertices of a 16-gon. Pull them into the center
NUM_DENTS = 4
NUM_PIECES = 15
Expand Down Expand Up @@ -59,15 +71,19 @@ def init_base_image(self, px):

pts.append( (x,y) )

pygame.draw.aalines(self.base_images[n], pygame.Color("#bc8f8fff"), True, pts)
pygame.draw.aalines(self.base_images[n], pygame.Color("#bc8f8fff"), True, pts)
#pygame.draw.aalines(self.base_images[n], pygame.Color("#bc8f8fff"), True, pts)
#pygame.draw.aalines(self.base_images[n], pygame.Color("#bc8f8fff"), True, pts)
pygame.draw.polygon(self.base_images[n], pygame.Color("#d2b48cff"), pts, 0)
self.collision_masks[n] = pygame.mask.from_surface(self.base_images[n])

def update(self, tick):

super().update(tick)

self.angle += self.omega * tick

self.image = self.base_images[ int(np.round(self.angle)) % 360 ]
idx = int(np.round(self.angle)) % 360
self.image = self.base_images[ idx ]
self.mask = self.collision_masks[idx]

self.dirty = 1
4 changes: 4 additions & 0 deletions physics.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ def __init__(self, x=0.0, y=0.0, vx=0.0, vy=0.0, angle=0):

pygame.sprite.DirtySprite.__init__(self)

self.name = 'N/A'

self.x = x
self.y = y
self.vx = vx
self.vy = vy
self.angle = angle

self.mask = None

def update(self, tick):

self.x += self.vx * tick/1000.0
Expand Down
2 changes: 2 additions & 0 deletions ship.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ def __init__(self, x=0.0, y=0.0, vx=0.0, vy=0.0, angle=90.0):

super().__init__(x=x, y=y, vx=vx, vy=vy, angle=angle)

self.name = 'Ship'

self.lives = 3

self.firing = False
Expand Down

0 comments on commit ece2703

Please sign in to comment.