当前位置: 首页 > article >正文

使用Pygame制作“太空侵略者”游戏

1. 前言

在 2D 游戏开发中,“太空侵略者”是一款入门难度适中、却能覆盖多种常见游戏机制的项目:

  • 玩家控制飞船(Player)左右移动,发射子弹。
  • 敌人(Enemy)排列成一行或多行,从屏幕顶端缓慢移动或左右移动逼近玩家。
  • 当敌人被击中时,会被销毁并加分。若敌人到达玩家所在行或玩家被碰撞,则游戏结束。

在本篇中,我们将使用 Python + Pygame 实现一个简化版本的 Space Invaders,涵盖:玩家移动、子弹发射、敌人生成与移动、碰撞检测、计分与游戏结束逻辑等。


2. 开发环境

  1. Python 3.x
  2. Pygame
    如果尚未安装,可在命令行执行:
    pip install pygame
    
  3. 桌面系统:Windows、macOS 或大多数 Linux 系统都可正常运行。

确认 import pygame 无报错即可开始。


3. 游戏思路与关键点

  1. 玩家(Player)

    • 以飞船形象出现在屏幕下方,可左右移动(受屏幕边界限制)。
    • 按空格键或其他按键发射子弹。子弹往上移动,离开屏幕后可回收。
  2. 敌人(Enemy)

    • 可一次性生成若干敌人(如 3 行 × 6 列),排列在屏幕上方。
    • 敌人整体移动:
      • 可以先左右移动,到达边界后整体往下一行移动;
      • 或者在一定频率向玩家方向缓慢下降。
    • 当敌人到达玩家所在行(或接近底部),游戏结束。
  3. 子弹(Bullet)

    • 玩家发射的子弹以固定速度向上移动;
    • 敌人若与子弹发生碰撞,则敌人被销毁,玩家得分,子弹也随之消失。
  4. 碰撞检测

    • Rect 或基于距离的判断:当子弹矩形与敌人矩形重叠时,判定击中。
    • 当敌人矩形与玩家矩形重叠,或敌人到达屏幕下方,则游戏结束。
  5. 游戏循环

    • 每帧:处理输入事件(玩家移动、发射)、更新玩家位置、子弹与敌人位置,检测碰撞、绘制画面。
    • 当所有敌人消灭或玩家阵亡,即可结束游戏并显示结果。

4. 完整示例代码

以下示例保存为 space_invaders.py 并运行即可。请根据自己的需求调节画面尺寸、敌人数量、速度等参数。

