运行效果
代码
# 先导入系统模块import sys# 随机模块import random# 再导入第三方模块import pygameimport pygame.locals# 背景图片路径IMG_BACKGROUND = "res/img_bg_level_1.jpg"# 敌机图片路径 元组IMG_ENEMYPLANE = ("res/img-plane_1.png", "res/img-plane_2.png", "res/img-plane_3.png", "res/img-plane_4.png","res/img-plane_5.png", "res/img-plane_6.png", "res/img-plane_7.png")# 玩家飞机图片路径IMG_PLAYER_PLANE = "res/hero2.png"# 子弹图片IMG_BULLET = "res/bullet_13.png"class Model(object):"""提供基础模型"""# 窗口对象window = Nonedef __init__(self, img_path, x, y):# 图片对象self.img = pygame.image.load(img_path)# x坐标self.x = x# y坐标self.y = ydef display(self):# 将要显示的对象添加到窗体中, 并指定其坐标Model.window.blit(self.img, (self.x, self.y))class Game(object):"""游戏整体控制"""# 窗口宽度WINDOW_WIDTH = 512# 窗口高度WINDOW_HEIGHT = 768# 窗体标题WINDOW_TITLE = "Plane Battle v1.0"# 小图标路径APP_ICON = "res/app.ico"def __init__(self):# 窗体对象self.window = None# 背景对象self.background = None# 敌机对象self.enemy_planes = list()# 玩家对象self.player_plane = Nonedef run(self):"""运行入口, 整体游戏控制"""# 框架初始化self.frame_init()# 模型初始化self.model_init()# 构造反复执行的机制, 刷新窗体、使窗体保持在屏幕上while True:# 背景移动self.background.move()# 显示背景self.background.display()for enemy_plane in self.enemy_planes:# 敌机下降enemy_plane.move()# 显示敌机(加载贴图)enemy_plane.display()# 显示玩家self.player_plane.display()# 把敌机列表传给玩家飞机, 好进行子弹与敌机的碰撞检测self.player_plane.collision_checking(self.enemy_planes)# 刷新窗体pygame.display.update()# 事件监听self.event_init()def frame_init(self):"""窗体初始化"""# 设置窗体对象self.window = pygame.display.set_mode((Game.WINDOW_WIDTH, Game.WINDOW_HEIGHT))# 将窗口对象传给Model类属性Model.window = self.window# 左上小图标对象app_img = pygame.image.load(Game.APP_ICON)# 设置窗体图标pygame.display.set_icon(app_img)# 设置窗体标题文本pygame.display.set_caption(Game.WINDOW_TITLE)def model_init(self):"""初始化窗体中的对象"""# 背景对象self.background = Background(IMG_BACKGROUND, 0, 0)for _ in IMG_ENEMYPLANE:# 加入多加敌机到 敌机列表中self.enemy_planes.append(EnemyPlane())# 玩家对象self.player_plane = PlayerPlane(IMG_PLAYER_PLANE, PlayerPlane.PLAYERPLANE_X, PlayerPlane.PLAYERPLANE_Y)def event_init(self):"""事件监听"""# 获取事件列表中的每一个事件for event in pygame.event.get():# 判断事件类别是否为退出事件if event.type == pygame.locals.QUIT:# 退出程序sys.exit()# 当事件类别是鼠标移动动作时if event.type == pygame.locals.MOUSEMOTION:# 获取鼠标坐标位置position = pygame.mouse.get_pos()# 根据鼠标的位置设置玩家飞机的位置self.player_plane.x = position[0] - PlayerPlane.PLAYERPLANE_WIDTH / 2self.player_plane.y = position[1] - PlayerPlane.PLAYERPLANE_HEIGHT / 2 + 5# 获取鼠标是否按下的状态mouse_state = pygame.mouse.get_pressed()# 判断是否按下鼠标左键if mouse_state[0] == 1:# 获取鼠标坐标位置position = pygame.mouse.get_pos()# 初始化子弹位置self.player_plane.bullets.append(Bullet(IMG_BULLET, position[0] - Bullet.BULLET_WIDTH / 2,position[1] - Bullet.BULLET_HEIGHT - 30))# 当玩家按下鼠标左键时, 才开始游戏self.player_plane.start_game = Trueclass Background(Model):"""背景"""def display(self):"""装载上下两张图片到窗体中"""# 将要显示的对象添加到窗体中, 并指定其坐标Model.window.blit(self.img, (self.x, self.y))Model.window.blit(self.img, (self.x, self.y - Game.WINDOW_HEIGHT))def move(self):"""背景移动"""# 当纵轴的值小于等于屏幕高度时:if self.y <= Game.WINDOW_HEIGHT:# 移动图片self.y += 1else:# 图片归位self.y = 0class PlayerPlane(Model):"""玩家飞机"""# 玩家飞机的宽度PLAYERPLANE_WIDTH = 120# 玩家飞机的高度PLAYERPLANE_HEIGHT = 78# 玩家飞机的初始位置PLAYERPLANE_X = 200PLAYERPLANE_Y = 500def __init__(self, img, x, y):super().__init__(img, x, y)# 子弹列表对象self.bullets = list()# 需要删除的子弹列表self.remove_bullets = list()# 玩家是否开始游戏标志self.start_game = Falsedef collision_checking(self, enemy_list):"""子弹的显示, 还有子弹与敌机的碰撞检测"""for bullet in self.bullets:# 子弹移动bullet.move()# 子弹显示bullet.display()# 当子弹飞出屏幕时:if bullet.y < -Bullet.BULLET_HEIGHT:# 将这个子弹添加到待删除子弹的列表self.remove_bullets.append(bullet)# 子弹没有飞出屏幕else:# 子弹矩形bullet_rect = pygame.locals.Rect(bullet.x, bullet.y, Bullet.BULLET_WIDTH, Bullet.BULLET_HEIGHT)for enemy in enemy_list:# 敌机矩形enemy_rect = pygame.locals.Rect(enemy.x, enemy.y, EnemyPlane.ENEMYPLANE_WIDTH, EnemyPlane.ENEMYPLANE_HEIGHT)# 两个矩形碰撞检测if pygame.Rect.colliderect(bullet_rect, enemy_rect):# 子弹碰撞敌机后, 敌机归位到屏幕上方enemy.enemy_plane_init()# 子弹加入删除列表self.remove_bullets.append(bullet)# 一颗子弹只能撞击 一架敌机, 退出for循环break# 玩家飞机矩形player_rect = pygame.locals.Rect(self.x, self.y, PlayerPlane.PLAYERPLANE_WIDTH,PlayerPlane.PLAYERPLANE_HEIGHT)for enemy in enemy_list:# 敌机矩形enemy_rect = pygame.locals.Rect(enemy.x, enemy.y, EnemyPlane.ENEMYPLANE_WIDTH,EnemyPlane.ENEMYPLANE_HEIGHT)# 玩家飞机与敌机碰撞检测if pygame.Rect.colliderect(player_rect, enemy_rect):# 一开始游戏时, 玩家按下鼠标左键, 才能判断玩家飞机与敌机碰撞检测, 再退出游戏if self.start_game:# 退出程序sys.exit()# 根据 待删除子弹的列表 删除子弹列表中的对象for bullet in self.remove_bullets:self.bullets.remove(bullet)else:# 删除完后, 需要将 待删除列表清空self.remove_bullets.clear()class Bullet(Model):"""子弹"""# 子弹的宽度BULLET_WIDTH = 20# 子弹的高度BULLET_HEIGHT = 29# 子弹间的移动速度BULLET_SPEED = 8def move(self):"""子弹移动"""self.y -= Bullet.BULLET_SPEEDclass EnemyPlane(Model):"""敌机"""# 敌机的宽度ENEMYPLANE_WIDTH = 100# 敌机的高度ENEMYPLANE_HEIGHT = 68# 敌机移动速度ENEMYPLANE_SPEED = 4def __init__(self):self.enemy_plane_init()def enemy_plane_init(self):"""初始化敌机"""# 敌机归到窗口上方self.y = 0 - EnemyPlane.ENEMYPLANE_HEIGHT# 敌机横坐标随机出现self.x = random.randint(0, Game.WINDOW_WIDTH - EnemyPlane.ENEMYPLANE_WIDTH)# 贴图随机self.img = pygame.image.load(IMG_ENEMYPLANE[random.randint(0, 6)])def move(self):# 当敌机没有下降出屏幕高度时if self.y <= Game.WINDOW_HEIGHT:# 移动敌机self.y += EnemyPlane.ENEMYPLANE_SPEEDelse:self.enemy_plane_init()if __name__ == '__main__':Game().run()
打包成exe文章链接
记一次pygame小程序打包成exe
图片素材地址
链接: /s/1mMeJfSqEjSgMATxU6SXfZg
提取码: 9cge