pygame实现射击游戏

文章目录

代码

创建shot_demo.py,代码:

python 复制代码
import pygame
import random
import sys

# --- 常量定义 ---
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60

# 颜色定义 (R, G, B)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)


# --- 类定义 ---

class Player(pygame.sprite.Sprite):
    """玩家飞船类"""

    def __init__(self):
        super().__init__()
        # 使用一个绿色矩形代表玩家
        self.image = pygame.Surface((50, 40))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.rect.centerx = SCREEN_WIDTH // 2
        self.rect.bottom = SCREEN_HEIGHT - 30
        self.speed = 8
        self.shoot_delay = 250  # 射击冷却时间(毫秒)
        self.last_shot = pygame.time.get_ticks()

    def update(self):
        # 键盘控制移动
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT] or keys[pygame.K_a]:
            self.rect.x -= self.speed
        if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
            self.rect.x += self.speed
        if keys[pygame.K_UP] or keys[pygame.K_w]:
            self.rect.y -= self.speed
        if keys[pygame.K_DOWN] or keys[pygame.K_s]:
            self.rect.y += self.speed

        # 限制玩家在屏幕范围内
        if self.rect.right > SCREEN_WIDTH:
            self.rect.right = SCREEN_WIDTH
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.bottom > SCREEN_HEIGHT:
            self.rect.bottom = SCREEN_HEIGHT
        if self.rect.top < 0:
            self.rect.top = 0

    def shoot(self):
        # 处理射击逻辑,包含冷却时间
        now = pygame.time.get_ticks()
        if now - self.last_shot > self.shoot_delay:
            self.last_shot = now
            bullet = Bullet(self.rect.centerx, self.rect.top)
            all_sprites.add(bullet)
            bullets.add(bullet)


class Enemy(pygame.sprite.Sprite):
    """敌机类"""

    def __init__(self):
        super().__init__()
        # 使用一个红色矩形代表敌人
        self.image = pygame.Surface((30, 30))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        # 在屏幕顶部随机位置生成
        self.rect.x = random.randrange(SCREEN_WIDTH - self.rect.width)
        self.rect.y = random.randrange(-100, -40)
        self.speedy = random.randrange(1, 5)

    def update(self):
        self.rect.y += self.speedy
        # 如果敌人飞出屏幕底部,则将其重置到顶部
        if self.rect.top > SCREEN_HEIGHT:
            self.rect.x = random.randrange(SCREEN_WIDTH - self.rect.width)
            self.rect.y = random.randrange(-100, -40)
            self.speedy = random.randrange(1, 5)


class Bullet(pygame.sprite.Sprite):
    """子弹类"""

    def __init__(self, x, y):
        super().__init__()
        # 使用一个白色小矩形代表子弹
        self.image = pygame.Surface((5, 10))
        self.image.fill(WHITE)
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.bottom = y
        self.speedy = -10

    def update(self):
        self.rect.y += self.speedy
        # 如果子弹飞出屏幕顶部,则销毁它以节省内存
        if self.rect.bottom < 0:
            self.kill()


# --- 游戏初始化 ---
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("简易太空射击游戏")
clock = pygame.time.Clock()
font = pygame.font.SysFont('arial', 30)

# 创建精灵和精灵组
all_sprites = pygame.sprite.Group()
enemies = pygame.sprite.Group()
bullets = pygame.sprite.Group()

player = Player()
all_sprites.add(player)

# 创建初始敌人
for _ in range(8):
    enemy = Enemy()
    all_sprites.add(enemy)
    enemies.add(enemy)

score = 0
running = True