import pygame
import sys
import random# 初始化 Pygame
pygame.init()# ---------------------
# 全局配置
# ---------------------
WIDTH, HEIGHT = 600, 600
FPS = 60# 颜色
BLACK  = (0, 0, 0)
WHITE  = (255, 255, 255)
GREEN  = (0, 255, 0)
RED    = (255, 0, 0)
YELLOW = (255, 255, 0)# 创建窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Space Invaders - Pygame 示例")
clock = pygame.time.Clock()# 字体
font = pygame.font.SysFont("arial", 24)# ---------------------
# 玩家类
# ---------------------
class Player:def __init__(self):self.width = 40self.height = 40self.x = (WIDTH - self.width) // 2self.y = HEIGHT - 60self.speed = 5self.color = GREENdef draw(self, surface):pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height))def move_left(self):self.x -= self.speedif self.x < 0:self.x = 0def move_right(self):self.x += self.speedif self.x + self.width > WIDTH:self.x = WIDTH - self.widthdef get_rect(self):return pygame.Rect(self.x, self.y, self.width, self.height)# ---------------------
# 敌人类
# ---------------------
class Enemy:def __init__(self, x, y):self.width = 30self.height = 30self.x = xself.y = yself.speed_x = 2   # 水平移动速度self.speed_y = 20  # 到达边界后往下移动的距离self.color = REDdef draw(self, surface):pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height))def update(self, enemies):"""水平移动敌人群,若到达左右边界,则整体向下移动"""self.x += self.speed_x# 检测边界if self.x < 0 or self.x + self.width > WIDTH:# 改变方向,并让所有敌人往下移动 speed_yfor e in enemies:e.speed_x = -e.speed_xe.y += e.speed_yreturndef get_rect(self):return pygame.Rect(self.x, self.y, self.width, self.height)# ---------------------
# 子弹类
# ---------------------
class Bullet:def __init__(self, x, y):self.x = xself.y = yself.radius = 5self.speed = 7self.color = YELLOWdef update(self):self.y -= self.speed  # 向上移动def draw(self, surface):pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), self.radius)def get_rect(self):return pygame.Rect(self.x - self.radius, self.y - self.radius,self.radius * 2, self.radius * 2)# ---------------------
# 工具函数
# ---------------------
def create_enemies(rows=3, cols=6):"""生成敌人列表,分布在屏幕上方"""enemies = []gap_x = 60gap_y = 50start_x = 50start_y = 50for row in range(rows):for col in range(cols):x = start_x + col * gap_xy = start_y + row * gap_yenemy = Enemy(x, y)enemies.append(enemy)return enemiesdef main():player = Player()enemies = create_enemies(rows=3, cols=6)bullets = []score = 0running = Truewhile running:clock.tick(FPS)# 1) 处理事件for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseelif event.type == pygame.KEYDOWN:if event.key == pygame.K_SPACE:# 发射子弹bullet_x = player.x + player.width // 2bullet_y = player.ybullets.append(Bullet(bullet_x, bullet_y))# 键盘输入keys = pygame.key.get_pressed()if keys[pygame.K_LEFT]:player.move_left()if keys[pygame.K_RIGHT]:player.move_right()# 2) 更新子弹位置并检测越界for b in bullets[:]:b.update()if b.y + b.radius < 0:bullets.remove(b)# 3) 更新敌人群位置for e in enemies:e.update(enemies)# 4) 碰撞检测:子弹与敌人for b in bullets[:]:b_rect = b.get_rect()for e in enemies[:]:e_rect = e.get_rect()if b_rect.colliderect(e_rect):# 撞击 -> 敌人消失、子弹消失、得分enemies.remove(e)bullets.remove(b)score += 10break  # 该子弹已被移除,无需再检测其它敌人# 5) 检测敌人是否到达玩家或超越底部 -> 游戏结束for e in enemies:# 若敌人越过玩家所在 y,或者直接与玩家重叠if e.y + e.height > player.y:running = False# 6) 如果敌人全部消灭 -> 获胜 or 提示if not enemies:# 可以自定义下一波敌人或结束游戏running = False# 7) 绘制screen.fill(BLACK)# 绘制玩家、敌人、子弹player.draw(screen)for e in enemies:e.draw(screen)for b in bullets:b.draw(screen)# 显示得分score_surface = font.render(f"Score: {score}", True, WHITE)screen.blit(score_surface, (10, 10))pygame.display.flip()game_over(score)def game_over(score):# 游戏结束界面screen.fill(BLACK)msg = f"Game Over! Your Score: {score}"label = font.render(msg, True, WHITE)rect = label.get_rect(center=(WIDTH // 2, HEIGHT // 2))screen.blit(label, rect)pygame.display.flip()pygame.time.wait(3000)pygame.quit()sys.exit()if __name__ == "__main__":main()

主要逻辑解析

  1. Player(玩家)

    • 只有左右移动逻辑,且在碰撞边界时保持在范围内。
    • 按空格键发射子弹(Bullet 对象),存入列表。
  2. Enemy(敌人)

    • 通过 create_enemies() 一次性生成多个敌人,按行列布局排列在上方。
    • 每帧都执行 update(),在水平方向移动;若检测到超出左右边界,就整体往下一行,并反转移动方向。
  3. Bullet(子弹)

    • 每帧向上移动,若飞出屏幕则被移除;
    • 碰撞到敌人后,敌人与子弹都被移除并加分。
  4. 碰撞检测

    • 使用 Rectcolliderect 方法判断子弹与敌人是否重叠。
    • 当任意敌人到达玩家所在行或越过玩家,则游戏结束。
  5. 游戏结束

    • 当敌人列表为空时,玩家成功消灭全部敌人,也退出游戏循环;
    • 或者当敌人到达玩家区域,表示玩家失败。
    • 最后进入 game_over() 界面做简单提示后退出。

5. 运行效果

image.png
在这里插入图片描述


6. 总结

通过本篇文章,你已经学会了如何使用 Pygame 编写一个简易版的 Space Invaders 游戏:从玩家移动与射击,到敌人群体移动与下落,再到碰撞检测与游戏结束逻辑,都得到了体现。

相关文章:

使用Pygame制作“太空侵略者”游戏

1. 前言 在 2D 游戏开发中&#xff0c;“太空侵略者”是一款入门难度适中、却能覆盖多种常见游戏机制的项目&#xff1a; 玩家控制飞船&#xff08;Player&#xff09;左右移动&#xff0c;发射子弹。敌人&#xff08;Enemy&#xff09;排列成一行或多行&#xff0c;从屏幕顶…...

《逆向工程核心原理》第三~五章知识整理

查看上一章节内容《逆向工程核心原理》第一~二章知识整理 对应《逆向工程核心原理》第三章到第五章内容 小端序标记法 字节序 多字节数据在计算机内存中存放的字节顺序分为小端序和大端序两大类 大端序与小端序 BYTE b 0x12; WORD w 0x1234; DWORD dw 0x12345678; cha…...

2025 AI行业变革:从DeepSeek V3到o3-mini的技术演进

【核心要点】 DeepSeek V3引领算力革命&#xff0c;成本降至1/20o3-mini以精准优化回应市场挑战AI技术迈向真正意义的民主化行业生态正在深刻重构 一、市场格局演变 发展脉络 2025年初&#xff0c;AI行业迎来重要转折。DeepSeek率先发布V3模型&#xff0c;通过革命性的架构创…...

SAP SD学习笔记28 - 请求计划(开票计划)之2 - Milestone请求(里程碑开票)

上一章讲了请求计划&#xff08;开票计划&#xff09;中的 定期请求。 SAP SD学习笔记27 - 请求计划(开票计划)之1 - 定期请求-CSDN博客 本章继续来讲请求计划&#xff08;开票计划&#xff09;的其他内容&#xff1a; Milestone请求(里程碑请求)。 目录 1&#xff0c;Miles…...

算法随笔_27:最大宽度坡

上一篇:算法随笔_26: 按奇偶排序数组-CSDN博客 题目描述如下: 给定一个整数数组 nums&#xff0c;坡是元组 (i, j)&#xff0c;其中 i < j 且 nums[i] < nums[j]。这样的坡的宽度为 j - i。 找出 nums 中的坡的最大宽度&#xff0c;如果不存在&#xff0c;返回 0 。 …...

SpringBoot+Vue的理解(含axios/ajax)-前后端交互前端篇

文章目录 引言SpringBootThymeleafVueSpringBootSpringBootVue&#xff08;前端&#xff09;axios/ajaxVue作用响应式动态绑定单页面应用SPA前端路由 前端路由URL和后端API URL的区别前端路由的数据从哪里来的 Vue和只用三件套axios区别 关于地址栏url和axios请求不一致VueJSPS…...

大白话讲清楚embedding原理

Embedding&#xff08;嵌入&#xff09;是一种将高维数据&#xff08;如单词、句子、图像等&#xff09;映射到低维连续向量的技术&#xff0c;其核心目的是通过向量表示捕捉数据之间的语义或特征关系。以下从原理、方法和应用三个方面详细解释Embedding的工作原理。 一、Embe…...

2025年1月22日(网络编程 udp)

系统信息&#xff1a; ubuntu 16.04LTS Raspberry Pi Zero 2W 系统版本&#xff1a; 2024-10-22-raspios-bullseye-armhf Python 版本&#xff1a;Python 3.9.2 已安装 pip3 支持拍摄 1080p 30 (1092*1080), 720p 60 (1280*720), 60/90 (640*480) 已安装 vim 已安装 git 学习…...

【RAG】SKLearnVectorStore 避免使用gpt4all会connection err

gpt4all 列表中包含了多个开源的大模型,如 Qwen2.5、Llama 3、DeepSeek、Mistral 等,但 不包含 OpenAI 的 GPT-4o。GPT-4o 是 OpenAI 提供的闭源模型,目前只能通过 OpenAI API 或 ChatGPT 官方应用(网页版、移动端)访问,并不支持本地运行,也没有 GGUF 量化格式的模型文件…...

