Skip to content

VIP #540

Description

@lauelok122-blip

-- coding: utf-8 --

import pygame
import random
import sys

1. 初始化 Pygame

pygame.init()

視窗大小

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("VIP Games: AI 機械人保衛戰")

顏色定義

WHITE = (255, 255, 255)
BLACK = (15, 15, 25)
GOLD = (255, 215, 0) # VIP 的尊貴金色
RED = (255, 50, 50) # AI 機械人的危險紅色
BLUE = (50, 150, 255) # 保鏢/玩家的科技藍色
LASER_COLOR = (0, 255, 200) # 雷射子彈顏色

幀率控制

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

2. 遊戲角色設定

玩家 (保鏢)

player_width = 40
player_height = 40
player_x = SCREEN_WIDTH // 2
player_y = SCREEN_HEIGHT - 80
player_speed = 6

VIP (目標:需要保護的人)

vip_width = 50
vip_height = 50
vip_x = SCREEN_WIDTH // 2 - vip_width // 2
vip_y = SCREEN_HEIGHT - 150 # VIP 待在後方
vip_hp = 100

子彈列表

bullets = []
bullet_speed = 8
bullet_radius = 5

AI 機械人 (敵人) 列表

enemies = []
enemy_width = 35
enemy_height = 35
enemy_speed_min = 2
enemy_speed_max = 4
spawn_counter = 0
spawn_rate = 30 # 每30幀(約0.5秒)有機會生一隻

分數

score = 0

使用系統預設字型

pygame.font.init()
font = pygame.font.SysFont("arial", 26)
over_font = pygame.font.SysFont("arial", 50)

def draw_text(text, font, color, surface, x, y):
textobj = font.render(text, 1, color)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)

3. 遊戲主循環

running = True
game_over = False

while running:
# 背景
screen.fill(BLACK)

# 處理事件
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
        pygame.quit()
        sys.exit()
    
    # 按空白鍵射擊雷射
    if event.type == pygame.KEYDOWN and not game_over:
        if event.key == pygame.K_SPACE:
            # 子彈從玩家頭頂射出
            bullets.append([player_x + player_width // 2, player_y])

if not game_over:
    # 鍵盤操控玩家移動
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and player_x > 0:
        player_x -= player_speed
    if keys[pygame.K_RIGHT] and player_x < SCREEN_WIDTH - player_width:
        player_x += player_speed
    if keys[pygame.K_UP] and player_y > SCREEN_HEIGHT // 2: # 限制玩家只能在下半部移動
        player_y -= player_speed
    if keys[pygame.K_DOWN] and player_y < SCREEN_HEIGHT - player_height:
        player_y += player_speed

    # AI 機械人生成邏輯
    spawn_counter += 1
    if spawn_counter >= spawn_rate:
        spawn_counter = 0
        # 隨機在頂部不同位置出生
        enemy_x = random.randint(0, SCREEN_WIDTH - enemy_width)
        enemy_y = -enemy_height
        enemy_speed = random.uniform(enemy_speed_min, enemy_speed_max)
        enemies.append([enemy_x, enemy_y, enemy_speed])
        
        # 隨著分數增加,難度慢慢提升
        if score > 0 and score % 10 == 0 and spawn_rate > 15:
            spawn_rate -= 1

    # 更新子彈位置
    for bullet in bullets[:]:
        bullet[1] -= bullet_speed
        if bullet[1] < 0:
            bullets.remove(bullet)

    # 更新機械人位置
    for enemy in enemies[:]:
        enemy[1] += enemy[2] # 往下移動
        
        # 建立機械人的碰撞矩形
        enemy_rect = pygame.Rect(enemy[0], enemy[1], enemy_width, enemy_height)
        
        # 檢查機械人有沒有撞到 VIP
        vip_rect = pygame.Rect(vip_x, vip_y, vip_width, vip_height)
        if enemy_rect.colliderect(vip_rect):
            vip_hp -= 20
            if vip_hp <= 0:
                vip_hp = 0
                game_over = True
            enemies.remove(enemy)
            continue
            
        # 檢查機械人有沒有撞到玩家 (保鏢)
        player_rect = pygame.Rect(player_x, player_y, player_width, player_height)
        if enemy_rect.colliderect(player_rect):
            # 撞到保鏢,機械人被摧毀
            score += 1 
            enemies.remove(enemy)
            continue

        # 如果機械人掉出螢幕底,代表防線失守,VIP 也會扣血
        if enemy[1] > SCREEN_HEIGHT:
            vip_hp -= 10
            if vip_hp <= 0:
                vip_hp = 0
                game_over = True
            enemies.remove(enemy)

    # 碰撞檢測:子彈打中機械人
    for bullet in bullets[:]:
        bullet_rect = pygame.Rect(bullet[0] - bullet_radius, bullet[1] - bullet_radius, bullet_radius * 2, bullet_radius * 2)
        for enemy in enemies[:]:
            enemy_rect = pygame.Rect(enemy[0], enemy[1], enemy_width, enemy_height)
            if bullet_rect.colliderect(enemy_rect):
                # 命中!移除子彈同機械人,加分
                if bullet in bullets:
                    bullets.remove(bullet)
                enemies.remove(enemy)
                score += 1
                break

# 4. 繪製畫面上所有物件
# 畫 VIP (金色寶箱/盾牌形狀的保護目標)
pygame.draw.rect(screen, GOLD, (vip_x, vip_y, vip_width, vip_height), border_radius=10)
# 畫 VIP 內核
pygame.draw.rect(screen, WHITE, (vip_x + 15, vip_y + 15, 20, 20))

# 畫玩家 (藍色保鏢)
pygame.draw.rect(screen, BLUE, (player_x, player_y, player_width, player_height), border_radius=5)

# 畫子彈
for bullet in bullets:
    pygame.draw.circle(screen, LASER_COLOR, (bullet[0], bullet[1]), bullet_radius)

# 畫 AI 機械人 (紅色方塊)
for enemy in enemies:
    pygame.draw.rect(screen, RED, (enemy[0], enemy[1], enemy_width, enemy_height), border_radius=3)
    pygame.draw.rect(screen, BLACK, (enemy[0] + 10, enemy[1] + 10, enemy_width - 20, 5)) # 機械人眼睛

# 顯示 UI 資訊
draw_text(f"SCORE: {score}", font, WHITE, screen, 20, 20)
draw_text(f"VIP HP: {vip_hp}%", font, GOLD, screen, 20, 55)

# 畫一條防線提示
pygame.draw.line(screen, (50, 50, 50), (0, vip_y + vip_height + 20), (SCREEN_WIDTH, vip_y + vip_height + 20), 2)

# 如果 Game Over 顯示結束畫面
if game_over:
    draw_text("GAME OVER", over_font, RED, screen, SCREEN_WIDTH // 2 - 140, SCREEN_HEIGHT // 2 - 50)
    draw_text("VIP Has Been Destroyed!", font, WHITE, screen, SCREEN_WIDTH // 2 - 130, SCREEN_HEIGHT // 2 + 10)
    draw_text("Press ESC to Quit", font, GOLD, screen, SCREEN_WIDTH // 2 - 90, SCREEN_HEIGHT // 2 + 50)
    
    keys = pygame.key.get_pressed()
    if keys[pygame.K_ESCAPE]:
        running = False

# 更新螢幕
pygame.display.flip()
clock.tick(FPS)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions