Python飞机大战游戏
# 导入模块顺序:官方标准模块、第三方模块、应用程序模块
import random
import pygame
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
FRAME_PER_SEC = 60
CREATE_ENEMY_EVENT = pygame.USEREVENT
HERO_FIRE_EVENT = pygame.USEREVENT+1
# 定义子类,继承自Sprite类
# 精灵和精灵组
"""
简化开发步骤(图像加载、位置变化、绘制图像)提供的两个类
pygame.sprite.Sprite(存储图像数据和位置)
pygame.sprite.Group
update更新精灵位置
精灵组
update:让组中所有精灵调用update方法
draw:将组中所有精灵的图像各自绘制到不同的位置
"""
class GameSprite(pygame.sprite.Sprite):
# 如果父类不是object的基类,在初始化方法中必须主动调用父类的初始化方法
def __init__(self, image_name, speed=1):
# 调用父类的初始化方法
super().__init__()
# 定义对象的属性,图像、位置、速度
self.image = pygame.image.load(image_name)
self.rect = self.image.get_rect()
self.speed = speed
def update(self):
self.rect.y += self.speed
class Background(GameSprite):
def __init__(self, is_alt=False):
super().__init__("./images/background.png")
if is_alt:
self.rect.y = -self.rect.height
def update(self):
super().update()
if self.rect.y > SCREEN_RECT.height:
self.rect.y = -self.rect.height
class Enemy(GameSprite):
def __init__(self):
# 创建精灵
super().__init__("./images/enemy1.png")
# 指定初始随机速度和随机位置
self.speed = random.randint(1, 3)
self.rect.bottom = 0
max_x = SCREEN_RECT.width-self.rect.width
self.rect.x = random.randint(0, max_x)
def update(self):
super().update()
# 敌机飞离屏幕,从精灵组删除
if self.rect.y >= SCREEN_RECT.height:
# 将它从所有精灵组移出,精灵被自动销毁,__del__方法自动被调用
self.kill()
def __del__(self):
pass
class Hero(GameSprite):
def __init__(self):
super().__init__("./images/me1.png", 0)
self.rect.bottom = SCREEN_RECT.bottom-120
self.rect.centerx = SCREEN_RECT.centerx
self.bullets = pygame.sprite.Group()
def update(self):
self.rect.x += self.speed
if self.rect.x <= 0:
self.rect.x = 0
elif self.rect.right > SCREEN_RECT.right:
self.rect.right = SCREEN_RECT.right
def fire(self):
for i in (0, 1, 2):
bullet = Bullet()
# 跟随英雄移动
bullet.rect.bottom = self.rect.y-20*i
bullet.rect.centerx = self.rect.centerx
self.bullets.add(bullet)
class Bullet(GameSprite):
def __init__(self):
super().__init__("./images/bullet1.png", -2)
def update(self):
super().update()
if self.rect.bottom < 0:
self.kill()
def __del__(self):
pass
# 飞机大战游戏
from sprites import *
class PlaneGame(object):
def __init__(self):
# 游戏初始化
# 1、使用pygame创建图形窗口
# 创建游戏主窗口
# 初始化游戏显示窗口 480*700指定屏幕的宽和高(默认屏幕大小),是否是全屏(默认不传递),颜色位数(默认自动匹配),一般只需要使用元组传递第一个参数即可
# 返回结果就是游戏的主窗口
self. screen = pygame.display.set_mode(SCREEN_RECT.size)
# 2、设置游戏时钟,创建时钟对象
self.clock = pygame.time.Clock()
# 3、调用私有方法,创建精灵和精灵组
self.__create_sprites()
# 4、设置定时器事件,每隔一秒出现一架敌机,每隔0.5秒发射一次子弹,每次连发三枚
pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)
pygame.time.set_timer(HERO_FIRE_EVENT, 500)
def __create_sprites(self):
# 游戏坐标系:原点左上角,x轴水平向右增加,y轴水平向下增加
# 分别表示x y width weight,hero_rect也有这4个和size属性
# 创建背景精灵和精灵组
bg1 = Background()
bg2 = Background(is_alt=True)
self.bg_group = pygame.sprite.Group(bg1, bg2)
self.enemy_group = pygame.sprite.Group()
self.hero = Hero()
self.hero_group = pygame.sprite.Group(self.hero)
def start_game(self):
# 游戏开始
# 导入并初始化所有pygame模块,这样才能使用pygame的其他模块
pygame.init()
# 为使游戏启动后不会立即退出增加的一个游戏循环,本质就是一个无限循环,游戏循环意味着游戏正式开始
# 设置刷新频率60、检测用户交互、更新所有图像位置、更新屏幕显示
while True:
# 1、循环中调用tick(帧率)方法
self.clock.tick(FRAME_PER_SEC)
# 2、监听事件
self.__event_handler()
# 3、碰撞检测
self.__check_collide()
# 4、更新/绘制精灵组
self.__update_sprites()
# 5、更新屏幕显示
pygame.display.update()
def __event_handler(self):
# 事件监听
event_list = pygame.event.get()
for event in event_list:
if event.type == pygame.QUIT:
self.__game_over()
elif event.type == CREATE_ENEMY_EVENT:
# 到了敌机出场的时间
enemy1 = Enemy()
self.enemy_group.add(enemy1)
# elif event.type == pygame.K_DOWN and event.type == pygame.K_RIGHT:
# 不能识别连续按键
elif event.type == HERO_FIRE_EVENT:
self.hero.fire()
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_RIGHT]:
self.hero.speed = 2
elif keys_pressed[pygame.K_LEFT]:
self.hero.speed = -2
else:
self.hero.speed = 0
def __check_collide(self):
# 两个精灵组中所有精灵的碰撞检测,dokill为True,发生碰撞的精灵自动移除,collided计算碰撞的回调函数
# 子弹摧毁敌机
pygame.sprite.groupcollide(self.hero.bullets,self.enemy_group,True,True)
# 某个精灵和指定精灵组中的精灵碰撞
# 敌机撞毁英雄
enemies = pygame.sprite.spritecollide(self.hero,self.enemy_group,True)
if len(enemies)>0:
self.hero.kill()
PlaneGame.__game_over()
def __update_sprites(self):
# 更新/绘制精灵组
# self.screen.blit(bgImg, (0, 0)) self.screen.blit(hero, hero_rect)
self.bg_group.update()
self.bg_group.draw(self.screen)
self.enemy_group.update()
self.enemy_group.draw(self.screen)
self.hero_group.update()
self.hero_group.draw(self.screen)
self.hero.bullets.update()
self.hero.bullets.draw(self.screen)
@staticmethod
def __game_over():
# 游戏结束
pygame.quit()
# 直接退出系统,终止当前正在执行的程序
exit()
if __name__ == '__main__':
# 创建游戏对象
game = PlaneGame()
# 启动游戏
game.start_game()
综合体现了Python的面向对象编程的特性,并且对于pygame有了一定的理解。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人