ios swift画中画技术尝试

继上篇&#xff1a;iOS swift 后台运行应用尝试失败-CSDN博客 为什么想到画中画&#xff0c;起初是看到后台模式里有一个picture in picture&#xff0c;去了解了后发现这个就是小窗口视频播放&#xff0c;方便用户执行多任务。看小窗口视频的同时&#xff0c;可以作其他的事情…...

Prometheus 中的 Exporter

在 Prometheus 生态系统中,Exporter 扮演着至关重要的角色,它们负责从不同的服务或系统中收集和暴露度量数据。本文将详细介绍 Exporter 的概念、类型以及如何有效使用它们将 Prometheus 集成到各种系统中进行监控。 什么是 Exporter? Exporter 是一段软件,它从应用程序或…...

玄奘的启示

今天没事&#xff0c;又看了一遍央视拍的《玄奘大师》&#xff08;程池、齐秦配乐版&#xff09;伪纪录片&#xff0c;很有感触。 古罗马哲学家塞内加说“人最可怕的事情莫过于死前只留下活过的岁数。” 他在《论生命之短暂》中这样写道&#xff1a;“生命并非短促&#xff0…...

车载以太网---数据链路层

在上一章节中&#xff0c;我们讲解了数据链路层与物理层的接口MIIM,在本章中我们主要介绍车载网络中的数据链路层。 目录 数据链路层与网络层的区别 数据链路层&#xff1a;负责“同一链路”或“局域网/子网”内的可靠传输 传输范围&#xff1a; 主要功能&#xff1a; 通路…...

文本复制兼容方案最佳实现落地。

文章目录 一、navigator.clipboard.writeText二、方案落地总结 一、navigator.clipboard.writeText navigator.clipboard.writeText 是一个Web API&#xff0c;它允许网页脚本将文本数据写入用户的系统剪贴板。这个API是异步的&#xff0c;并且设计用于提高安全性和用户体验&a…...

ArkTS高性能编程实践

文章目录 概述声明与表达式函数数组异常 概述 本文主要提供应用性能敏感场景下的高性能编程的相关建议&#xff0c;助力开发者开发出高性能的应用。高性能编程实践&#xff0c;是在开发过程中逐步总结出来的一些高性能的写法和建议&#xff0c;在业务功能实现过程中&#xff0…...

阿里新发的大模型Qwen2.5-max如何?

阿里新发布的大模型Qwen2.5-Max是一款性能卓越、技术先进的大型语言模型&#xff0c;其在多个方面展现了突出的表现。以下是基于我搜索到的资料对Qwen2.5-Max的详细评价&#xff1a; 技术特点 超大规模预训练数据&#xff1a;Qwen2.5-Max采用了超过20万亿tokens的超大规模预训…...

吴晓波 历代经济变革得失@简明“中国经济史” - 读书笔记

目录 《历代经济变革得失》读书笔记一、核心观点二、主要内容&#xff08;一&#xff09;导论&#xff08;二&#xff09;春秋战国时期&#xff08;三&#xff09;汉代&#xff08;四&#xff09;北宋&#xff08;五&#xff09;明清时期&#xff08;六&#xff09;近现代&…...

SQL GROUP BY 详解

SQL GROUP BY 详解 引言 在数据库查询中,GROUP BY 子句是一个非常有用的工具,它允许我们对查询结果进行分组,并基于这些分组进行聚合计算。本文将详细介绍 GROUP BY 的用法、注意事项以及在实际应用中的场景。 什么是 GROUP BY? GROUP BY 子句用于对查询结果进行分组。…...

走向基于大语言模型的新一代推荐系统:综述与展望

HightLight 论文题目&#xff1a;Towards Next-Generation LLM-based Recommender Systems: A Survey and Beyond作者机构&#xff1a;吉林大学、香港理工大学、悉尼科技大学、Meta AI论文地址&#xff1a; https://arxiv.org/abs/2410.1974 基于大语言模型的下一代推荐系统&…...

6 Flink 状态管理

6 Flink 状态管理 1. State-Keyed State2. State-Operator State3. Broadcast State 我们前面写的 wordcount 的例子&#xff0c;没有包含状态管理。如果一个task在处理过程中挂掉了&#xff0c;那么它在内存中的状态都会丢失&#xff0c;所有的数据都需要重新计算。从容错和消…...

