A clone of Asteroids.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

174 lines
5.2 KiB

#!/usr/bin/env python3
from sys import argv, exit
import pygame as pg
# locals
from .ship import Ship
from .starfield import Starfield
from .torpedo import Torpedo
from .asteroid import Asteroid
# Colors
BLACK = (0,)*3
WHITE = (255,)*3
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# Graphical Environment
WIN_SIZE = (1280, 960)
MAX_FPS = 60
## Game constants
N_ASTEROIDS_START = 3
# Sprite positions
start = (WIN_SIZE[0]//2,WIN_SIZE[1]//2)
## Setup
pg.init()
clock = pg.time.Clock()
pg.display.set_caption("Junk Space")
screen = pg.display.set_mode(WIN_SIZE)
scr_rect = screen.get_rect()
pg.mouse.set_cursor(pg.SYSTEM_CURSOR_CROSSHAIR)
map_rect = pg.Rect(
(start[0]-scr_rect.width/2,
start[1]-scr_rect.height/2),
scr_rect.size
)
font = pg.font.SysFont('Sans',24)
big_font = pg.font.SysFont('Sans',56)
the_starfield = Starfield(screen, grid_step=40, paralax=1);
while True:
# Game setup
start_time = pg.time.get_ticks()
the_ship = Ship(start,scr_rect)
the_ship.rect.x = scr_rect.centerx - the_ship.rect.width / 2
the_ship.rect.y = scr_rect.centery - the_ship.rect.height / 2
moving = pg.sprite.Group()
asteroids = pg.sprite.Group()
torpedoes = pg.sprite.Group()
for i in range(N_ASTEROIDS_START):
tmp = Asteroid(map_rect)
asteroids.add(tmp)
moving.add(tmp)
gun_cooldown = 0
win = False
lose = False
carry_on = True
# Game loop
while carry_on:
# Quitting states
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
exit()
elif event.type==pg.KEYDOWN:
if event.key==pg.K_ESCAPE:
pg.quit()
exit()
elif event.key == pg.K_r:
carry_on = False
if not (win or lose):
### Game Logic ###
mousev = pg.math.Vector2(pg.mouse.get_pos()) - scr_rect.center
keyboard_events = pg.key.get_pressed()
mouse_events = pg.mouse.get_pressed()
# ship direction
if mousev.length() > the_ship.SIZE/2:
the_ship.direction += mousev.normalize()
the_ship.direction.normalize_ip()
# Move ship
if keyboard_events[pg.K_SPACE]:
the_ship.velocity += the_ship.direction / 2
the_ship.map_pos.x += round(the_ship.velocity.x) % map_rect.w
the_ship.map_pos.y += round(the_ship.velocity.y) % map_rect.h
# Move camera to follow ship
map_rect.x = (the_ship.map_pos.x - map_rect.w/2) % map_rect.w
map_rect.y = (the_ship.map_pos.y - map_rect.h/2) % map_rect.h
# Torpedoes
if mouse_events[0] and gun_cooldown <= 0:
tmp = Torpedo(
scr_rect,
the_ship.map_pos,
the_ship.direction,
the_ship.velocity,
)
moving.add(tmp)
torpedoes.add(tmp)
gun_cooldown = Torpedo.COOLTIME
elif gun_cooldown > 0:
gun_cooldown -= 1
# Collisions
for an_asteroid in asteroids:
for a_torpedo in moving.sprites():
if an_asteroid.rect.colliderect(a_torpedo.rect):
if isinstance(a_torpedo, Torpedo):
a_torpedo.kill()
children = an_asteroid.breakup()
moving.add(children)
asteroids.add(children)
if an_asteroid.rect.colliderect(the_ship.rect):
lose = True
# Win state
if len([s for s in moving if isinstance(s, Asteroid)]) == 0:
win = True
### Display Logic ###
screen.fill(BLACK)
the_starfield.draw(screen, map_rect, (map_rect.w, map_rect.h))
moving.update(map_rect=map_rect)
moving.draw(screen)
the_ship.update(rot_vector= the_ship.direction)
screen.blit(the_ship.image, the_ship.rect)
if not (win or lose):
elapsed_time = (pg.time.get_ticks()-start_time)/1000
elapsed_minutes = int(elapsed_time // 60)
elapsed_seconds = int(elapsed_time // 1) % 60
time_string = f"{elapsed_minutes:d}:{elapsed_seconds:02d}"
time_label = font.render(time_string, 1, WHITE)
time_pos = (screen.get_width()-10-time_label.get_width(),10)
screen.blit(time_label, time_pos)
if win or lose:
if win:
big_label = big_font.render("You win!",1, GREEN, BLACK)
else:
big_label = big_font.render("You lose!",1, BLUE, BLACK)
big_pos = (
(screen.get_width()-big_label.get_width())/2,
(screen.get_height()-big_label.get_height())/2,
)
screen.blit(big_label, big_pos)
pg.display.flip()
clock.tick(MAX_FPS)