Here is what I have so far.
import pygame
import math
import random
pygame.init()
pygame.font.init()
clock = pygame.time.Clock()
infoObject = pygame.display.Info()
game_screen_x = infoObject.current_w - 50
game_screen_y = infoObject.current_h - 100
win = pygame.display.set_mode((game_screen_x, game_screen_y))
screen_center_x = int(game_screen_x / 2)
screen_center_y = int(game_screen_y / 2)
left_rand_location_x = 0
left_rand_location_y = 0
right_rand_location_x = 0
right_rand_location_y = 0
pygame.display.set_caption("SpaceDemoDerby")
# define colors
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
lightblue = (173, 216, 230)
grey = (87, 87, 87)
offwhite = (230, 230, 230)
# load images
back_ground = pygame.image.load('bg.png').convert()
pygame.transform.scale(back_ground, (game_screen_x, game_screen_y))
load_image_one = pygame.image.load('blueship.png').convert_alpha()
load_image_two = pygame.image.load('redship.png').convert_alpha()
load_image_one.set_colorkey(black)
load_image_two.set_colorkey(black)
ship_one_image = pygame.transform.scale(load_image_one, (32, 32))
ship_two_image = pygame.transform.scale(load_image_two, (32, 32))
explosion_anim = {}
explosion_anim['boom'] = []
for i in range(6):
filename = 'exp{}.png'.format(i)
img = pygame.image.load(filename).convert()
img.set_colorkey(black)
explosion_anim['boom'].append(img)
# load music and sound effects
music = pygame.mixer.music.load('unbreakable havoc redone.wav')
pygame.mixer.music.play(-1)
shoot_sound = pygame.mixer.Sound('Laser.wav')
explode_sound = pygame.mixer.Sound('Explosion.wav')
shield_sounds = []
for i in range(5):
filename = 'Metal_sounds_{}.wav'.format(i)
snd = pygame.mixer.Sound(filename)
shield_sounds.append(snd)
crash_sounds = []
for i in range(4):
filename = 'crash{}.wav'.format(i)
snd = pygame.mixer.Sound(filename)
crash_sounds.append(snd)
# starter variables
bullet_speed = 15
fd_fric = 0.5
bd_fric = 0.1
player_max_speed = 10
rotation_max_speed = 5
all_sprites = pygame.sprite.Group()
left_rnd_location_x = random.randint(25, (screen_center_x - 50))
left_rnd_location_y = random.randint(25, (screen_center_y - 50))
right_rnd_location_x = random.randint((screen_center_x + 50), (game_screen_x - 25))
right_rnd_location_y = random.randint((screen_center_y - 50), (game_screen_y - 25))
# fonts
font1 = pygame.font.SysFont('Arial', 20, True)
font2 = pygame.font.SysFont('Arial', 16)
font3 = pygame.font.SysFont('Arial', 28, True, True)
class explosion(pygame.sprite.Sprite):
def __init__(self, center, name):
pygame.sprite.Sprite.__init__(self)
self.name = name
self.image = explosion_anim[self.name][0]
self.rect = self.image.get_rect()
self.rect.center = center
self.frame = 0
self.last_update = pygame.time.get_ticks()
self.frame_rate = 60
def update(self):
now = pygame.time.get_ticks()
if now - self.last_update > self.frame_rate:
self.last_update = now
self.frame += 1
if self.frame == len(explosion_anim[self.name]):
self.kill()
else:
center = self.rect.center
self.image = explosion_anim[self.name][self.frame]
self.rect = self.image.get_rect()
self.rect.center = center
class bullet(object):
def __init__(self, x, y, dir, color):
self.x = x
self.y = y
self.dir = dir
self.color = color
self.life = 60
def updatebullet(self):
self.x += bullet_speed * math.cos((self.dir + 90) * math.pi / 180)
self.y += bullet_speed * -math.sin((self.dir + 90) * math.pi / 180)
pygame.draw.circle(win, self.color, (int(self.x), int(self.y)), 3)
self.life -= 1
class spaceship(object):
def __init__(self, x_move, y_move, width, height, rot, image):
self.x_move = x_move
self.y_move = y_move
self.width = width
self.height = height
self.rot_angle = rot
self.vel = 0
self.hspeed = 0
self.vspeed = 0
self.thrust = False
self.rotated = False
self.fired_shots_delay = 10
self.image = image
self.image_list = []
self.rot_angle_index = 0
self.shield = 100
self.visable = True
self.score = 0
for i in range(72):
holder = pygame.transform.rotozoom(self.image, i * 5, 1)
self.image_list.append(holder)
def propulsion(self): # from asteroids
speed = math.sqrt(self.hspeed ** 2 + self.vspeed ** 2)
if self.thrust:
if speed + fd_fric < player_max_speed:
self.hspeed += fd_fric * math.cos((self.rot_angle + 90) * math.pi / 180)
self.vspeed += fd_fric * -math.sin((self.rot_angle + 90) * math.pi / 180)
else:
self.hspeed = player_max_speed * math.cos((self.rot_angle + 90) * math.pi / 180)
self.vspeed = player_max_speed * -math.sin((self.rot_angle + 90) * math.pi / 180)
else:
if speed - bd_fric > 0:
change_in_hspeed = (bd_fric * math.cos(self.vspeed / self.hspeed))
change_in_vspeed = (bd_fric * math.sin(self.vspeed / self.hspeed))
if self.hspeed != 0:
if change_in_hspeed / abs(change_in_hspeed) == self.hspeed / abs(self.hspeed):
self.hspeed -= change_in_hspeed
else:
self.hspeed += change_in_hspeed
if self.vspeed != 0:
if change_in_vspeed / abs(change_in_vspeed) == self.vspeed / abs(self.vspeed):
self.vspeed -= change_in_vspeed
else:
self.vspeed += change_in_vspeed
else:
self.hspeed = 0
self.vspeed = 0
self.x_move += self.hspeed
self.y_move += self.vspeed
def ship_draw(self, win, list, angle):
if self.rot_angle <= -360 or self.rot_angle >= 360:
self.rot_angle = self.rot_angle - (360 * (self.rot_angle // 360))
self.rot_angle_index = self.rot_angle // 5
if self.visable:
win.blit(self.image_list[self.rot_angle_index], (self.x_move - int(self.image_list[self.rot_angle_index].get_width() / 2), self.y_move - int(
self.image_list[self.rot_angle_index].get_height() / 2)))
print (self.rot_angle, self.rot_angle_index)
else:
self.reset()
win.blit(self.image_list[self.rot_angle_index],
(self.x_move - int(self.image_list[self.rot_angle_index].get_width() / 2), self.y_move - int(
self.image_list[self.rot_angle_index].get_height() / 2)))
# screen wrap
if self.x_move > game_screen_x:
self.x_move = 0
elif self.x_move < 0:
self.x_move = game_screen_x
elif self.y_move > game_screen_y:
self.y_move = 40
elif self.y_move < 40:
self.y_move = game_screen_y
def hitship(self):
if self.shield > 0:
self.shield -= 10
if self.shield < 0:
self.shield = 0
random.choice(shield_sounds).play()
def reset(self):
if not ship_one.visable:
self.x_move = random.randint(25, (screen_center_x - 50))
self.y_move = random.randint(50, (game_screen_y - 25))
if not ship_two.visable:
self.x_move = random.randint((screen_center_x + 50), (game_screen_x - 25))
self.y_move = random.randint(50, (game_screen_y - 25))
self.rot_angle = 0
self.hspeed = 0
self.vspeed = 0
self.thrust = False
self.rotated = False
self.visable = True
ship_one.shield = 100
ship_two.shield = 100
def shipscollide(rect_one, rect_two):
c_tolerance = 10
ship_one.thrust = False
ship_two.thrust = False
if abs(rect_two.top - rect_one.bottom) < c_tolerance:
if ship_one.hspeed > 0 or ship_two.hspeed < 0:
ship_one.vspeed *= -1
ship_two.vspeed *= -1
if abs(rect_two.bottom - rect_one.top) < c_tolerance:
if ship_one.hspeed < 0 or ship_two.hspeed > 0:
ship_one.vspeed *= -1
ship_two.vspeed *= -1
if abs(rect_two.right - rect_one.left) < c_tolerance:
if ship_one.hspeed < 0 or ship_two.hspeed > 0:
ship_one.hspeed *= -1
ship_two.hspeed *= -1
if abs(rect_two.left - rect_one.right) < c_tolerance:
if ship_one.hspeed > 0 or ship_two.hspeed < 0:
ship_one.hspeed *= -1
ship_two.hspeed *= -1
if abs(rect_two.top - rect_one.left) < c_tolerance:
if ship_one.hspeed > 0 or ship_two.hspeed < 0:
ship_one.vspeed *= -1
ship_two.vspeed *= -1
if abs(rect_two.bottom - rect_one.right) < c_tolerance:
if ship_one.hspeed < 0 or ship_two.hspeed > 0:
ship_one.vspeed *= -1
ship_two.vspeed *= -1
if abs(rect_two.right - rect_one.top) < c_tolerance:
if ship_one.hspeed < 0 or ship_two.hspeed > 0:
ship_one.hspeed *= -1
ship_two.hspeed *= -1
if abs(rect_two.left - rect_one.bottom) < c_tolerance:
if ship_one.hspeed > 0 or ship_two.hspeed < 0:
ship_one.hspeed *= -1
ship_two.hspeed *= -1
if abs(rect_two.top - rect_one.top) < c_tolerance:
if ship_one.hspeed > 0 or ship_two.hspeed < 0:
ship_one.vspeed *= -1
ship_two.vspeed *= -1
if abs(rect_two.bottom - rect_one.bottom) < c_tolerance:
if ship_one.hspeed < 0 or ship_two.hspeed > 0:
ship_one.vspeed *= -1
ship_two.vspeed *= -1
if abs(rect_two.right - rect_one.right) < c_tolerance:
if ship_one.hspeed < 0 or ship_two.hspeed > 0:
ship_one.hspeed *= -1
ship_two.hspeed *= -1
if abs(rect_two.left - rect_one.left) < c_tolerance:
if ship_one.hspeed > 0 or ship_two.hspeed < 0:
ship_one.hspeed *= -1
ship_two.hspeed *= -1
if abs(rect_two.bottom - rect_one.left) < c_tolerance:
if ship_one.hspeed > 0 or ship_two.hspeed < 0:
ship_one.vspeed *= -1
ship_two.vspeed *= -1
if abs(rect_two.top - rect_one.right) < c_tolerance:
if ship_one.hspeed < 0 or ship_two.hspeed > 0:
ship_one.vspeed *= -1
ship_two.vspeed *= -1
if abs(rect_two.right - rect_one.bottom) < c_tolerance:
if ship_one.hspeed < 0 or ship_two.hspeed > 0:
ship_one.hspeed *= -1
ship_two.hspeed *= -1
if abs(rect_two.left - rect_one.top) < c_tolerance:
if ship_one.hspeed > 0 or ship_two.hspeed < 0:
ship_one.hspeed *= -1
ship_two.hspeed *= -1
impact_damage = [2, 5, 10]
if ship_one.shield > 0:
ship_one.shield -= random.choice(impact_damage)
if ship_one.shield < 0:
ship_one.shield = 0
if ship_two.shield > 0:
ship_two.shield -= random.choice(impact_damage)
if ship_two.shield < 0:
ship_two.shield = 0
random.choice(crash_sounds).play()
def collision(bx, by, sx, sy, size):
if bx > sx - size and bx < sx + size and by > sy - size and by < sy + size:
return True
return False
def status_bar():
# background bar
pygame.draw.rect(win, grey, (0, 0, game_screen_x, 45))
#Title
title_text = font3.render('SPACE DEMO DERBY', True, black)
win.blit(title_text, (800, 10))
# score
score1_text = font1.render('Red Ships Destroyed: ' + str(ship_one.score), True, offwhite)
score2_text = font1.render('Blue Ships Destroyed: ' + str(ship_two.score), True, offwhite)
win.blit(score1_text, (410, 10))
win.blit(score2_text, (game_screen_x - 648, 10))
# shield health bars
shield1_text = font2.render('SHIELD INTEGRITY', True, offwhite)
win.blit(shield1_text, (245, 15))
win.blit(shield1_text, (game_screen_x - 395, 15))
pygame.draw.rect(win, red, (40, 15, 200, 15))
pygame.draw.rect(win, red, (game_screen_x - 240, 15, 200, 15))
pygame.draw.rect(win, green, (40, 15, 200 - (2 * (100 - ship_one.shield)), 15))
pygame.draw.rect(win, green, (game_screen_x - 240, 15, 200 - (2 * (100 - ship_two.shield)), 15))
def clear_screen():
win.fill((0, 0, 0))
win.blit(back_ground, (0, 0))
# create a spaceship
ship_one = spaceship(left_rnd_location_x, left_rnd_location_y, 32, 32, 0, ship_one_image)
ship_two = spaceship(right_rnd_location_x, right_rnd_location_y, 32, 32, 0, ship_two_image)
# initial variables
s1_fired_shots = []
s2_fired_shots = []
fired_shots_cap = 10
shot_delay_constant = 10
run = True
# main loop
while run:
clock.tick(80)
for shot in s1_fired_shots:
if shot.life == 0:
s1_fired_shots.pop(s1_fired_shots.index(shot))
for shot in s2_fired_shots:
if shot.life == 0:
s2_fired_shots.pop(s2_fired_shots.index(shot))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_e:
ship_one.thrust = True
if event.key == pygame.K_KP8:
ship_two.thrust = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_e:
ship_one.thrust = False
if event.key == pygame.K_KP8:
ship_two.thrust = False
keys = pygame.key.get_pressed()
if keys[pygame.K_f]: # CW rotation
ship_one.rot_angle -= rotation_max_speed
if keys[pygame.K_KP6]:
ship_two.rot_angle -= rotation_max_speed
if keys[pygame.K_s]: #CCW rotation
ship_one.rot_angle += rotation_max_speed
if keys[pygame.K_KP4]:
ship_two.rot_angle += rotation_max_speed
if keys[pygame.K_TAB] and len(s1_fired_shots) < fired_shots_cap:
if ship_one.fired_shots_delay == 0:
s1_fired_shots.append(bullet(ship_one.x_move, ship_one.y_move, ship_one.rot_angle, lightblue))
# shoot_sound.play()
ship_one.fired_shots_delay = shot_delay_constant
else:
ship_one.fired_shots_delay -= 1
if keys[pygame.K_RETURN] and len(s2_fired_shots) < fired_shots_cap:
if ship_two.fired_shots_delay == 0:
s2_fired_shots.append(bullet(ship_two.x_move, ship_two.y_move, ship_two.rot_angle, red))
# shoot_sound.play()
ship_two.fired_shots_delay = shot_delay_constant
else:
ship_two.fired_shots_delay -= 1
clear_screen()
# movement
ship_one.propulsion()
ship_two.propulsion()
all_sprites.update()
# check for bullet hits
for shot in s1_fired_shots:
shot.updatebullet()
if ship_two.visable:
if collision(shot.x, shot.y, ship_two.x_move, ship_two.y_move, 32):
ship_two.hitship()
s1_fired_shots.pop(s1_fired_shots.index(shot))
if ship_two.shield <= 0:
tmp = pygame.Rect(ship_two.x_move, ship_two.y_move, 32, 32)
exp = explosion(tmp.topleft, 'boom')
explode_sound.play()
all_sprites.add(exp)
ship_two.visable = False
ship_one.score += 1
for shot in s2_fired_shots:
shot.updatebullet()
if ship_one.visable:
if collision(shot.x, shot.y, ship_one.x_move, ship_one.y_move, 32):
ship_one.hitship()
s2_fired_shots.pop(s2_fired_shots.index(shot))
if ship_one.shield <= 0:
tmp = pygame.Rect(ship_one.x_move, ship_one.y_move, 32, 32)
exp = explosion(tmp.topleft, 'boom')
explode_sound.play()
all_sprites.add(exp)
ship_one.visable = False
ship_two.score += 1
# check for ship collisions
if ship_one.visable and ship_two.visable:
tmp1 = pygame.Rect(ship_one.x_move, ship_one.y_move, 32, 32)
tmp2 = pygame.Rect(ship_two.x_move, ship_two.y_move, 32, 32)
# if collision(ship_one.x_move, ship_one.y_move,ship_two.x_move, ship_two.y_move, 24):
# shipscollide(tmp1, tmp2)
if tmp1.colliderect(tmp2):
shipscollide(tmp1, tmp2)
if ship_two.shield <= 0:
tmp = pygame.Rect(ship_two.x_move, ship_two.y_move, 32, 32)
exp = explosion(tmp.topleft, 'boom')
explode_sound.play()
all_sprites.add(exp)
ship_two.visable = False
ship_one.score += 1
if ship_one.shield <= 0:
tmp = pygame.Rect(ship_one.x_move, ship_one.y_move, 32, 32)
exp = explosion(tmp.topleft, 'boom')
explode_sound.play()
all_sprites.add(exp)
ship_one.visable = False
ship_two.score += 1
# draw new positions
ship_one.ship_draw(win, ship_one.image_list, ship_one.rot_angle)
ship_two.ship_draw(win, ship_two.image_list, ship_two.rot_angle)
status_bar()
all_sprites.draw(win)
pygame.display.flip()
pygame.quit()