文章目录
代码
创建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() 更新整个屏幕的显示。