Skip to content

How can you further improve your game programming skills using Python? #66

@CKLin-oneshot

Description

@CKLin-oneshot

import pygame
import random
import sys
import json
from pygame.locals import *

=== 1. 初始化 pygame 與視窗 ===

pygame.init()
pygame.mixer.init()

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("太空戰機終極版 - BOSS 攻擊")

clock = pygame.time.Clock()
FPS = 60

=== 2. 指定支援中文的字型(系統字型或自帶字型檔) ===

chinese_font = pygame.font.SysFont("Microsoft JhengHei", 36)

顏色定義

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
ORANGE = (255, 165, 0)
BLUE = (0, 0, 255)

=== 歷史考題資料 ===

historical_questions = [
{
"question": "誰是中國的第一位皇帝?",
"choices": ["秦始皇", "漢高祖", "劉邦", "孫中山"],
"answer": 0
},
{
"question": "第一屆現代奧運會在哪一年舉辦?",
"choices": ["1896", "1900", "1912", "1924"],
"answer": 0
},
{
"question": "美國獨立宣言是哪一年簽署的?",
"choices": ["1776","1783","1801","1802"],
"answer": 0
},
{
"question": "第二次世界大戰開始於哪一年?",
"choices": ["1939", "1941", "1945", "1950"],
"answer": 0
},
{
"question":"活字印刷術最早是由誰發明的?",
"choices":["畢昇","哥倫布","牛頓","達文西"],
"answer":0
}
]

def run_quiz(screen, question_data):
"""顯示考題的函式,使用支援中文的字型。"""
global chinese_font
question = question_data["question"]
choices = question_data["choices"]
correct_index = question_data["answer"]

selected = None
running_quiz = True
while running_quiz:
    screen.fill(BLACK)

    # 顯示題目
    question_surf = chinese_font.render(question, True, WHITE)
    screen.blit(question_surf, (50, 50))

    # 顯示選項
    for i, choice in enumerate(choices):
        choice_text = f"{i+1}. {choice}"
        choice_surf = chinese_font.render(choice_text, True, WHITE)
        screen.blit(choice_surf, (50, 100 + i * 40))

    pygame.display.flip()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            # 同時偵測上排數字與小鍵盤
            if event.key in [pygame.K_1, pygame.K_KP1]:
                selected = 0
            elif event.key in [pygame.K_2, pygame.K_KP2]:
                selected = 1
            elif event.key in [pygame.K_3, pygame.K_KP3]:
                selected = 2
            elif event.key in [pygame.K_4, pygame.K_KP4]:
                selected = 3

            if selected is not None:
                running_quiz = False

return selected == correct_index

def historical_attack(all_sprites, rocks, enemy_bullets, particles, explosion_sound, score):
"""執行歷史攻擊:清除畫面上所有敵人(包括 BOSS),播放特效並加分。"""
for enemy in list(rocks):
create_particles(particles, all_sprites, enemy.rect.center)
if isinstance(enemy, Boss):
score += 500
else:
score += 10
enemy.kill()
# 清除所有敵方子彈
for bullet in enemy_bullets:
bullet.kill()
if explosion_sound:
explosion_sound.play()
return score
def choose_weapon_mode(screen):
font = pygame.font.SysFont("Microsoft JhengHei", 36)
options = [
"1. 單發(Single Shot)",
"2. 雙發(Double Shot)",
"3. 三發散射(Triple Spread)"
]
selected_mode = None
choosing = True
while choosing:
screen.fill((0, 0, 0))
title_surf = font.render("選擇你的武器模式 (Choose Your Weapon):", True, WHITE)
screen.blit(title_surf, (50, 50))
for i, opt in enumerate(options):
opt_surf = font.render(opt, True, WHITE)
screen.blit(opt_surf, (50, 120 + i * 40))
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
print("按下的鍵:", event.key) # 除錯訊息
if event.key == pygame.K_1:
selected_mode = 1
choosing = False
elif event.key == pygame.K_2:
selected_mode = 2
choosing = False
elif event.key == pygame.K_3:
selected_mode = 3
choosing = False
return selected_mode

=== 遊戲資源加載 ===

