Spaceinvader v1
BIN
pygame/space_invaders/source/assets/background.jpg
Normal file
|
After Width: | Height: | Size: 274 KiB |
BIN
pygame/space_invaders/source/assets/images/explosionblue.png
Normal file
|
After Width: | Height: | Size: 272 B |
BIN
pygame/space_invaders/source/assets/images/explosiongreen.png
Normal file
|
After Width: | Height: | Size: 287 B |
BIN
pygame/space_invaders/source/assets/images/explosionpurple.png
Normal file
|
After Width: | Height: | Size: 272 B |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 692 B |
|
After Width: | Height: | Size: 706 B |
|
After Width: | Height: | Size: 743 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 842 B |
BIN
pygame/space_invaders/source/assets/sprites/enemies/mystery.png
Normal file
|
After Width: | Height: | Size: 299 B |
|
After Width: | Height: | Size: 159 B |
|
After Width: | Height: | Size: 80 B |
BIN
pygame/space_invaders/source/assets/sprites/playership.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
pygame/space_invaders/source/fonts/space_invaders.ttf
Normal file
257
pygame/space_invaders/source/space_invaders.py
Normal file
@ -0,0 +1,257 @@
|
||||
# Author - Kristiāns Francis Cagulis
|
||||
# Date - 06.03.2022
|
||||
# Title - Space invaders
|
||||
# TODO: Add score system
|
||||
# TODO: Add enemy movement in groups
|
||||
|
||||
import pygame
|
||||
from random import randrange, choice
|
||||
from os.path import abspath, dirname, join
|
||||
|
||||
WIDTH, HEIGHT = 800, 800
|
||||
|
||||
WINDOW = pygame.display.set_mode((WIDTH, HEIGHT))
|
||||
pygame.display.set_caption("Space Invaders")
|
||||
pygame.font.init()
|
||||
|
||||
# paths
|
||||
BASE_PATH = abspath(dirname(__file__))
|
||||
SPRITE_PATH = join(BASE_PATH, "assets", "sprites")
|
||||
ENEMY_PATH = join(SPRITE_PATH, "enemies")
|
||||
FONT = join(BASE_PATH, "fonts", "space_invaders.ttf")
|
||||
|
||||
# load sprites
|
||||
SPACESHIP = pygame.image.load(join(SPRITE_PATH, "playership.png")) # player
|
||||
PLAYER_MISSILE = pygame.image.load(join(SPRITE_PATH, "missiles", "playermissile.png")) # player missile
|
||||
|
||||
# enemies
|
||||
ENEMY_1 = pygame.transform.scale(pygame.image.load(join(ENEMY_PATH, "enemy1", "enemy1_1.png")), (40, 35))
|
||||
ENEMY_2 = pygame.transform.scale(pygame.image.load(join(ENEMY_PATH, "enemy2", "enemy2_1.png")), (40, 35))
|
||||
ENEMY_3 = pygame.transform.scale(pygame.image.load(join(ENEMY_PATH, "enemy3", "enemy3_1.png")), (40, 35))
|
||||
ENEMY_MISSILE = pygame.image.load(join(SPRITE_PATH, "missiles", "enemymissile.png")) # enemy missile
|
||||
|
||||
# background
|
||||
BACKGROUND = pygame.transform.scale(pygame.image.load(join(BASE_PATH, "assets", "background.jpg")), (WIDTH, HEIGHT))
|
||||
|
||||
# colors (R, G, B)
|
||||
BLUE = (16, 16, 69)
|
||||
WHITE = (255, 255, 255)
|
||||
RED = (188, 2, 5)
|
||||
|
||||
|
||||
class Missile:
|
||||
|
||||
def __init__(self, x: int, y: int, img) -> None:
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.img = img
|
||||
self.mask = pygame.mask.from_surface(self.img)
|
||||
|
||||
def draw(self, window) -> None:
|
||||
window.blit(self.img, (self.x, self.y))
|
||||
|
||||
def move(self, velocity: int) -> None:
|
||||
self.y += velocity
|
||||
|
||||
def off_screen(self, height: int) -> bool:
|
||||
return not (self.y <= height and self.y >= 0)
|
||||
|
||||
def collision(self, object) -> bool:
|
||||
return collide(self, object)
|
||||
|
||||
|
||||
class Ship:
|
||||
COOLDOWN = 30
|
||||
|
||||
def __init__(self, x: int, y: int, lives: int = 5) -> None:
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.lives = lives
|
||||
self.ship_img = None
|
||||
self.missile_img = None
|
||||
self.missiles = []
|
||||
self.cooldown_counter = 0
|
||||
|
||||
def draw(self, window) -> None:
|
||||
window.blit(self.ship_img, (self.x, self.y))
|
||||
for missile in self.missiles:
|
||||
missile.draw(WINDOW)
|
||||
|
||||
def move_missiles(self, velocity: int, object) -> None:
|
||||
self.cooldown()
|
||||
for missile in self.missiles:
|
||||
missile.move(velocity)
|
||||
if missile.off_screen(HEIGHT):
|
||||
self.missiles.remove(missile)
|
||||
elif missile.collision(object):
|
||||
object.lives -= 1
|
||||
self.missiles.remove(missile)
|
||||
|
||||
def cooldown(self) -> None:
|
||||
if self.cooldown_counter >= self.COOLDOWN:
|
||||
self.cooldown_counter = 0
|
||||
elif self.cooldown_counter > 0:
|
||||
self.cooldown_counter += 1
|
||||
|
||||
def shoot(self) -> None:
|
||||
if self.cooldown_counter == 0:
|
||||
missile = Missile(self.x + self.get_width() / 2 - 5 / 2, self.y, self.missile_img) # missile spawn offset
|
||||
self.missiles.append(missile)
|
||||
self.cooldown_counter = 1
|
||||
|
||||
def get_width(self) -> int:
|
||||
return self.ship_img.get_width()
|
||||
|
||||
def get_height(self) -> int:
|
||||
return self.ship_img.get_height()
|
||||
|
||||
|
||||
class Player(Ship):
|
||||
|
||||
def __init__(self, x: int, y: int, lives: int = 5) -> None:
|
||||
super().__init__(x, y, lives)
|
||||
self.ship_img = SPACESHIP
|
||||
self.missile_img = PLAYER_MISSILE
|
||||
self.mask = pygame.mask.from_surface(self.ship_img)
|
||||
self.max_lives = lives
|
||||
|
||||
def move_missiles(self, velocity: int, objects: list) -> None:
|
||||
self.cooldown()
|
||||
for missile in self.missiles:
|
||||
missile.move(velocity)
|
||||
if missile.off_screen(HEIGHT):
|
||||
self.missiles.remove(missile)
|
||||
else:
|
||||
for object in objects:
|
||||
if missile.collision(object):
|
||||
objects.remove(object)
|
||||
if missile in self.missiles:
|
||||
self.missiles.remove(missile)
|
||||
|
||||
|
||||
class Enemy(Ship):
|
||||
COLOR_MAP = {
|
||||
"magenta": ENEMY_1,
|
||||
"cyan": ENEMY_2,
|
||||
"lime": ENEMY_3,
|
||||
}
|
||||
|
||||
def __init__(self, x: int, y: int, color: str) -> None:
|
||||
super().__init__(x, y)
|
||||
self.ship_img = self.COLOR_MAP[color]
|
||||
self.missile_img = ENEMY_MISSILE
|
||||
self.mask = pygame.mask.from_surface(self.ship_img)
|
||||
|
||||
def move(self, velocity: int) -> None:
|
||||
self.y += velocity
|
||||
|
||||
|
||||
def main() -> None:
|
||||
run = True
|
||||
lost = False
|
||||
lost_count = 0
|
||||
FPS = 60
|
||||
level = 0
|
||||
|
||||
enemies = []
|
||||
wave_length = 5
|
||||
player_velocity = 7
|
||||
enemy_velocity = 2
|
||||
missile_velocity = 5
|
||||
|
||||
player = Player(300, 650)
|
||||
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
def redraw_window() -> None:
|
||||
WINDOW.blit(BACKGROUND, (0, 0))
|
||||
# draw text
|
||||
lives_label = set_font(50).render(f"Lives: {player.lives}", 1, WHITE)
|
||||
level_label = set_font(50).render(f"Level: {level}", 1, WHITE)
|
||||
WINDOW.blit(lives_label, (10, 10))
|
||||
WINDOW.blit(level_label, (WIDTH - level_label.get_width() - 10, 10))
|
||||
|
||||
for enemy in enemies:
|
||||
enemy.draw(WINDOW)
|
||||
|
||||
player.draw(WINDOW)
|
||||
|
||||
if lost:
|
||||
lost_label = set_font(60).render("You lost!", 1, RED)
|
||||
WINDOW.blit(lost_label, (WIDTH / 2 - lost_label.get_width() / 2, 350))
|
||||
|
||||
pygame.display.update()
|
||||
|
||||
while run:
|
||||
clock.tick(FPS)
|
||||
redraw_window()
|
||||
|
||||
if player.lives <= 0:
|
||||
lost = True
|
||||
lost_count += 1
|
||||
|
||||
# stop game
|
||||
if lost:
|
||||
if lost_count > FPS * 3:
|
||||
run = False
|
||||
else:
|
||||
continue
|
||||
|
||||
if len(enemies) == 0:
|
||||
level += 1
|
||||
wave_length += 5
|
||||
for i in range(wave_length):
|
||||
enemy = Enemy(randrange(50, WIDTH - 100), randrange(-1500, -100), choice(["magenta", "cyan", "lime"]))
|
||||
enemies.append(enemy)
|
||||
|
||||
for event in pygame.event.get():
|
||||
# quit game
|
||||
if event.type == pygame.QUIT:
|
||||
quit()
|
||||
|
||||
keys = pygame.key.get_pressed()
|
||||
|
||||
# move left
|
||||
if (keys[pygame.K_a] or keys[pygame.K_LEFT]) and (player.x - player_velocity > 0):
|
||||
player.x -= player_velocity
|
||||
# move right
|
||||
if (keys[pygame.K_d] or keys[pygame.K_RIGHT]) and (player.x + player_velocity + player.get_width() < WIDTH):
|
||||
player.x += player_velocity
|
||||
# shoot
|
||||
if keys[pygame.K_SPACE]:
|
||||
player.shoot()
|
||||
|
||||
for enemy in enemies[:]:
|
||||
enemy.move(enemy_velocity)
|
||||
enemy.move_missiles(missile_velocity, player)
|
||||
|
||||
if randrange(0, 2 * 60) == 1:
|
||||
enemy.shoot()
|
||||
|
||||
if collide(enemy, player) or (enemy.y + enemy.get_height() > HEIGHT):
|
||||
player.lives -= 1
|
||||
enemies.remove(enemy)
|
||||
|
||||
player.move_missiles(-missile_velocity, enemies)
|
||||
|
||||
|
||||
# lambda functions
|
||||
set_font = lambda size, font=FONT: pygame.font.Font(font, size) # sets font size
|
||||
collide = lambda obj1, obj2: obj1.mask.overlap(obj2.mask, (obj2.x - obj1.x, obj2.y - obj1.y)) != None # checks if 2 objects collide/overlap
|
||||
|
||||
|
||||
def main_menu() -> None:
|
||||
while True:
|
||||
WINDOW.blit(BACKGROUND, (0, 0))
|
||||
title_label = set_font(50).render("Press any key to start...", 1, WHITE)
|
||||
WINDOW.blit(title_label, (WIDTH / 2 - title_label.get_width() / 2, HEIGHT / 2 - title_label.get_height() / 2))
|
||||
pygame.display.update()
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
quit()
|
||||
if event.type == pygame.KEYDOWN:
|
||||
main()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main_menu()
|
||||
121
pygame/space_invaders/source/space_invaders_old.py
Normal file
@ -0,0 +1,121 @@
|
||||
# Author - Kristiāns Francis Cagulis
|
||||
# Date - 25.02.2022
|
||||
# Title - Space invaders
|
||||
|
||||
import pygame
|
||||
import math
|
||||
import random
|
||||
|
||||
BLUE = (16, 16, 69)
|
||||
|
||||
# init game
|
||||
pygame.init()
|
||||
pygame.display.set_caption("Space invaders")
|
||||
|
||||
# 32x32 game icon
|
||||
icon = pygame.image.load("icons/space_invader_enemy_icon.png")
|
||||
pygame.display.set_icon(icon)
|
||||
# 64x64 player icon
|
||||
player = pygame.image.load("icons/space_shuttle_player_icon.png")
|
||||
player_x = 370
|
||||
player_y = 480
|
||||
player_x_change = 0
|
||||
|
||||
# 64x64 enemy icon
|
||||
enemy = pygame.image.load("icons/space_invader_enemy_icon.png")
|
||||
enemy_x = random.randint(0, 736)
|
||||
enemy_y = random.randint(50, 150)
|
||||
enemy_x_change = .2
|
||||
enemy_y_change = 10
|
||||
|
||||
|
||||
# missile
|
||||
missile = pygame.image.load("icons/fireball_icon.png")
|
||||
missile_x = 0
|
||||
missile_y = 480 # player_y
|
||||
missile_x_change = 0
|
||||
missile_y_change = .50
|
||||
missile_state = "ready"
|
||||
|
||||
screen = pygame.display.set_mode((800, 600))
|
||||
|
||||
|
||||
def display_player(x, y):
|
||||
screen.blit(player, (x, y))
|
||||
|
||||
|
||||
def display_enemy(x, y):
|
||||
screen.blit(enemy, (x, y))
|
||||
|
||||
|
||||
def display_missile(x, y):
|
||||
global missile_state
|
||||
missile_state = "fire"
|
||||
screen.blit(missile, (x + 16, y - 10))
|
||||
|
||||
|
||||
def is_collision(enemy_x, enemy_y, missile_x, missile_y):
|
||||
distance = math.sqrt(math.pow(enemy_x - missile_x, 2) + math.pow(enemy_y - missile_y, 2))
|
||||
if distance < 27:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
running = True
|
||||
|
||||
while running:
|
||||
screen.fill(BLUE)
|
||||
|
||||
# change player pos
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
running = False
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_LEFT:
|
||||
player_x_change = -.5
|
||||
if event.key == pygame.K_RIGHT:
|
||||
player_x_change = .5
|
||||
if event.key == pygame.K_SPACE:
|
||||
if missile_state == "ready":
|
||||
missile_x = player_x
|
||||
# missile_state = "fire"
|
||||
display_missile(missile_x, missile_y)
|
||||
|
||||
if event.type == pygame.KEYUP:
|
||||
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
|
||||
player_x_change = 0
|
||||
|
||||
# player pos
|
||||
if player_x + player_x_change > 0 and player_x + player_x_change < 736:
|
||||
player_x += player_x_change
|
||||
|
||||
enemy_x += enemy_x_change
|
||||
enemy_y += enemy_y_change
|
||||
|
||||
# enemy pos
|
||||
if enemy_x >= 736:
|
||||
enemy_x_change = -.2
|
||||
elif enemy_x <= 0:
|
||||
enemy_x_change = .2
|
||||
if enemy_y >= 336:
|
||||
enemy_y_change = -.1
|
||||
elif enemy_y <= 50:
|
||||
enemy_y_change = .1
|
||||
|
||||
collision = is_collision(enemy_x, enemy_y, missile_x, missile_y)
|
||||
if collision:
|
||||
missile_y = 480
|
||||
missile_state = "ready"
|
||||
# score ...
|
||||
|
||||
display_enemy(enemy_x, enemy_y)
|
||||
|
||||
if missile_y <= 0:
|
||||
missile_state = "ready"
|
||||
if missile_state == "fire":
|
||||
display_missile(missile_x, missile_y)
|
||||
missile_y -= missile_y_change
|
||||
|
||||
display_player(player_x, player_y)
|
||||
pygame.display.update()
|
||||