Created
April 21, 2025 12:39
-
-
Save shricodev/4f581d865e3b15d00c763ffbd6bd6eb5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame | |
import random | |
import sys | |
# --------------------------- CONFIG --------------------------------- | |
WIDTH, HEIGHT = 480, 640 | |
FPS = 60 | |
STAR_COUNT = 120 | |
PLAYER_SPEED = 5 | |
BULLET_SPEED = -8 | |
ENEMY_SPEED = 2 | |
ENEMY_SPAWN_EVERY = 600 # milliseconds | |
SHOOT_COOLDOWN = 250 # milliseconds | |
# -------------------------------------------------------------------- | |
pygame.init() | |
screen = pygame.display.set_mode((WIDTH, HEIGHT)) | |
clock = pygame.time.Clock() | |
font = pygame.font.SysFont("consolas", 24) | |
pygame.display.set_caption("Galaga‑style MVP") | |
# ------------------------- STARFIELD -------------------------------- | |
stars = [] | |
for _ in range(STAR_COUNT): | |
x = random.randrange(0, WIDTH) | |
y = random.randrange(0, HEIGHT) | |
sp = random.choice([1, 2]) # slow / fast stars | |
stars.append([x, y, sp]) | |
def update_and_draw_stars(): | |
for s in stars: | |
s[1] += s[2] # move down | |
if s[1] > HEIGHT: | |
s[0] = random.randrange(0, WIDTH) | |
s[1] = 0 | |
pygame.draw.rect(screen, (255, 255, 255), (*s[:2], 2, 2)) | |
# ------------------------- SPRITES ---------------------------------- | |
class Player(pygame.sprite.Sprite): | |
def __init__(self): | |
super().__init__() | |
self.image = pygame.Surface((40, 30), pygame.SRCALPHA) | |
pygame.draw.polygon(self.image, (50, 200, 250), | |
[(0, 30), (20, 0), (40, 30)]) | |
self.rect = self.image.get_rect(midbottom=(WIDTH // 2, HEIGHT - 10)) | |
self.last_shot = 0 | |
def update(self): | |
keys = pygame.key.get_pressed() | |
if keys[pygame.K_LEFT] or keys[pygame.K_a]: | |
self.rect.x -= PLAYER_SPEED | |
if keys[pygame.K_RIGHT] or keys[pygame.K_d]: | |
self.rect.x += PLAYER_SPEED | |
self.rect.clamp_ip(screen.get_rect()) # keep on screen | |
def shoot(self): | |
now = pygame.time.get_ticks() | |
if now - self.last_shot > SHOOT_COOLDOWN: | |
self.last_shot = now | |
bullet = Bullet(self.rect.midtop) | |
all_sprites.add(bullet) | |
bullets.add(bullet) | |
class Bullet(pygame.sprite.Sprite): | |
def __init__(self, pos): | |
super().__init__() | |
self.image = pygame.Surface((4, 10)) | |
self.image.fill((255, 255, 0)) | |
self.rect = self.image.get_rect(midbottom=pos) | |
def update(self): | |
self.rect.y += BULLET_SPEED | |
if self.rect.bottom < 0: | |
self.kill() | |
class Enemy(pygame.sprite.Sprite): | |
def __init__(self): | |
super().__init__() | |
w, h = 30, 24 | |
self.image = pygame.Surface((w, h), pygame.SRCALPHA) | |
# simple “bug” sprite | |
pygame.draw.ellipse(self.image, (255, 0, 0), (0, 0, w, h)) | |
pygame.draw.line(self.image, (0, 0, 0), (0, h//2), (w, h//2), 2) | |
self.rect = self.image.get_rect( | |
midtop=(random.randrange(20, WIDTH - 20), -h)) | |
def update(self): | |
self.rect.y += ENEMY_SPEED | |
if self.rect.top > HEIGHT: | |
self.kill() | |
# ------------------------ GROUPS & TIMERS --------------------------- | |
all_sprites = pygame.sprite.Group() | |
bullets = pygame.sprite.Group() | |
enemies = pygame.sprite.Group() | |
player = Player() | |
all_sprites.add(player) | |
ENEMY_EVENT = pygame.USEREVENT + 1 | |
pygame.time.set_timer(ENEMY_EVENT, ENEMY_SPAWN_EVERY) | |
score = 0 | |
# ========================= MAIN LOOP ================================ | |
running = True | |
while running: | |
dt = clock.tick(FPS) | |
# -------- EVENT -------- | |
for event in pygame.event.get(): | |
if event.type == pygame.QUIT: | |
running = False | |
if event.type == ENEMY_EVENT: | |
enemy = Enemy() | |
all_sprites.add(enemy) | |
enemies.add(enemy) | |
if event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP): | |
player.shoot() | |
# -------- UPDATE ------- | |
all_sprites.update() | |
# bullet–enemy collisions | |
hits = pygame.sprite.groupcollide(enemies, bullets, True, True) | |
score += len(hits) | |
# enemy reaches player? (just quit for MVP) | |
if pygame.sprite.spritecollideany(player, enemies): | |
running = False | |
# -------- DRAW --------- | |
screen.fill((0, 0, 20)) # dark space | |
update_and_draw_stars() | |
all_sprites.draw(screen) | |
# score | |
txt = font.render(f"Score: {score}", True, (255, 255, 255)) | |
screen.blit(txt, (10, 10)) | |
pygame.display.flip() | |
pygame.quit() | |
sys.exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment