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() 更新整个屏幕的显示。
相关推荐
love530love5 小时前
LiveTalking 数字人项目 Windows 部署完全指南(EPGF 架构)
人工智能·windows·python·架构·livetalking·epgf
遇事不決洛必達5 小时前
【Python基础】GIL 锁是什么及其对爬虫的影响
爬虫·python·线程·进程·gil锁
海兰5 小时前
【水浒传:第二篇】AI江湖 —项目详细设计指南(一)
jvm·人工智能·游戏
CryptoPP6 小时前
快速对接东京证券交易所API数据:实战指南与代码示例
开发语言·人工智能·windows·python·信息可视化·区块链
探物 AI7 小时前
把 MambaOut 塞进 YOLOv11:会有什么样的反应
python·yolo·计算机视觉
如竟没有火炬7 小时前
最大矩阵——单调栈
数据结构·python·线性代数·算法·leetcode·矩阵
阳区欠7 小时前
【LangChain】LLM基础介绍
开发语言·python·langchain
Cosolar7 小时前
保姆级 CrewAI 教程:从零构建多智能体协作系统
人工智能·python·架构
GDAL7 小时前
使用 uv 管理 Python 版本
python·uv·版本
真实的菜7 小时前
Redis 从入门到精通(十二):典型业务场景实战 —— 排行榜、限流器、秒杀系统、Session 共享
数据库·redis·python