第1章 量子暗网中的血色黎明

月球暗面的危机与阴谋 量子隧穿效应催生的幽蓝电弧&#xff0c;于环形山表面肆意跳跃&#xff0c;仿若无数奋力挣扎的机械蠕虫&#xff0c;将月球暗面的死寂打破&#xff0c;徒增几分诡异。艾丽伫立在被遗弃的“广寒宫”量子基站顶端&#xff0c;机械义眼之中&#xff0c;倒映着…...

爬虫基础(六)代理简述

目录 一、什么是代理 二、基本原理 三、代理分类 一、什么是代理 爬虫一般是自动化的&#xff0c;当我们自动运行时 爬虫自动抓取数据&#xff0c;但一会就出现了错误&#xff1a; 如&#xff0c;您的访问频率过高&#xff01; 这是因为网站的反爬措施&#xff0c;如果频…...

前端 Vue 性能提升策略

一、引言 前端性能优化是确保 Web 应用快速响应和流畅用户体验的关键。对于使用 Vue.js 构建的应用,性能优化不仅涉及通用的前端技术,还包括针对 Vue 特性的特定优化措施。本文将从多个方面探讨如何全面提升前端和 Vue 应用的性能。 二、前端性能优化基础 1. 减少初始加载…...

MCU内部ADC模块误差如何校准

本文章是笔者整理的备忘笔记。希望在帮助自己温习避免遗忘的同时&#xff0c;也能帮助其他需要参考的朋友。如有谬误&#xff0c;欢迎大家进行指正。 一、ADC误差校准引言 MCU 片内 ADC 模块的误差总包括了 5 个静态参数 (静态失调&#xff0c;增益误差&#xff0c;微分非线性…...

Spring MVC消息转换器

在Spring MVC框架中&#xff0c;extendMessageConverters 通常与消息转换器&#xff08;Message Converters&#xff09;相关。消息转换器是Spring MVC用于将HTTP请求和响应主体&#xff08;body&#xff09;转换为Java对象和字符串的组件。它们在处理不同的媒体类型&#xff0…...

手写防抖函数、手写节流函数

文章目录 1 手写防抖函数2 手写节流函数 1 手写防抖函数 函数防抖是指在事件被触发n秒后再执行回调&#xff0c;如果在这n秒内事件又被触发&#xff0c;则重新计时。这可以使用在一些点击请求的事件上&#xff0c;避免因为用户的多次点击向后端发送多次请求。 function debou…...

【Rust自学】15.4. Drop trait:告别手动清理,释放即安全

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 15.4.1. Drop trait的意义 类型如果实现了Drop trait&#xff0c;就可以让程序员自定义当值离开作用域时发生的操作。例如文件、网络资源…...

【Block总结】CPCA,通道优先卷积注意力|即插即用

论文信息 标题: Channel Prior Convolutional Attention for Medical Image Segmentation 论文链接: arxiv.org 代码链接: GitHub 创新点 本文提出了一种新的通道优先卷积注意力&#xff08;CPCA&#xff09;机制&#xff0c;旨在解决医学图像分割中存在的低对比度和显著…...

信息学奥赛一本通 1607:【 例 2】任务安排 2 | 洛谷 P10979 任务安排 2

【题目链接】 ybt 1607&#xff1a;【 例 2】任务安排 2 洛谷 P10979 任务安排 2 注&#xff1a;ybt1607中n最大达到 1 0 4 10^4 104&#xff0c;洛谷P10979中n最大达到 3 ∗ 1 0 5 3*10^5 3∗105&#xff0c;本题解统一认为n最大达到 3 ∗ 1 0 5 3*10^5 3∗105。 【题目考点…...

AI(计算机视觉)自学路线

本文仅用来记录一下自学路线方便日后复习&#xff0c;如果对你自学有帮助的话也很开心o(*&#xffe3;▽&#xffe3;*)ブ B站吴恩达机器学习->B站小土堆pytorch基础学习->opencv相关知识&#xff08;Halcon或者opencv库&#xff09;->四类神经网络&#xff08;这里跟…...