def load_image(path, default_size, default_shape='plane'):
try:
image = pygame.image.load(path).convert_alpha()
image = pygame.transform.scale(image, default_size)
except Exception as e:
print("Error loading image:", e)
image = pygame.Surface(default_size, pygame.SRCALPHA)
if default_shape == 'plane':
pygame.draw.polygon(image, RED, [
(default_size[0] // 2, 0),
(0, default_size[1]),
(default_size[0], default_size[1])
])
elif default_shape == 'rock':
pygame.draw.circle(image, (128, 128, 128),
(default_size[0] // 2, default_size[1] // 2),
min(default_size) // 2)
elif default_shape == 'bullet':
pygame.draw.rect(image, WHITE, (0, 0, default_size[0], default_size[1]))
return image
life_img = load_image("life.png", (20, 20), default_shape="item")
weapon_img = load_image("weapon.png", (20, 20), default_shape="item")
plane_img = load_image("plane.png", (50, 50), 'plane')
rock_img = load_image("rock.png", (40, 40), 'rock')
boss_img = load_image("boss4.png", (100, 80))
#new_boss_img = load_image("new_boss.png", (100, 80))
bullet_img = load_image("bullet.png", (5, 15), 'bullet')
enemy_bullet_img = load_image("enemy_bullet.png", (10, 20), 'bullet')
ship_img = load_image("ship.png", (23, 23), 'ship')

載入多個 BOSS 圖片,假設有 3 張圖片

boss_images = []
for i in range(1, 4): # 如果你有 3 張圖,就用 1 到 3
filename = f"boss{i}.png"
boss_images.append(load_image(filename, (100, 80)))

載入背景圖片

try:
background_img = pygame.image.load("background.png").convert()
background_img = pygame.transform.scale(background_img, (SCREEN_WIDTH, SCREEN_HEIGHT))
except Exception as e:
print("Error loading background image:", e)
background_img = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
background_img.fill(BLACK)

你可以準備一張標題畫面圖,例如 title_screen.png

若沒有,就用黑底

try:
title_screen_img = pygame.image.load("title_screen.png").convert()
title_screen_img = pygame.transform.scale(title_screen_img, (SCREEN_WIDTH, SCREEN_HEIGHT))
except:
title_screen_img = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
title_screen_img.fill(BLACK)

載入音效

shoot_sound = pygame.mixer.Sound("shoot.wav") if pygame.mixer.get_init() else None
laser_sound = pygame.mixer.Sound("laser.wav") if pygame.mixer.get_init() else None
levelup_sound = pygame.mixer.Sound("levelup.wav") if pygame.mixer.get_init() else None
explosion_sound = pygame.mixer.Sound("explosion.wav") if pygame.mixer.get_init() else None

=== 遊戲物件類別 ===

class Player(pygame.sprite.Sprite):
def init(self):
super().init()
self.image = plane_img
self.image.set_colorkey(WHITE)
self.rect = self.image.get_rect()
self.rect.centerx = SCREEN_WIDTH // 2
self.rect.bottom = SCREEN_HEIGHT - 10
self.speed = 8
self.lives = 3

def update(self, controls):
    keys = pygame.key.get_pressed()
    if keys[controls['left']]:
        self.rect.x -= self.speed
    if keys[controls['right']]:
        self.rect.x += self.speed
    self.rect.clamp_ip(screen.get_rect())

class Item(pygame.sprite.Sprite):
def init(self):
super().init()
self.type = random.choice(["life", "weapon"])
# 用圖片來表示道具
if self.type == "life":
self.image = life_img # 讀取生命道具圖片
else:
self.image = weapon_img # 讀取武器道具圖片
self.rect = self.image.get_rect()
self.rect.x = random.randint(0, SCREEN_WIDTH - self.rect.width)
self.rect.y = -self.rect.height
self.speed = random.randint(2, 4)

def update(self):
    self.rect.y += self.speed
    if self.rect.top > SCREEN_HEIGHT:
        self.kill()

class Bullet(pygame.sprite.Sprite):
def init(self, x, y, speed=-10, dx=0, img=bullet_img):
super().init()
self.image = img
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.bottom = y
self.speed = speed
self.dx = dx # 新增水平速度

def update(self):
    self.rect.x += self.dx
    self.rect.y += self.speed
    if self.rect.bottom < 0 or self.rect.top > SCREEN_HEIGHT:
        self.kill()

class LaserBeam(pygame.sprite.Sprite):
def init(self, x, y):
super().init()
self.image = pygame.Surface((SCREEN_WIDTH, 10), pygame.SRCALPHA)
self.image.fill((0, 255, 0, 100))
self.rect = self.image.get_rect(center=(x, y))
self.duration = 45
self.damage = 50

def update(self):
    self.duration -= 1
    if self.duration <= 0:
        self.kill()

class Rock(pygame.sprite.Sprite):
def init(self, difficulty=1.0, level=1):
super().init()
self.image = rock_img
self.rect = self.image.get_rect()
self.rect.x = random.randint(0, SCREEN_WIDTH - self.rect.width)
self.rect.y = -self.rect.height
base_speed = random.randint(1, 3) # 初始速度較低
level_multiplier = 1 + (level // 10) * 0.2 # 每10關增加20%速度
self.speed = base_speed * difficulty * level_multiplier

def update(self):
    self.rect.y += self.speed
    if self.rect.top > SCREEN_HEIGHT:
        self.kill()

class Boss(pygame.sprite.Sprite):
def init(self, difficulty=1.0, image=None):
super().init()
if image is None:
image = boss_img # 确保此时 boss_img 已经定义
self.image = image
self.rect = self.image.get_rect()
self.rect.centerx = SCREEN_WIDTH // 2
self.rect.y = 50
self.max_health = 500 * difficulty
self.health = self.max_health
self.speed = 2 * difficulty
self.move_direction = 1
self.shoot_delay = 60
self.shoot_timer = 0

def update(self):
    self.rect.x += self.speed * self.move_direction
    if self.rect.right > SCREEN_WIDTH or self.rect.left < 0:
        self.move_direction *= -1
    self.shoot_timer += 1
    if self.shoot_timer >= self.shoot_delay:
        self.shoot_timer = 0
        self.shoot()

def shoot(self):
    # 隨機選擇一種攻擊模式
    mode = random.choice(["normal", "spread", "rapid"])
    if mode == "normal":
        # 普通單發攻击
        bullet = BossBullet(self.rect.centerx, self.rect.bottom)
        all_sprites.add(bullet)
        enemy_bullets.add(bullet)
    elif mode == "spread":
        # 擴散攻擊,左右各發一顆有角度的子彈

        for dx in [-3, 0, 3]:
            bullet = BossBullet(self.rect.centerx, self.rect.bottom, dx=dx)
            all_sprites.add(bullet)
            enemy_bullets.add(bullet)
    elif mode == "rapid":
        # 連續快速攻擊,連續發射數顆子彈
        for i in range(3):
            bullet = BossBullet(self.rect.centerx, self.rect.bottom)
            all_sprites.add(bullet)
            enemy_bullets.add(bullet)
    if shoot_sound:
        shoot_sound.play()

class BossBullet(pygame.sprite.Sprite):
def init(self, x, y, dx=0):
super().init()
self.image = enemy_bullet_img
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.top = y
self.speed = 5
self.dx = dx

def update(self):
    self.rect.x += self.dx
    self.rect.y += self.speed
    if self.rect.top > SCREEN_HEIGHT:
        self.kill()

def draw_boss_health_bar(screen, boss):
bar_width = boss.rect.width
bar_height = 10
health_ratio = boss.health / boss.max_health
fill_width = int(bar_width * health_ratio)
bar_x = boss.rect.x
bar_y = boss.rect.y - bar_height - 5
fill_rect = pygame.Rect(bar_x, bar_y, fill_width, bar_height)
outline_rect = pygame.Rect(bar_x, bar_y, bar_width, bar_height)
pygame.draw.rect(screen, RED, fill_rect)
pygame.draw.rect(screen, WHITE, outline_rect, 2)

class Particle(pygame.sprite.Sprite):
def init(self, x, y):
super().init()
self.size = random.randint(2, 5)
self.image = pygame.Surface((self.size2, self.size2), pygame.SRCALPHA)
color = (random.randint(200,255), random.randint(0,200), 0)
pygame.draw.circle(self.image, color, (self.size, self.size), self.size)
self.rect = self.image.get_rect(center=(x, y))
self.velocity = [random.randint(-3, 3), random.randint(-5, 0)]
self.lifetime = 20

def update(self):
    self.rect.x += self.velocity[0]
    self.rect.y += self.velocity[1]
    self.lifetime -= 1
    if self.lifetime <= 0:
        self.kill()

=== 遊戲系統 ===

class GameState:
def init(self):
self.current_level = 1
self.level_thresholds = [50, 100, 200, 250, 400, 600, 800, 1200, 1600, 1700, 1800,1900,2000,2100,2500,3000,3100,3200,3400,3500,3600,3700,3800,4000,4100,4200,4300,4400,4500]#設定關卡的邏輯
self.rock_spawn_rate = 0.02
self.special_weapon_charged = False
self.boss_active = False
self.high_score = self.load_high_score()
self.difficulty = 1.0
# 新增:記錄目前武器模式
self.weapon_mode = 1 # 預設單發

def update_level(self, score):
    prev_level = self.current_level
    for i, threshold in enumerate(self.level_thresholds):
        if score >= threshold:
            self.current_level = i + 2
            self.rock_spawn_rate = 0.02 + (0.01 * self.current_level)
            self.special_weapon_charged = True
            # 這裡可以根據分數提高難度,例如:
            self.difficulty = 1.0 + score / 1000.0  # 或其他調整公式
    if self.current_level != prev_level:
        if levelup_sound:
            levelup_sound.play()
        print("升級了,進入武器選單")
        new_mode = choose_weapon_mode(screen)
        if new_mode:
            self.weapon_mode = new_mode
        # 重置 Boss 活動狀態
        self.boss_active = False

def load_high_score(self):
    try:
        with open('save.json') as f:
            return json.load(f).get('high_score', 0)
    except:
        return 0

def save_high_score(self, score):
    with open('save.json', 'w') as f:
        json.dump({'high_score': max(score, self.high_score)}, f)

class SettingsMenu:
def init(self):
self.active = False
self.controls = {
'left': K_LEFT,
'right': K_RIGHT,
'shoot': K_SPACE,
'laser': K_l
}
self.difficulty_levels = [0.8, 1.0, 1.2]
self.current_diff = 1
self.load_settings()

def load_settings(self):
    try:
        with open('settings.json') as f:
            data = json.load(f)
            self.controls = data.get('controls', self.controls)
            self.current_diff = data.get('difficulty', 1)
    except:
        self.save_settings()

def save_settings(self):
    with open('settings.json', 'w') as f:
        json.dump({'controls': self.controls, 'difficulty': self.current_diff}, f)

def get_difficulty(self):
    return self.difficulty_levels[self.current_diff]

=== 新增:首頁(標題畫面) ===

def show_title_screen():
"""顯示標題畫面,等待玩家按下任意鍵開始"""
title_running = True
while title_running:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# 按下任何鍵或滑鼠,就進入遊戲
if event.type == KEYDOWN or event.type == MOUSEBUTTONDOWN:
title_running = False

    # 繪製標題背景
    screen.blit(title_screen_img, (0, 0))

    # 在畫面下方顯示提示文字
    tip_text = chinese_font.render("按任意鍵開始 (Press any key to start)", True, WHITE)
    screen.blit(tip_text, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT - 100))

    pygame.display.flip()
    clock.tick(FPS)

=== 遊戲主程式 ===

def main():
global all_sprites, enemy_bullets, rocks

settings = SettingsMenu()
game_state = GameState()
game_state.difficulty = settings.get_difficulty()

# 建立各群組
all_sprites   = pygame.sprite.Group()
bullets       = pygame.sprite.Group()
enemy_bullets = pygame.sprite.Group()
rocks         = pygame.sprite.Group()
particles     = pygame.sprite.Group()
items         = pygame.sprite.Group()   # 新增:創建一个道具组

player = Player()
all_sprites.add(player)

score = 0
game_over = False
running = True

while running:
    # 事件處理
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
        elif event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                settings.active = not settings.active
            elif event.key == K_h and not settings.active and not game_over:
                quiz_data = random.choice(historical_questions)
                if run_quiz(screen, quiz_data):
                    score = historical_attack(all_sprites, rocks, enemy_bullets, particles, explosion_sound, score)
                else:
                    print("答錯了,沒有特殊攻擊。")
            elif not settings.active:
                if event.key == settings.controls['shoot'] and not game_over:
                    if game_state.weapon_mode == 1:
                        # 單發
                        bullet = Bullet(player.rect.centerx, player.rect.top)
                        all_sprites.add(bullet)
                        bullets.add(bullet)
                    elif game_state.weapon_mode == 2:
                        # 雙發
                        bullet_left = Bullet(player.rect.centerx - 10, player.rect.top)
                        bullet_right = Bullet(player.rect.centerx + 10, player.rect.top)
                        all_sprites.add(bullet_left, bullet_right)
                        bullets.add(bullet_left, bullet_right)
                    elif game_state.weapon_mode == 3:
                        # 三發散射:左右子彈初始位置略有偏移,且帶有水平速度
                        bullet_center = Bullet(player.rect.centerx, player.rect.top)
                        bullet_left = Bullet(player.rect.centerx - 10, player.rect.top, dx=-3)
                        bullet_right = Bullet(player.rect.centerx + 10, player.rect.top, dx=3)
                        all_sprites.add(bullet_center, bullet_left, bullet_right)
                        bullets.add(bullet_center, bullet_left, bullet_right)
                    if shoot_sound:
                        shoot_sound.play()
                    items = pygame.sprite.Group()
                    # 在主迴圈更新部分加入道具生成(機率可調整)
                    if random.random() < 0.005:  # 例如每幀有 0.5% 的機率生成道具
                        item = Item()
                        all_sprites.add(item)
                        items.add(item)

                # 接下來檢查玩家與道具的碰撞
                item_hits = pygame.sprite.spritecollide(player, items, True)
                for item in item_hits:
                    if item.type == "life":
                        player.lives += 1  # 增加一條生命
                        print("獲得生命增益!")
                    elif item.type == "weapon":
                        # 你可以選擇調用武器選單,或直接修改玩家的射擊參數
                        new_mode = choose_weapon_mode(screen)
                        if new_mode:
                            game_state.weapon_mode = new_mode
                        print("獲得武器增益!")

                if event.key == settings.controls['laser'] and game_state.special_weapon_charged and not game_over:
                    laser = LaserBeam(player.rect.centerx, player.rect.top)
                    all_sprites.add(laser)
                    bullets.add(laser)
                    game_state.special_weapon_charged = False
                    if laser_sound:
                        laser_sound.play()
                if event.key == K_r and game_over:
                    game_over = False
                    all_sprites.empty()
                    bullets.empty()
                    enemy_bullets.empty()
                    rocks.empty()
                    particles.empty()
                    player = Player()
                    all_sprites.add(player)
                    score = 0
                    game_state = GameState()
                    game_state.difficulty = settings.get_difficulty()

    if not game_over and not settings.active:
        # 更新等級
        game_state.update_level(score)

        # 生成敵人或 Boss
        if game_state.current_level % 5 == 0 and not game_state.boss_active:
            # 根據關卡計算 BOSS 索引,例如關卡 5 對應 boss_images[0],關卡 10 對應 boss_images[1],依此類推
            boss_index = (game_state.current_level // 5 - 1)
            # 如果超出圖片數量,則循環使用最後一張
            if boss_index >= len(boss_images):
                boss_index = len(boss_images) - 1
            boss = Boss(game_state.difficulty, image=boss_images[boss_index])
            all_sprites.add(boss)
            rocks.add(boss)
            game_state.boss_active = True

        elif random.random() < game_state.rock_spawn_rate:
            rock = Rock(game_state.difficulty, game_state.current_level)
            all_sprites.add(rock)
            rocks.add(rock)

# 更新玩家與所有精靈
        player.update(settings.controls)
        for sprite in all_sprites:
            if sprite != player:
                sprite.update()

        # 碰撞處理
        score = handle_collisions(all_sprites, bullets, rocks, particles, game_state, score)

        # 檢查玩家被撞
        if pygame.sprite.spritecollide(player, rocks, True):
            player.lives -= 1
            if player.lives <= 0:
                game_over = True
                game_state.save_high_score(score)
        if pygame.sprite.spritecollide(player, enemy_bullets, True):
            player.lives -= 1
            if player.lives <= 0:
                game_over = True
                game_state.save_high_score(score)

    # 繪製畫面
    screen.blit(background_img, (0, 0))
    all_sprites.draw(screen)
    particles.draw(screen)
    for enemy in rocks:
        if isinstance(enemy, Boss):
            draw_boss_health_bar(screen, enemy)
    draw_ui(screen, score, player.lives, game_state, settings, game_over)

    if settings.active:
        draw_settings(screen, settings)

    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()
sys.exit()

def handle_collisions(all_sprites, bullets, rocks, particles, game_state, score):
hits = pygame.sprite.groupcollide(bullets, rocks, True, False)
for bullet, hit_list in hits.items():
for target in hit_list:
if isinstance(target, Boss):
target.health -= 10
if target.health <= 0:
target.kill()
score += 500
# 生成新 Boss(只要仍處於 Boss 關卡)
if game_state.current_level % 5 == 0:
boss_index = (game_state.current_level // 5 - 1)
if boss_index >= len(boss_images):
boss_index = len(boss_images) - 1
new_boss = Boss(game_state.difficulty, image=boss_images[boss_index])
all_sprites.add(new_boss)
rocks.add(new_boss)
# 保持 boss_active 為 True,因為我們仍在 Boss 關卡
game_state.boss_active = True
else:
target.kill()
score += 10
create_particles(particles, all_sprites, target.rect.center)
if explosion_sound:
explosion_sound.play()

# 處理激光碰撞(類似邏輯)
for laser in [s for s in bullets if isinstance(s, LaserBeam)]:
    laser_hits = pygame.sprite.spritecollide(laser, rocks, False)
    for target in laser_hits:
        if isinstance(target, Boss):
            target.health -= laser.damage
            if target.health <= 0:
                target.kill()
                score += 500
                if game_state.current_level % 5 == 0:
                    boss_index = (game_state.current_level // 5 - 1)
                    if boss_index >= len(boss_images):
                        boss_index = len(boss_images) - 1
                    new_boss = Boss(game_state.difficulty, image=boss_images[boss_index])
                    all_sprites.add(new_boss)
                    rocks.add(new_boss)
                    game_state.boss_active = True
        else:
            target.kill()
            score += 20
        create_particles(particles, all_sprites, target.rect.center)
        if explosion_sound:
            explosion_sound.play()
return score

def create_particles(particles, all_sprites, position):
for _ in range(10):
particle = Particle(*position)
particles.add(particle)
all_sprites.add(particle)

def draw_ui(screen, score, lives, game_state, settings, game_over):
ui_font = pygame.font.Font(None, 36)

texts = [
    (f"Score: {score}", (10, 10)),
    (f"Level: {game_state.current_level}", (SCREEN_WIDTH // 2 - 50, 10)),
    (f"Laser: {'READY' if game_state.special_weapon_charged else 'CHARGING'}", (10, 50)),
    (f"High Score: {game_state.high_score}", (SCREEN_WIDTH - 200, 50)),
    (f"Difficulty: {game_state.difficulty:.2f}", (10, 90))


]
for text, pos in texts:
    surf = ui_font.render(text, True, WHITE)
    screen.blit(surf, pos)

# 顯示玩家生命(右上角)
spacing = 5
ship_rect = ship_img.get_rect()
x_offset = SCREEN_WIDTH - ship_rect.width - 10
y_offset = 10
for i in range(lives):
    pos = (x_offset - i * (ship_rect.width + spacing), y_offset)
    screen.blit(ship_img, pos)

if game_over:
    game_over_text = ui_font.render("GAME OVER! Press R to restart", True, RED)
    screen.blit(game_over_text, (SCREEN_WIDTH // 2 - 180, SCREEN_HEIGHT // 2))

def draw_settings(screen, settings):
font = pygame.font.Font(None, 36)
screen.fill(BLACK)
texts = [
"Settings Menu",
"Press ESC to return",
f"Left: {pygame.key.name(settings.controls['left'])}",
f"Right: {pygame.key.name(settings.controls['right'])}",
f"Shoot: {pygame.key.name(settings.controls['shoot'])}",
f"Laser: {pygame.key.name(settings.controls['laser'])}",
f"Difficulty: {['Easy', 'Normal', 'Hard'][settings.current_diff]}"
]
for i, text in enumerate(texts):
surf = font.render(text, True, WHITE)
screen.blit(surf, (50, 50 + i * 40))

=== 進入遊戲 ===

if name == "main":
# 先顯示首頁,再進入遊戲
show_title_screen()
main()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions