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
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(f"Space Collector")
|
|
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)
|
|
|
|
|