Pygame Millennium Mission Game Code
Pygame Millennium Mission Game Code
import random
import math
import array
from collections import deque
# Game Settings
CLOCK = [Link]()
FPS = 60
MAX_LIFE = 3.0
SHIELD_DURATION = FPS * 5 # 5 seconds shield
NUKE_SCORE_GAIN = 10
# States
STATE_MENU = 0
STATE_PLAYING = 1
STATE_PAUSE = 2 # New Pause State
STATE_SHOP = 3
STATE_GAMEOVER = 4
STATE_NO_AMMO = 5
# Firing Settings
AUTO_FIRE_DELAY = 20 # Frames to wait before auto-fire starts
RAPID_FIRE_INTERVAL = 10 # 6 bullets per second (60/10)
DOUBLE_CLICK_TIME = 300 # milliseconds
# Fonts
try:
font_sm = [Link]('Inter', 18)
font_md = [Link]('Inter', 24, bold=True)
font_lg = [Link]('Inter', 40, bold=True)
font_xl = [Link]('Inter', 60, bold=True)
except:
font_sm = [Link](None, 24)
font_md = [Link](None, 32)
font_lg = [Link](None, 50)
font_xl = [Link](None, 70)
def create_sounds(self):
[Link]['shoot'] = self.create_square_wave(880, 0.05, 0.2)
[Link]['explosion'] = self.create_noise(0.2, 0.3)
[Link]['coin'] = self.create_square_wave(1500, 0.05, 0.15)
[Link]['powerup'] = self.create_square_wave(600, 0.1, 0.2)
[Link]['hit'] = self.create_square_wave(200, 0.05, 0.3)
SOUNDS = SoundGenerator()
# Lists
ship = None
bullets = []
enemies = []
explosions = []
coins = []
floating_texts = []
powerups = []
particles = []
starfield_layers = [] # For parallax effect
spawn_timer = 0
class Star:
def __init__(self, size_layer):
# Store as floats to maintain smooth movement calculations
self.x = float([Link](0, WIDTH))
self.y = float([Link](0, HEIGHT))
[Link] = size_layer
[Link] = [Link] * 0.8
[Link] = C_WHITE if [Link] == 3 else C_LIGHT_GREY
def update(self):
self.y += [Link]
if self.y > HEIGHT:
self.y = 0.0
self.x = float([Link](0, WIDTH))
if [Link] == 3:
[Link](surface, [Link], (draw_x, draw_y), 1)
elif [Link] == 2:
[Link](surface, [Link], (draw_x, draw_y), (draw_x, draw_y
+ 1))
else:
# set_at requires integer coordinates
surface.set_at((draw_x, draw_y), [Link])
class Particle:
def __init__(self, x, y, color, size, life, speed_y=0):
# Store positions as floats
self.x = float(x)
self.y = float(y)
[Link] = color
[Link] = size
[Link] = life
self.max_life = life
self.speed_y = float(speed_y)
self.speed_x = [Link](-0.5, 0.5)
def update(self):
self.x += self.speed_x
self.y += self.speed_y
[Link] -= 1
[Link] *= 0.95
class FloatingText:
def __init__(self, x, y, text, color, duration=60):
# Store position as float for smooth scrolling
self.x = float(x)
self.y = float(y)
[Link] = text
[Link] = color
[Link] = duration
def update(self):
self.y -= 1.0 # Use float movement
[Link] -= 1
class Button:
def __init__(self, x, y, w, h, text, color, text_color=C_WHITE, cost=None):
[Link] = [Link](x, y, w, h)
[Link] = text
[Link] = color
self.text_color = text_color
[Link] = cost
[Link] = True
class Explosion:
def __init__(self, pos, size=40, color=C_ORANGE):
[Link] = pos
self.max_size = size
[Link] = 5
[Link] = True
[Link] = color
[Link]('explosion')
# Create larger, more dramatic particles
for _ in range(12):
[Link](Particle(pos[0], pos[1], color, [Link](4, 8),
40, [Link](-3, 3)))
[Link] += 4
else:
[Link] = False
class GameObject:
def __init__(self, x, y, color):
[Link] = [Link](x, y, 0, 0)
[Link] = color
class Coin(GameObject):
def __init__(self, x, y):
super().__init__(x, y, C_GOLD)
[Link] = [Link](x, y, 15, 15)
[Link] = 0
self.exact_y = float(y) # Store vertical position as float
def update(self):
self.exact_y += 3.0
[Link].y = int(self.exact_y) # Update rect position with integer
[Link] = ([Link] + 15) % 360 # Faster spin
# Inner $ symbol
txt = font_sm.render("$", True, C_ORANGE)
[Link](txt, ([Link] - 5, [Link] - 10))
class Bullet(GameObject):
def __init__(self, x, y, is_wingman=False, target=None, is_auto_aim=False):
col = C_MAGENTA if is_auto_aim else (C_ORANGE if is_wingman else C_RED)
super().__init__(x, y, col)
[Link] = [Link](x, y, 4, 12)
[Link] = 14.0 if is_auto_aim else 12.0
self.is_auto_aim = is_auto_aim
self.exact_x = float(x)
self.exact_y = float(y)
# Tracing/Targeting Logic
if target:
tx, ty = target
dx = float(tx) - self.exact_x
dy = float(ty) - self.exact_y
dist = [Link](dx, dy)
if dist > 0:
[Link] = (dx / dist) * [Link]
[Link] = (dy / dist) * [Link]
else:
[Link] = 0.0; [Link] = -[Link]
else:
[Link] = 0.0; [Link] = -[Link]
if not is_wingman:
[Link]('shoot')
def update(self):
self.exact_x += [Link]
self.exact_y += [Link]
# Convert to integer for the rect position
[Link] = int(self.exact_x)
[Link] = int(self.exact_y)
class Ship(GameObject):
def __init__(self):
super().__init__(WIDTH // 2, HEIGHT - 60, C_BLUE)
[Link] = [Link](0, 0, 30, 40)
[Link] = (WIDTH // 2, HEIGHT - 60)
self.has_wingman = False
self.auto_aim_timer = 0
self.fire_held_frames = 0
self.fire_cooldown = 0
self.muzzle_flash_timer = 0
# Muzzle Flash
if self.muzzle_flash_timer > 0:
for offset in [-10, 10]:
[Link](surface, C_WHITE, ([Link] + offset,
[Link]), [Link](3, 6))
self.muzzle_flash_timer -= 1
# Glow Effect
self.draw_glow(surface, 40, color)
# Right wing
p_r1 = ([Link], [Link])
p_r2 = ([Link] + 5, [Link] + 10)
p_r3 = ([Link], [Link] + 15)
[Link](surface, color, [p_r1, p_r2, p_r3])
# Main body/cockpit
p_main = [([Link] - 5, [Link]), ([Link] + 5,
[Link]), ([Link] + 5, [Link]), ([Link] - 5,
[Link])]
[Link](surface, C_LIGHT_GREY, p_main)
# Cockpit (Glass)
[Link](surface, C_WHITE, ([Link] - 3, [Link] +
5, 6, 8), border_radius=1)
if self.has_wingman:
# Draw wingmen as smaller triangles
for offset in [-50, 50]:
wx = [Link] + offset
wy = [Link] + 5
[Link](surface, C_GREEN, [(wx, wy-8), (wx-4, wy+4),
(wx+4, wy+4)])
class Enemy(GameObject):
def __init__(self, is_boss=False):
self.is_boss = is_boss
size = 80 if is_boss else 30
col = C_RED if is_boss else C_GREEN
self.can_dodge = False
if not is_boss and [Link]() < 0.08: # Increased dodge chance for
challenge
self.can_dodge = True
[Link] = C_YELLOW
if is_boss:
[Link] = 50 + (stage * 15)
self.max_hp = [Link]
[Link] = 1.0
self.move_dir = 1
else:
[Link] = 1 + (stage // 3)
self.max_hp = [Link]
[Link] = 1.0 + (stage * 0.3)
# DODGE LOGIC
if self.can_dodge:
for b in bullets_list:
# Check if bullet is approaching and is within a narrow
horizontal band
if [Link] < [Link] and ([Link] -
[Link]) < 80:
if abs([Link] - [Link]) < 5:
dodge_dir = 3 if [Link] < [Link]
else -3
[Link].x += dodge_dir
[Link](Particle([Link],
[Link], C_YELLOW, 2, 5))
# Perspective Scaling
scale_factor = 1.0 + ([Link].y / HEIGHT) * 0.4 # Reduced scale factor
for more controlled perspective
new_size = int(self.base_size * scale_factor)
[Link] = new_size
[Link] = new_size
if self.is_boss:
r = [Link]
[Link](surface, dark_color, [Link](-10, -10),
border_radius=5)
[Link](surface, [Link], r, 2, border_radius=5)
# HP Bar
hp_rect = [Link]([Link], [Link] - 15, [Link], 5)
[Link](surface, C_DARK_GREY, hp_rect)
fill = ([Link] / self.max_hp) * [Link]
[Link](surface, C_RED, (hp_rect.left, hp_rect.top,
int(fill), 5))
else:
r = [Link]
# Enemy is a flying saucer/triangle
p1 = ([Link], [Link])
p2 = ([Link], [Link])
p3 = ([Link], [Link])
p4 = ([Link], [Link])
[Link](surface, dark_color, [p1, p2, p3])
[Link](surface, [Link], [p1, p3, p4])
if self.can_dodge:
[Link](surface, C_YELLOW, ([Link], [Link] - 5),
4)
class PowerUp(GameObject):
def __init__(self, x, y):
# Slightly adjusted weights for powerups
roll = [Link](1, 100)
if roll >= 95:
[Link] = 'FIRE_ASSIST'
col = C_MAGENTA
elif roll >= 70:
[Link] = 'LIFE'
col = C_GREEN
else:
[Link] = 'COIN_MAGNET'
col = C_BLUE # New powerup color
super().__init__(x, y, col)
[Link] = [Link](x, y, 20, 20)
self.initial_y = float(y)
self.exact_y = float(y)
self.sine_offset = [Link](0, [Link] * 2) # Random offset for wave
effect
def update(self):
# Sine wave movement for eye-catching movement
self.exact_y += 1.5
[Link].y = int(self.exact_y)
[Link].x += int([Link]([Link].get_ticks() * 0.005 +
self.sine_offset) * 0.5)
initial = ""
if [Link] == 'FIRE_ASSIST': initial = "A"
elif [Link] == 'LIFE': initial = "+"
elif [Link] == 'COIN_MAGNET': initial = "M"
def init_starfield():
"""Initializes multiple layers of stars for a parallax effect."""
global starfield_layers
starfield_layers = []
# Layer 1: Slow (far)
starfield_layers.append([Star(1) for _ in range(150)])
# Layer 2: Medium
starfield_layers.append([Star(2) for _ in range(100)])
# Layer 3: Fast (near)
starfield_layers.append([Star(3) for _ in range(50)])
def draw_starfield(surface):
"""Updates and draws the parallax starfield."""
for layer in starfield_layers:
for star in layer:
[Link]()
[Link](surface)
def init_game():
global ship, bullets, enemies, explosions, coins, powerups, score, money,
bullets_left, stage, life_float, score_goal, floating_texts, particles, high_score
ship = Ship()
bullets = []
enemies = []
explosions = []
coins = []
powerups = []
floating_texts = []
particles = []
init_starfield()
score = 0
money = 0
bullets_left = 100
stage = 1
life_float = MAX_LIFE
score_goal = 50
def start_stage():
global bullets, enemies, explosions, coins, powerups, spawn_timer, score_goal,
particles
bullets = []
enemies = []
explosions = []
coins = []
powerups = []
particles = []
spawn_timer = 0
if stage == 1: score_goal = 50
elif stage == 2: score_goal = 100
else: score_goal = 100 + (stage - 2) * 60 # Slightly higher goal for later
stages
def calculate_rewards():
global money, bullets_left, last_rewards
ammo_gain = 50
bullets_left += ammo_gain
health_bonus = int(life_float) * 20
money += health_bonus
last_rewards = {"ammo_gained": ammo_gain, "health_bonus": health_bonus}
def get_nearest_enemy():
nearest = None
min_dist = 9999
for e in enemies:
if [Link] > 0:
dist = [Link]([Link] - [Link], [Link] -
[Link])
if dist < min_dist:
min_dist = dist
nearest = e
return nearest
def trigger_fire():
global bullets_left
if bullets_left > 0:
bullets_left -= 1
ship.muzzle_flash_timer = 3
target_pos = None
is_auto = False
if ship.auto_aim_timer > 0:
target = get_nearest_enemy()
if target:
target_pos = [Link]
is_auto = True
if ship.has_wingman:
[Link](Bullet([Link] - 50, [Link], True,
target=target_pos, is_auto_aim=is_auto))
[Link](Bullet([Link] + 50, [Link], True,
target=target_pos, is_auto_aim=is_auto))
def trigger_nuke(pos):
"""Triggers a screen-clearing nuclear bomb."""
global enemies, bullets, explosions, coins, floating_texts, score
enemies = []
bullets = [b for b in bullets if b.is_auto_aim]
[Link]('explosion')
def handle_input():
"""Handles ship movement and auto-fire based on mouse input."""
# Clamp mouse_y to keep the ship below the HUD (y > 80)
clamped_y = max(80 + [Link] // 2, mouse_y)
def draw_hud(surface):
"""Draws the clean, sci-fi themed heads-up display."""
# HP Bar
hp_x, hp_y, hp_w, hp_h = 10, 10, 120, 15
[Link](surface, C_BLACK, (hp_x, hp_y, hp_w, hp_h), border_radius=3)
hp_fill_w = int((life_float / MAX_LIFE) * hp_w)
# Pulsing red if low health
hp_color = C_RED if life_float > 1.0 else (255, 100, 100) if
[Link].get_ticks() % 1000 < 500 else C_RED
[Link](surface, hp_color, (hp_x, hp_y, hp_fill_w, hp_h),
border_radius=3)
# Stage
stage_text = font_md.render(f"SECTOR {stage}", True, C_YELLOW)
[Link](stage_text, (10, 35))
# Score
score_display = font_lg.render(f"{score}", True, C_WHITE)
goal_display = font_sm.render(f"/{score_goal}", True, C_LIGHT_GREY)
bar_w = 150
bar_h = 5
bar_x = WIDTH//2 - bar_w//2
bar_y = 55
# Ammo
ammo_icon_x = WIDTH - 120
ammo_icon_y = 10
[Link](surface, C_BLUE, (ammo_icon_x, ammo_icon_y, 10, 15))
ammo_text = font_md.render(f"{bullets_left}", True, C_BLUE if bullets_left > 20
else C_RED)
[Link](ammo_text, (ammo_icon_x + 15, ammo_icon_y - 2))
# Money
money_icon_x = WIDTH - 120
money_icon_y = 35
[Link](surface, C_GOLD, (money_icon_x + 5, money_icon_y + 7), 6) #
Coin icon
money_text = font_md.render(f"${money}", True, C_GOLD)
[Link](money_text, (money_icon_x + 15, money_icon_y - 2))
# Nuke Counter
nuke_icon_x = WIDTH - 40
nuke_icon_y = 35
if ship.has_nuke:
[Link](surface, C_MAGENTA, (nuke_icon_x - 5, nuke_icon_y + 7),
6) # Nuke icon
nuke_text = font_md.render(f"x{ship.nuke_count}", True, C_MAGENTA)
[Link](nuke_text, (nuke_icon_x + 5, nuke_icon_y - 2))
def draw_pause_screen(surface):
"""Draws the pause overlay."""
overlay = [Link]((WIDTH, HEIGHT))
overlay.set_alpha(200)
[Link](C_BLACK)
[Link](overlay, (0,0))
# Shop Buttons
btn_buy_bullets = Button(WIDTH//2 - 120, 250, 240, 40, "+20 Ammo", C_BLUE, cost=1)
btn_buy_wingman = Button(WIDTH//2 - 120, 300, 240, 40, "Wingman", C_GREEN, cost=20)
while running:
dt = [Link](FPS)
[Link](C_BLACK)
if btn_continue.is_clicked(m_pos):
stage += 1
start_stage()
game_state = STATE_PLAYING
if btn_emergency_sac.is_clicked(m_pos):
if life_float > 1.0:
life_float -= 1.0
bullets_left += 30
game_state = STATE_PLAYING
else:
life_float = 0
game_state = STATE_GAMEOVER
if game_state == STATE_PLAYING:
handle_input()
[Link](screen)
if bullets_left <= 0:
game_state = STATE_NO_AMMO
# Spawning
if spawn_timer <= 0:
is_boss_present = any(e.is_boss for e in enemies)
if stage % 5 == 0 and not is_boss_present and score < score_goal:
[Link](Enemy(is_boss=True))
elif len(enemies) < 10 and not is_boss_present:
[Link](Enemy())
spawn_timer = max(30, 80 - (stage * 5))
spawn_timer -= 1
for b in bullets[:]:
[Link]()
[Link](screen)
if [Link] < 0 or [Link] > WIDTH or [Link] < 0 or
[Link] > HEIGHT:
[Link](b)
for e in enemies[:]:
[Link](bullets)
[Link](screen)
[Link](Explosion([Link], 80 if e.is_boss
else 40))
score += 1 if not e.is_boss else 50
if [Link]() < 0.4: [Link](Coin([Link],
[Link]))
if [Link]() < 0.03 or e.is_boss:
[Link](PowerUp([Link], [Link]))
break
for c in coins[:]:
[Link]()
[Link](screen)
# Coin Magnet Logic (attracts coins when magnet powerup is active)
if ship.auto_aim_timer > 0:
dx = [Link] - [Link]
dy = [Link] - [Link]
dist = [Link](dx, dy)
if dist < 150 and dist > 0:
[Link] += int(dx / (dist / 5))
[Link] += int(dy / (dist / 5))
if [Link]([Link]):
money += 1
[Link](c)
floating_texts.append(FloatingText([Link], [Link],
"+$1", C_GOLD))
[Link]('coin')
elif [Link] > HEIGHT:
[Link](c)
for p in powerups[:]:
[Link]()
[Link](screen)
if [Link]([Link]):
[Link](p)
[Link]('powerup')
if [Link] == 'LIFE':
life_float = min(MAX_LIFE, life_float + 1)
floating_texts.append(FloatingText([Link],
[Link], "+1 HP", C_GREEN))
elif [Link] == 'FIRE_ASSIST':
ship.auto_aim_timer = FPS * 10
floating_texts.append(FloatingText([Link],
[Link], "OBLIVION MODE!", C_MAGENTA))
elif [Link] == 'COIN_MAGNET':
ship.auto_aim_timer = FPS * 7 # Re-use the timer for magnet
effect
floating_texts.append(FloatingText([Link],
[Link], "MAGNET ACTIVE!", C_BLUE))
for ex in explosions[:]:
[Link](screen)
if not [Link]: [Link](ex)
for ft in floating_texts[:]:
[Link]()
[Link](screen)
if [Link] <= 0: floating_texts.remove(ft)
if life_float <= 0:
game_state = STATE_GAMEOVER
if score >= score_goal:
calculate_rewards()
game_state = STATE_SHOP
# Reward Report
resupply_txt = font_md.render(f"SUPPLY DROP: +{last_rewards['ammo_gained']}
Ammo", True, C_BLUE)
bonus_txt = font_md.render(f"PERFORMANCE BONUS: +$
{last_rewards['health_bonus']}", True, C_GOLD)
[Link](resupply_txt, (WIDTH//2 - resupply_txt.get_width()//2, 120))
[Link](bonus_txt, (WIDTH//2 - bonus_txt.get_width()//2, 160))
btn_buy_bullets.draw(screen)
btn_buy_wingman.draw(screen)
btn_buy_shield.draw(screen)
btn_buy_nuke.draw(screen)
btn_continue.draw(screen)
draw_hud(screen)
btn_start.draw(screen)
[Link]()
[Link]()