【Python】使用pygame打造一个独具特色的外星人飞船大战射击游戏,附源码和工程文件_pygame灾厄代码
游戏设计目标
本项目旨在打造一款基于 Python Pygame 库的街机射击游戏,提供令人热血沸腾的太空战斗体验。游戏场景背景是星空不断滚动,在游戏中,玩家可以通过使用 WASD 键来平稳地操控飞船,自由移动在屏幕内,同时利用空格键发射导弹,按下 B 键投放炸弹,以抵抗多种形式外星人的进攻,比如它们呈正弦形、斜线飞行等。游戏采用模块化设计,主程序负责处理初始化、事件控制和游戏流程控制,主菜单支持诸如“开始游戏”、“查看高分”、“音效开关”和“退出”等功能,玩家可以通过键盘的 KEYDOWN 事件进行菜单选项切换。此外,游戏核心部分通过不断检测键盘状态以确保飞船移动的顺畅性。各类游戏对象(包括飞船、外星人、导弹、爆炸效果和 powerup 道具)都采用面向对象的设计,并利用对象池技术进行对象的重复利用,以降低内存占用和提高运行效率。另外,游戏还利用 SQLite 数据库对高分记录和音效设置进行持久化存储,确保玩家数据能够在多次游戏运行中被保留。整体系统结构清晰,各功能模块分工明确,不仅满足了实时性和操作流畅性的需求,还为以后扩展新类型外星人和功能增强打下了牢固的基础。
游戏操作方式
菜单
-
w/s 键:移动光标
-
- 输入/返回键:确认选择或提交高分
游戏
- 输入/返回键:确认选择或提交高分
-
w/a/s/d 键:操作船只移动
-
- 空格键:发射导弹
-
- b 键:投放炸弹
- b 键:投放炸弹
总体设计思路
该游戏基于 Pygame 库展开,是一款横向或纵向卷动的射击游戏。主要设计理念是将游戏模块化,每个模块负责不同的功能,通过对象池技术、精灵组和事件循环来实现游戏的整体逻辑。
- 模块化设计
- 游戏采用模块化设计,主要核心模块包括:
-
- **shooting_game**:负责游戏的初始化、主菜单、游戏主循环以及事件监听和碰撞检测。
-
- **sprites**:定义所有游戏对象,如飞船、外星人、导弹、爆炸效果、炸弹、能量道具(powerup)等,采用面向对象的设计方式。
-
- **database**:利用 SQLite 数据库持久化存储游戏得分、高分榜和音效设定。
-
- **load**:负责加载和处理图片和声音资源,将资源加载和业务逻辑代码分开。
- 面向对象设计
- 每个游戏元素都有独立的类来封装,比如:
-
- `MasterSprite`:作为所有精灵类的基类,定义了全局属性(速度、精灵组引用等)。
-
Ship
:玩家操控的飞船,处理移动、边界限制和炸弹功能。
-
- `Alien` 及其子类(`Siney`、`Spikey`、`Fasty` 等):不同类型的外星人,利用多态来实现各自的运动方式。
-
- `Missile` 和 `Explosion`:导弹和爆炸效果的实现,同时通过对象池技术复用对象,避免频繁创建和销毁对象造成的性能开销。
-
- `Powerup` 及其子类:炸弹和护盾增益道具,为游戏提供增益效果。
import osimport pygamemain_dir = os.path.split(os.path.abspath(__file__))[0]data_dir = os.path.join(main_dir, \'data\')# 省略20+行代码# 省略20+行代码def load_music(name): pygame.mixer.music.load(os.path.join(data_dir, name))def load_sound(name): class NoneSound: # 省略20+行代码 # 省略20+行代码 try: sound = pygame.mixer.Sound(fullname) except pygame.error: print(\'无法加载声音: %s\' % fullname)raise SystemExit(str(pygame.get_error())) return sounddef load_image(name, colorkey=None): fullname = os.path.join(data_dir, name) try: image = pygame.image.load(fullname) except pygame.error: print(\'无法加载图片:\', fullname) raise SystemExit(str(pygame.get_error())) # 省略20+行代码
- 事件处理和游戏主循环
- 代码采用 Pygame 的事件循环和定时器来控制游戏帧率,主要分为两个部分:
-
- **主菜单循环**:玩家可以通过键盘选择菜单项(例如开始游戏、查看高分、调整音效、退出),利用 KEYDOWN 事件切换菜单。
-
- **游戏主循环**:在游戏过程中,持续监听玩家键盘输入(利用 `pygame.key.get_pressed()` 实现平滑移动),定时生成导弹、炸弹、powerup 和外星人,然后进行碰撞检测(如导弹与外星人、飞船与外星人、powerup 与飞船)。
import pygameimport randomfrom collections import dequefrom sprites import (MasterSprite, Ship, Alien, Missile, BombPowerup, ShieldPowerup, Explosion, Siney, Spikey, Fasty, Roundy, Crawly) from database import Database from load import load_image, load_sound, load_musicif not pygame.mixer: print(\'警告,音效已禁用\') if not pygame.font: print(\'警告,字体已禁用\')BLUE = (0, 0, 255)RED = (255, 0, 0)class Keyboard(object): keys = {pygame.K_a: \'A\', pygame.K_b: \'B\', pygame.K_c: \'C\', pygame.K_d: \'D\', pygame.K_e: \'E\', pygame.K_f: \'F\', pygame.K_g: \'G\', pygame.K_h: \'H\', pygame.K_i: \'I\', pygame.K_j: \'J\', pygame.K_k: \'K\', pygame.K_l: \'L\', pygame.K_m: \'M\', pygame.K_n: \'N\', pygame.K_o: \'O\', pygame.K_p: \'P\', pygame.K_q: \'Q\', pygame.K_r: \'R\', pygame.K_s: \'S\', pygame.K_t: \'T\', pygame.K_u: \'U\', pygame.K_v: \'V\', pygame.K_w: \'W\', pygame.K_x: \'X\', pygame.K_y: \'Y\', pygame.K_z: \'Z\'}def main(): # 初始化 pygame.mixer.pre_init(11025, -16, 2, 512) pygame.init() # 省略20+行代码 # 省略20+行代码 backgroundLoc = 1500 finalStars = deque() for y in range(0, 1500, 30): size = random.randint(2, 5) x = random.randint(0, 500 - size) if y <= 500: finalStars.appendleft((x, y + 1500, size)) pygame.draw.rect(background, (255, 255, 0), pygame.Rect(x, y, size, size)) ```4. **碰撞检测和敌人管理** 5. - **碰撞检测**:游戏中主要利用 Pygame 内置的碰撞检测方法(`collide_rect`、`collide_circle`)来判断精灵之间的互动。6. - **敌人管理**:敌人以波次形式出现,每波之间会有间隔时间,当当前波的外星人都被击败后,游戏会进入倒计时状态,然后增加外星人数量或提升它们的移动速度,使游戏难度逐渐增加。```pythonimport pygameimport randomimport mathfrom load import load_imageclass MasterSprite(pygame.sprite.Sprite): allsprites = None speed = None# 省略20+行代码# 省略20+行代码class BombPowerup(Powerup): def __init__(self): super().__init__(\'bomb\') self.pType = \'bomb\'class ShieldPowerup(Powerup): def __init__(self): super().__init__(\'shield\') self.pType = \'shield\'class Ship(MasterSprite): def __init__(self): super().__init__() self.image, self.rect = load_image(\'ship.png\', -1) self.original = self.image # 省略20+行代码 # 省略20+行代码class Alien(MasterSprite): pool = pygame.sprite.Group() active = pygame.sprite.Group() def __init__(self, color): super().__init__() self.image, self.rect = load_image( \'space_invader_\' + color + \'.png\', -1) self.initialRect = self.rect screen = pygame.display.get_surface() self.area = screen.get_rect() self.loc = 0 self.radius = min(self.rect.width // 2, self.rect.height // 2) # 省略20+行代码 # 省略20+行代码# 省略20+行代码# 省略20+行代码
- 资源管理和持久化
-
- **资源加载**:图片和声音资源由 `load.py` 模块统一管理,通过指定路径和处理颜色键,实现图片转换和声音对象的创建。
-
- **数据库管理**:高分记录、音效和音乐设置通过 `database.py` 模块存储到 SQLite 数据库中,各模块通过静态方法来实现插入、删除和查询操作,确保高分记录和设置在程序重启后依旧保留。
import osimport sqlite3main_dir = os.path.split(os.path.abspath(__file__))[0]data_dir = os.path.join(main_dir, \'data\')class Database(object): path = os.path.join(data_dir, \'hiScores.db\') numScores = 15 @staticmethod def getSound(music=False): conn = sqlite3.connect(Database.path) c = conn.cursor() if music: # 省略20+行代码 # 省略20+行代码 return bool(setting[0][0]) if len(setting) > 0 else False @staticmethod def setSound(setting, music=False): conn = sqlite3.connect(Database.path) # 省略20+行代码 # 省略20+行代码 conn.commit() conn.close()# 省略20+行代码# 省略20+行代码
结语
综上所述,该游戏代码采用了面向对象和模块化设计模式,使游戏的各功能模块分层清晰。主循环负责整体的更新和事件监听,Sprites 模块负责定义和展示所有游戏对象的行为,Database 和 Load 模块分别负责数据持久化和资源加载。这一设计不仅使代码逻辑清晰、易于维护,还为未来功能的拓展(例如添加新类型外星人、设计更多增益道具或调整游戏难度)奠定了坚实基础。