找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

886

积分

0

好友

116

主题
发表于 6 小时前 | 查看: 1| 回复: 0

想用代码实现儿时的经典游戏吗?今天,我们就从零开始,手把手教你使用 Python 的 pygame 库开发一个完整的“打飞机”游戏。整个过程逻辑清晰,代码逐步迭代,非常适合编程新手入门游戏开发。

1. 环境准备:安装Python与pygame

工欲善其事,必先利其器。首先需要确保你的电脑上安装了 Python 环境。

从官网 python.org 下载 Python 并安装。

Python官方网站下载页面截图

建议选择最新的稳定版本。安装成功后,打开终端或命令提示符,使用 pip 安装我们游戏开发的核心库—— pygame

使用 pip 安装 pygame 模块

pip install pygame

在终端中执行pip install pygame命令截图

看到“Successfully installed”提示,说明安装成功。这样,我们的Python游戏开发环境就搭建好了。

2. 第一步:创建窗口与显示飞机

任何图形程序的第一步都是创建窗口。我们来写一段代码,在窗口里显示一张飞机图片。

import pygame

pygame.init()
screen = pygame.display.set_mode((450,800), 0, 32)
plane = pygame.image.load('plane.png')
screen.blit(plane, (200, 400))

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
    pygame.display.update()

代码解析:

  • pygame.init(): 初始化pygame的所有模块。
  • set_mode(): 创建一个450x800像素的窗口。
  • image.load(): 加载名为‘plane.png’的图片文件(请确保该图片与代码文件在同一目录)。
  • blit(): 将飞机图片绘制到屏幕坐标(200, 400)的位置。
  • while True 循环:游戏的主循环,用于持续监听事件(如关闭窗口)和更新画面。

运行代码,你会看到一个带有飞机图案的窗口。

显示飞机图片的pygame窗口

3. 第二步:让飞机跟随鼠标移动

静态的飞机可不行,我们让它动起来,实现用鼠标控制飞机的移动。

import pygame

pygame.init()
WHITE = (255, 255, 255)
screen = pygame.display.set_mode((450,800), 0, 32)
plane = pygame.image.load('plane.png')

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

    x, y = pygame.mouse.get_pos()
    x -= plane.get_width()/2
    y -= plane.get_height()/2
    screen.fill(WHITE)
    screen.blit(plane, (x, y))

    pygame.display.update()

核心改动:

  • 在循环内,通过 pygame.mouse.get_pos() 获取当前鼠标坐标。
  • 为了让飞机中心对准鼠标,我们让坐标减去飞机图片宽度和高度的一半。
  • 每次循环都先用 fill(WHITE) 填充白色背景,清空上一帧的画面,再绘制新位置的飞机。

现在,你的飞机已经能乖乖跟着鼠标光标跑了!

4. 第三步:生成敌机并移动

敌人来了!我们需要创建敌机类,并让它们从屏幕顶部随机位置出现并向下移动。

import pygame
import random

pygame.init()
WHITE = (255, 255, 255)
screen = pygame.display.set_mode((450,800), 0, 32)
plane = pygame.image.load('plane.png')

class Enemy:
    def restart(self):
        self.x = random.randint(50, 400)
        self.y = random.randint(-200, -50)
        self.speed = random.random() * 2 + 0.5

    def __init__(self):
        self.restart()
        self.image = pygame.image.load('enemy.png').convert_alpha()

    def move(self):
        if self.y < 800:
            self.y += self.speed
        else:
            self.restart()

class Plane:
    def restart(self):
        self.x = 200
        self.y = 600

    def __init__(self):
        self.restart()
        self.image = pygame.image.load('plane.png').convert_alpha()

    def move(self):
        x, y = pygame.mouse.get_pos()
        x-= self.image.get_width() / 2
        y-= self.image.get_height() / 2
        self.x = x
        self.y = y

plane = Plane()
enemies = []
for i in range(5):
    enemies.append(Enemy())

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

    # 绘制背景
    screen.fill(WHITE)
    # 绘制敌机
    for e in enemies:
        e.move()
        screen.blit(e.image, (e.x,e.y))
    # 绘制玩家
    plane.move()
    screen.blit(plane.image, (plane.x, plane.y))

    pygame.display.update()

设计思路:

  1. 面向对象:我们定义了 Enemy(敌机)和 Plane(玩家飞机)两个类,让代码结构更清晰。
  2. 敌机行为Enemy.restart() 方法负责将敌机重置到屏幕顶部的随机位置和随机速度。move() 方法让敌机持续下落,飞出屏幕底部后再次调用 restart(),实现循环出现。
  3. 玩家控制Plane 类的 move() 逻辑与之前一致,跟随鼠标。

运行代码,你会看到敌机源源不断地从上方飞来。

多架敌机出现在游戏窗口

5. 第四步:增加碰撞检测与游戏结束逻辑

躲闪不及,撞上敌机怎么办?我们需要检测碰撞,并触发“游戏结束”。

# ……(前面的Enemy, Plane类定义等代码保持不变)

def checkCrash(enemy, plane):
    # 简单的矩形碰撞检测
    pass # 此处应实现具体的检测逻辑,返回True或False