# --- 游戏主循环 ---
while running:
    # 1. 控制帧率
    clock.tick(FPS)

    # 2. 处理事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                player.shoot()

    # 3. 更新游戏状态
    all_sprites.update()

    # 4. 碰撞检测
    # 子弹击中敌人 (True, True) 表示两者都消失
    hits = pygame.sprite.groupcollide(enemies, bullets, True, True)
    for hit in hits:
        score += 1
        # 重新生成一个敌人
        enemy = Enemy()
        all_sprites.add(enemy)
        enemies.add(enemy)

    # 敌人撞到玩家
    hits = pygame.sprite.spritecollide(player, enemies, False)
    if hits:
        print(f"游戏结束!最终得分: {score}")
        running = False

    # 5. 绘制/渲染
    screen.fill(BLACK)  # 用黑色背景清空屏幕
    all_sprites.draw(screen)  # 绘制所有精灵

    # 绘制分数
    score_text = font.render(f'Score: {score}', True, WHITE)
    screen.blit(score_text, (10, 10))

    # 6. 翻转显示缓冲区
    pygame.display.flip()

pygame.quit()
sys.exit()
操作方式
动作 按键 (方向键 / WASD) 说明
移动 ↑ ↓ ← → 或 W A S D 控制绿色方块(玩家飞船)在屏幕范围内上下左右移动。
射击 空格键 (Space) 发射白色子弹。注意,代码中设置了冷却时间,不能无限连发。
退出 点击窗口 "X" 关闭游戏窗口。

实测wasd无效,方向键有效。

核心代码

这个游戏框架清晰地展示了Pygame开发的核心流程:
1、游戏初始化

pygame.init(): 启动Pygame库。

pygame.display.set_mode(): 创建游戏窗口。

pygame.time.Clock(): 创建时钟对象,用于控制游戏帧率。
2、精灵(Sprite)系统

通过继承 pygame.sprite.Sprite 类来创建玩家、敌人和子弹。这使得每个游戏对象都能方便地管理自己的图像 (image) 和位置 (rect)。

使用 pygame.sprite.Group() 来统一管理大量的游戏对象,可以方便地对它们进行批量更新 (update()) 和绘制 (draw())。
3、游戏主循环 (Game Loop)

这是游戏的心脏,每一帧都会重复执行以下步骤:

  • 处理事件: 监听用户的输入,如关闭窗口、按键按下等。
  • 更新状态: 调用所有精灵的 update() 方法,更新它们的位置、状态等。
  • 碰撞检测: 使用 groupcollide 和 spritecollide 等函数高效地检测不同精灵组之间的碰撞。
  • 绘制渲染: 先清空屏幕 (screen.fill),然后绘制所有需要显示的元素,最后使用 pygame.display.flip() 更新整个屏幕的显示。
相关推荐
想会飞的蒲公英3 小时前
计算机怎样读取中文文本:编码、清洗与标准化
人工智能·python·自然语言处理
SeaTunnel4 小时前
从 Python Script 地狱到标准化数据集成框架
大数据·开发语言·python·程序员·代码·seatunnel
深度研习笔记4 小时前
OpenCV工业视觉实战09|项目EXE打包+工控机无环境部署+后台常驻运行,彻底脱离Python环境,完成项目最终交付
python·opencv·webpack
CCPC不拿奖不改名4 小时前
大模型推理架构与开源生态知识整理
数据库·windows·python·架构·langchain·开源·github
Marst Code5 小时前
(python)2026Plotly 库评估:交互式可视化到底值不值得引入?
开发语言·python
databook5 小时前
当散点图不够用时:用 t-SNE 可视化多维数据
python·数据分析·数据可视化
爱自由的代码工5 小时前
游戏沉默用户怎么激活?一套可执行的步骤、指标与复盘方法
大数据·游戏·游戏发行·游戏运营·游戏分发
我的xiaodoujiao7 小时前
快速学习Python基础知识详细图文教程9--函数进阶
开发语言·python·学习·测试工具
weixin_408099677 小时前
2026 图片去水印 API 接口完全指南:一键去除图片水印(附 Python/Java/PHP/C# 示例)
java·python·php·图片处理·api调用·图片去水印·石榴智能
去码头整点薯条ing8 小时前
某当网登录滑块【协议+OCR】
爬虫·python·ocr