the game is gamin
This commit is contained in:
31
asteroid.py
Normal file
31
asteroid.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import random
|
||||
import pygame
|
||||
from circleshape import CircleShape
|
||||
from constants import ASTEROID_MIN_RADIUS
|
||||
|
||||
class Asteroid(CircleShape):
|
||||
def __init__(self, x, y, radius):
|
||||
super().__init__(x, y, radius)
|
||||
|
||||
def draw(self, screen):
|
||||
pygame.draw.circle(screen, "white", self.position, self.radius, 2)
|
||||
|
||||
def update(self, dt):
|
||||
self.position += self.velocity * dt
|
||||
|
||||
def split(self):
|
||||
self.kill()
|
||||
if self.radius <= ASTEROID_MIN_RADIUS:
|
||||
return
|
||||
|
||||
new_angle = random.uniform(20,50)
|
||||
new_velocity_1 = self.velocity.rotate(new_angle)
|
||||
new_velocity_2 = self.velocity.rotate(-new_angle)
|
||||
|
||||
new_radius = self.radius - ASTEROID_MIN_RADIUS
|
||||
|
||||
new_asteroid_1 = Asteroid(self.position[0], self.position[1], new_radius)
|
||||
new_asteroid_2 = Asteroid(self.position[0], self.position[1], new_radius)
|
||||
|
||||
new_asteroid_1.velocity = new_velocity_1 * 1.2
|
||||
new_asteroid_2.velocity = new_velocity_2 * 1.2
|
||||
52
asteroidfield.py
Normal file
52
asteroidfield.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import pygame
|
||||
import random
|
||||
from asteroid import Asteroid
|
||||
from constants import *
|
||||
|
||||
|
||||
class AsteroidField(pygame.sprite.Sprite):
|
||||
edges = [
|
||||
[
|
||||
pygame.Vector2(1, 0),
|
||||
lambda y: pygame.Vector2(-ASTEROID_MAX_RADIUS, y * SCREEN_HEIGHT),
|
||||
],
|
||||
[
|
||||
pygame.Vector2(-1, 0),
|
||||
lambda y: pygame.Vector2(
|
||||
SCREEN_WIDTH + ASTEROID_MAX_RADIUS, y * SCREEN_HEIGHT
|
||||
),
|
||||
],
|
||||
[
|
||||
pygame.Vector2(0, 1),
|
||||
lambda x: pygame.Vector2(x * SCREEN_WIDTH, -ASTEROID_MAX_RADIUS),
|
||||
],
|
||||
[
|
||||
pygame.Vector2(0, -1),
|
||||
lambda x: pygame.Vector2(
|
||||
x * SCREEN_WIDTH, SCREEN_HEIGHT + ASTEROID_MAX_RADIUS
|
||||
),
|
||||
],
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
pygame.sprite.Sprite.__init__(self, self.containers)
|
||||
self.spawn_timer = 0.0
|
||||
|
||||
def spawn(self, radius, position, velocity):
|
||||
asteroid = Asteroid(position.x, position.y, radius)
|
||||
asteroid.velocity = velocity
|
||||
|
||||
def update(self, dt):
|
||||
self.spawn_timer += dt
|
||||
if self.spawn_timer > ASTEROID_SPAWN_RATE:
|
||||
self.spawn_timer = 0
|
||||
|
||||
# spawn a new asteroid at a random edge
|
||||
edge = random.choice(self.edges)
|
||||
speed = random.randint(40, 100)
|
||||
velocity = edge[0] * speed
|
||||
velocity = velocity.rotate(random.randint(-30, 30))
|
||||
position = edge[1](random.uniform(0, 1))
|
||||
kind = random.randint(1, ASTEROID_KINDS)
|
||||
self.spawn(ASTEROID_MIN_RADIUS * kind, position, velocity)
|
||||
|
||||
25
circleshape.py
Normal file
25
circleshape.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import pygame
|
||||
|
||||
# Base class for game objects
|
||||
class CircleShape(pygame.sprite.Sprite):
|
||||
def __init__(self, x, y, radius):
|
||||
# we will be using this later
|
||||
if hasattr(self, "containers"):
|
||||
super().__init__(self.containers)
|
||||
else:
|
||||
super().__init__()
|
||||
|
||||
self.position = pygame.Vector2(x, y)
|
||||
self.velocity = pygame.Vector2(0, 0)
|
||||
self.radius = radius
|
||||
|
||||
def draw(self, screen):
|
||||
# sub-classes must override
|
||||
pass
|
||||
|
||||
def update(self, dt):
|
||||
# sub-classes must override
|
||||
pass
|
||||
|
||||
def colission(self, circle):
|
||||
return self.position.distance_to(circle.position) <= (self.radius + circle.radius)
|
||||
@@ -1,6 +1,14 @@
|
||||
SCREEN_WIDTH = 1280
|
||||
SCREEN_HEIGHT = 720
|
||||
|
||||
PLAYER_RADIUS = 20
|
||||
PLAYER_SPEED = 20
|
||||
PLAYER_TURN_SPEED = 300
|
||||
PLAYER_SHOT_SPEED = 500
|
||||
PLAYER_SHOOT_COOLDOWN = 0.3
|
||||
|
||||
SHOT_RADIUS = 5
|
||||
|
||||
ASTEROID_MIN_RADIUS = 20
|
||||
ASTEROID_KINDS = 3
|
||||
ASTEROID_SPAWN_RATE = 0.8 # seconds
|
||||
|
||||
39
main.py
39
main.py
@@ -1,8 +1,13 @@
|
||||
# this allows us to use code from
|
||||
# the open-source pygame library
|
||||
# throughout this file
|
||||
import sys
|
||||
import pygame
|
||||
from constants import *
|
||||
from player import *
|
||||
from asteroid import *
|
||||
from asteroidfield import *
|
||||
from shot import *
|
||||
|
||||
def main():
|
||||
print("Starting Asteroids!")
|
||||
@@ -13,13 +18,47 @@ def main():
|
||||
#set screen resolution
|
||||
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
|
||||
|
||||
clock = pygame.time.Clock()
|
||||
dt = 0
|
||||
|
||||
#groups
|
||||
updatable = pygame.sprite.Group()
|
||||
drawable = pygame.sprite.Group()
|
||||
asteroids = pygame.sprite.Group()
|
||||
shots = pygame.sprite.Group()
|
||||
|
||||
Player.containers = (updatable, drawable)
|
||||
Asteroid.containers = (updatable, drawable, asteroids)
|
||||
AsteroidField.containers = (updatable)
|
||||
Shot.containers = (updatable, drawable, shots)
|
||||
|
||||
player = Player(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)
|
||||
asteroidfield = AsteroidField()
|
||||
|
||||
while True:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
return
|
||||
|
||||
updatable.update(dt)
|
||||
|
||||
for a in asteroids:
|
||||
if a.colission(player):
|
||||
print("Game Over!")
|
||||
sys.exit()
|
||||
for s in shots:
|
||||
if a.colission(s):
|
||||
a.split()
|
||||
s.kill()
|
||||
|
||||
screen.fill((0,0,0))
|
||||
|
||||
for d in drawable:
|
||||
d.draw(screen)
|
||||
|
||||
|
||||
pygame.display.flip()
|
||||
dt = clock.tick(60) / 1000
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
57
player.py
Normal file
57
player.py
Normal file
@@ -0,0 +1,57 @@
|
||||
import pygame
|
||||
from constants import PLAYER_RADIUS, PLAYER_TURN_SPEED, PLAYER_SPEED, PLAYER_SHOT_SPEED, PLAYER_SHOOT_COOLDOWN
|
||||
from circleshape import CircleShape
|
||||
from shot import Shot
|
||||
|
||||
class Player(CircleShape):
|
||||
def __init__(self, x, y):
|
||||
super().__init__(x, y, PLAYER_RADIUS)
|
||||
self.rotation = 0
|
||||
self.shot_cooldown_counter = 0
|
||||
|
||||
def draw(self, screen):
|
||||
pygame.draw.polygon(screen, "white", self.triangle(), 2)
|
||||
|
||||
def update(self, dt):
|
||||
self.shot_cooldown_counter -= dt
|
||||
|
||||
keys = pygame.key.get_pressed()
|
||||
|
||||
if keys[pygame.K_a]:
|
||||
self.rotate(-dt)
|
||||
|
||||
if keys[pygame.K_d]:
|
||||
self.rotate(dt)
|
||||
|
||||
if keys[pygame.K_w]:
|
||||
self.move(dt)
|
||||
|
||||
if keys[pygame.K_s]:
|
||||
self.move(-dt)
|
||||
|
||||
if keys[pygame.K_SPACE]:
|
||||
self.shoot()
|
||||
|
||||
|
||||
def rotate(self, dt):
|
||||
self.rotation += PLAYER_TURN_SPEED * dt
|
||||
|
||||
def move(self, dt):
|
||||
forward = pygame.Vector2(0, 1).rotate(self.rotation)
|
||||
self.position += forward * PLAYER_SPEED * dt
|
||||
|
||||
def shoot(self):
|
||||
if self.shot_cooldown_counter > 0:
|
||||
return
|
||||
shot = Shot(self.position[0], self.position[1])
|
||||
shot.velocity = pygame.Vector2(0, 1).rotate(self.rotation) * PLAYER_SHOT_SPEED
|
||||
self.shot_cooldown_counter = PLAYER_SHOOT_COOLDOWN
|
||||
|
||||
|
||||
def triangle(self):
|
||||
forward = pygame.Vector2(0, 1).rotate(self.rotation)
|
||||
right = pygame.Vector2(0, 1).rotate(self.rotation + 90) * self.radius / 1.5
|
||||
a = self.position + forward * self.radius
|
||||
b = self.position - forward * self.radius - right
|
||||
c = self.position - forward * self.radius + right
|
||||
return [a, b, c]
|
||||
14
shot.py
Normal file
14
shot.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import pygame
|
||||
from circleshape import CircleShape
|
||||
from constants import SHOT_RADIUS
|
||||
|
||||
class Shot(CircleShape):
|
||||
def __init__(self, x, y):
|
||||
super().__init__(x, y, SHOT_RADIUS)
|
||||
self.rotation = 0
|
||||
|
||||
def draw(self, screen):
|
||||
pygame.draw.circle(screen, "white", self.position, self.radius, 2)
|
||||
|
||||
def update(self, dt):
|
||||
self.position += self.velocity * dt
|
||||
Reference in New Issue
Block a user