gameover = False
font = pygame.font.Font(None, 32)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

    # 绘制背景
    screen.fill(WHITE)

    if not gameover:
        # 绘制敌机
        for e in enemies:
            if checkCrash(e, plane): # 如果检测到碰撞
                gameover = True
            e.move()
            screen.blit(e.image, (e.x,e.y))
        # 绘制玩家
        plane.move()
        screen.blit(plane.image, (plane.x, plane.y))
    else:
        text = font.render(“Game Over!”, 1, (0, 0, 0))
        screen.blit(text, (165, 400))

    pygame.display.update()

你需要补全 checkCrash 函数,实现敌机与玩家飞机的碰撞检测(例如通过判断两个图片的矩形区域是否重叠)。当碰撞发生时,gameover 标志变为 True,主循环将不再更新飞机和敌机位置,而是在屏幕上显示“Game Over!”。

游戏结束画面显示Game Over文字

6. 第五步:发射子弹,消灭敌机

是时候反击了!我们创建子弹类,让玩家可以点击鼠标发射子弹来击落敌机。

# ……(前面的Enemy, Plane类定义等代码保持不变)

class Bullet:
    def __init__(self):
        self.x = 0
        self.y = -1
        self.image = pygame.image.load(‘bullet.png’).convert_alpha()
        self.active = False

    def move(self):
        if self.active:
            self.y -= 5 # 子弹向上飞
            if self.y < 0:
                self.active = False

    def restart(self):
        mouseX, mouseY = pygame.mouse.get_pos()
        self.x = mouseX - self.image.get_width() / 2
        self.y = mouseY - self.image.get_height() / 2
        self.active = True

def checkHit(enemy, bullet):
    if (bullet.x > enemy.x and bullet.x < enemy.x + enemy.image.get_width()) and (
        bullet.y > enemy.y and bullet.y < enemy.y + enemy.image.get_height()
    ):
        enemy.restart()
        bullet.active = False
        #增加返回值,用于计分
        return True
    return False

# ……(初始化代码)

bullets = []
for i in range(10): # 创建一组子弹
    bullets.append(Bullet())
count_b = len(bullets)
index_b = 0
interval_b = 0

# ……(在主循环中)
while True:
    # ……
    if not gameover:
        # 发射子弹(按固定时间间隔)
        interval_b -= 1
        if interval_b < 0:
            bullets[index_b].restart()
            interval_b = 30 # 控制发射频率
            index_b = (index_b + 1) % count_b
        for b in bullets:
            if b.active:
                for e in enemies:
                    checkHit(e, b) # 检测子弹是否击中敌机
                b.move()
                screen.blit(b.image, (b.x, b.y)) 
    # …… 

机制说明:

  • 子弹对象池:我们预创建了10颗子弹(bullets),循环使用,避免频繁创建销毁对象。
  • 发射控制:通过 interval_b 计时器控制子弹发射间隔,实现连续射击效果。
  • 击中检测checkHit 函数判断子弹与敌机的矩形区域是否相交,击中后重置敌机并销毁子弹。

玩家飞机发射子弹攻击敌机的游戏画面

7. 第六步:记录并显示游戏分数

击中敌机就该得分!我们增加一个分数变量,并在屏幕上实时显示。

# ……
#分数
score = 0

while True:
    # ……
    if not gameover:
        # ……
        # 在屏幕左上角显示实时分数
        text = font.render(“Socre: %d” % score, 1, (0, 0, 0))
        screen.blit(text, (0, 0))
    else:
        text = font.render(“Game Over!”, 1, (0, 0, 0))
        screen.blit(text, (165, 380))
        #在屏幕中央显示最终分数
        text = font.render(“Socre: %d” % score, 1, (0, 0, 0))
        screen.blit(text, (165, 420))

    pygame.display.update()

同时,需要修改之前的 checkHit 函数,在击中敌机时让 score 增加,例如 score += 100

游戏画面左上角显示分数Score: 2000

8. 第七步:增加细节与优化

至此,一个可玩的打飞机游戏核心框架已经完成。你可以继续为其增添魅力:

  • 美化贴图:寻找或绘制更精美的飞机、子弹、敌机以及背景图片。
  • 添加音效:使用 pygame.mixer 模块为发射子弹、击中敌机、游戏结束等事件添加音效。
  • 增加背景音乐:让游戏过程更有沉浸感。
  • 优化碰撞检测:使用更精确的像素级碰撞检测 (pygame.mask) 代替简单的矩形检测。
  • 设计关卡与难度递增:随着分数提高,增加敌机数量、速度或发射子弹。

一个画面更精美的俯视角打飞机游戏截图

通过以上八个步骤,我们完成了一个从环境搭建到功能完善的 pygame 游戏项目。这个过程不仅教会你如何使用 pygame 的核心API,更展示了游戏开发的基本逻辑:初始化 -> 主循环(处理输入、更新状态、绘制画面)

希望这个教程能成为你游戏开发之旅的良好开端。动手将每一步的代码跑起来,并尝试修改参数、添加新功能,是学习编程最好的方式。如果你在实现过程中遇到问题,或想分享你的创意修改,欢迎在云栈社区与更多开发者交流讨论。




上一篇:告别格式争论!Python代码格式化工具Black详解与团队协作实践
下一篇:Redis 8 RAG工程实战:CPU服务器部署Qwen3-Embedding-0.6B进行向量化
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-29 23:41 , Processed in 0.359819 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表