python 游戏_Python游戏

文章流程

  • 一、项目环境背景介绍

    • 1.Pycharm版本:社区2017.2.7版本

    • 2.对应python版本:3.6.4版本

    • 3.基于以上环境开发一个游戏

    • 4.游戏项目的目录结构如下

  • 二、项目过程中所有的.py文件代码

    • 1.alien_invasion.py(主文件)

    • 2.game_functions.py(功能函数)

    • 3.alien.py(外星人)

    • 4.ship.py(飞船)

    • 5.bullet.py(子弹)

    • 6.button.py(play按钮)

    • 7.settings.py(游戏属性设置)

    • 8.scoreboard.py(分数)

    • 9.game_stats.py(游戏状态)

    • 10.music.py(音效)

    • 11.游戏图片/音效素材获取

    • 12.针对游戏过程中各种报错解决办法思路的提醒

    • 13.游戏完成阶段总结

  • 三、主.py文件转可执行.exe文件

    • 1.安装pyinstaller:

    • 2.主.py文件转可执行.exe文件

    • 3.转后事件处理

  • 四、报错情况分析以及解决办法

    • 1.双击alien_invasion.exe执行文件出现闪退

    • 2.双击alien_invasion.exe执行文件弹出“Faied to execute script ***”错误

  • 五、压缩.exe相关素材

一、项目环境背景介绍

1.Pycharm版本:社区2017.2.7版本

ce3d7fb90ef28f92626bb5515093a4eb.png

2.对应python版本:3.6.4版本

ef8d43148e8acf9c3200ef275ee518b6.png环境搭建的帖子(这位哥们写得很细的 点赞):https://blog.csdn.net/wardseptember/article/details/79965836

3.基于以上环境开发一个游戏

在游戏《外星人入侵》中,玩家控制着一艘最初出现在屏幕底部中央的飞船。玩家可以使用箭头键左右移动飞船,还可使用空格键进行射击。游戏开始时,一群外星人出现在天空中,他们在屏幕中向下移动。玩家的任务是射杀这些外星人。玩家将所有外星人都消灭干净后,将出现一群新的外星人,他们移动的速度更快。只要有外星人撞到了玩家的飞船或到达了屏幕底部,玩家就损失一艘飞船。玩家损失三艘飞船后,游戏结束。(本游戏附加各种音效)

4.游戏项目的目录结构如下
>

>D\Python-Projects

>a book of py

>Projects

>Project 1(alien_invasion) chapter 12-14

>alien_invasion

>images

>alien.bmp

>ship.bmp

>musics

>Bullet_biu.wav

>Explo_Large.wav

>Explo_Small.wav

>order_music.mp3

>alien_invasion.py(主文件)

>game_functions.py(功能函数)

>alien.py(外星人)

>ship.py(飞船)

>bullet.py(子弹)

>button.py(play按钮)

>settings.py(游戏属性设置)

>scoreboard.py(分数)

>game_stats.py(游戏状态)

>music.py(音效)

>Max_score.json(历史最高分记录文件)

二、项目过程中所有的.py文件代码

1.alien_invasion.py(主文件)
# coding: UTF-8# 项目1:外星人入侵# 系统自带的类或函数# import sys  # 退出游戏----集中在game_functions.py中使用,故这注释掉import pygame   # 含有开发游戏所需功能from pygame.sprite import Group     # 存储所有有效子弹的类# 自定义的类或函数from settings import Settings   # 对《外星人入侵》游戏中所有设置的类,如屏幕宽高…from ship import Ship   # 创建飞船的类from button import Button   # 创建按钮的类from game_stats import Game_Stats   # 创建跟踪游戏统计信息的类from scoreboard import Scoreboard   # 创建得分类from music import bg_music  # 背景音乐import game_functions as gf     # 所有的功能函def run_game():    # 初始化游戏并创建一个屏幕对象    pygame.init()    ai_settings = Settings()    screen = pygame.display.set_mode(        (ai_settings.screen_width, ai_settings.screen_height))    pygame.display.set_caption("外星人入侵")    # 初始化声音播放模块    pygame.mixer.init()    # 创建Play按钮    play_button = Button(ai_settings, screen, "Play")    # 创建一艘飞船    ship = Ship(ai_settings, screen)    # 创建一个用于存储子弹的编组    bullets = Group()    # 创建一个用于存储外星人的编组    aliens = Group()    # 创建存储游戏统计信息的实例    game_stats = Game_Stats(ai_settings)    # 创建记分牌    scoreb = Scoreboard(ai_settings, screen, game_stats)    # 创建外星人群    gf.create_fleet(ai_settings, screen, ship, aliens)    # 加载背景音乐    bg_music()    # 开始游戏的主循环    while True:        # 调用响应鼠标和键盘事件的函数        gf.check_events(ai_settings, screen, game_stats, scoreb, play_button, ship, aliens, bullets)        if game_stats.game_active:            # 调用背景音乐            gf.play_bg_music()            # 调用飞船水平持续移动的函数            ship.update()            # 调用关于子弹相关操作的函数            gf.update_bullets(ai_settings, screen, game_stats, scoreb, ship, aliens, bullets)            # 调用外星人向右移动的函数            gf.update_aliens(ai_settings, game_stats, scoreb, screen, ship, aliens, bullets)        # 调用更新屏幕上的图像并切换到新屏幕的函数        gf.update_screen(ai_settings, screen, game_stats, scoreb, ship, aliens, bullets, play_button)run_game()  # 此时运行的话 会弹出一个pygame窗口
2.game_functions.py(功能函数)
# coding: UTF-8# 《外星人入侵》运行的所有函数import sysimport pygamefrom bullet import Bulletfrom alien import Alienfrom time import sleepimport jsonimport musicdef play_bg_music():    """背景音乐"""    if not pygame.mixer.music.get_busy():        pygame.mixer.music.play()def check_keydown_events(event, ai_settings, screen, ship, bullets, game_stats, scoreb, aliens):    """"        响应鼠标按下操作    """    # 按右箭头飞船向右移动    if event.key == pygame.K_RIGHT:        ship.moving_right = True    # 按左箭头飞船向左移动    elif event.key == pygame.K_LEFT:        ship.moving_left = True    # 按空格键创建一颗子弹并将其加入到编组bullets中    elif event.key == pygame.K_SPACE:        fire_bullet(ai_settings, screen, ship, bullets)    # 按p开始游戏    elif event.key == pygame.K_p:        start_game(ai_settings, screen, ship, bullets, game_stats, scoreb,                   aliens)    # 按z暂停游戏3s    elif event.key == pygame.K_z:        sleep(2)    # 按q退出游戏并把最高分写入文件    elif event.key == pygame.K_q:        with open('Max_score.json', 'w', encoding='UTF-8') as file:            json.dump(game_stats.high_score, file)        sys.exit()def fire_bullet(ai_settings, screen, ship, bullets):    """        按照要求发射子弹数量    """    if len(bullets) < ai_settings.bullet_allowed:        music.bullet_biu()                              # 发射子弹的声音        new_bullet = Bullet(ai_settings, screen, ship)  # 如果还没有到达限制,就发射一颗子弹        bullets.add(new_bullet)                         # 创建一颗子弹,并将其加入到编组bullets中def start_game(ai_settings, screen, ship, bullets, game_stats, scoreb,               aliens):    """        P264中动手试一试14-1的练习:让玩家按p开始游戏    """    # 重置游戏统计信息    game_stats.reset_stats()    game_stats.game_active = True    # 重置记分牌图像    scoreb.prep_score()    scoreb.prep_high_score()    scoreb.prep_level()    scoreb.prep_ships()    # 清空外星人列表和子弹列表    aliens.empty()    bullets.empty()    # 创建一群新的外星人,并让飞船居中    create_fleet(ai_settings, screen, ship, aliens)    ship.center_ship()    # 暂停让用户反应一会    sleep(0.5)def check_keyup_events(event, ship):    """"        响应鼠标松开---飞船停下    """    if event.key == pygame.K_RIGHT:        ship.moving_right = False    elif event.key == pygame.K_LEFT:        ship.moving_left = Falsedef check_play_button(ai_settings, screen, game_stats, scoreb, play_button, ship,                      aliens, bullets, mouse_x, mouse_y):    """        在玩家单击Play按钮时开始游戏    """    button_clicked = play_button.button_rect.collidepoint(mouse_x, mouse_y)    # 单击Play按钮且游戏处于非活跃状态时----避免了游戏处于活跃状态下单击到了Play按钮区域重启游戏    if button_clicked and not game_stats.game_active:        """如果鼠标单击位置在msg_image_rect范围内则将游戏置于活跃状态"""        # # 重置游戏设置        ai_settings.initialize_dynamic_settings()        # 游戏开始后Play按钮隐藏起来        pygame.mouse.set_visible(False)        start_game(ai_settings, screen, ship, bullets, game_stats, scoreb, aliens)def check_events(ai_settings, screen, game_stats, scoreb, play_button, ship, aliens, bullets):    """        响应鼠标和键盘事件    """    # 游戏退出并把最高分写入文件    for event in pygame.event.get():        if event.type == pygame.QUIT:            with open('Max_score.json', 'w', encoding='UTF-8') as file:                json.dump(game_stats.high_score, file)            sys.exit()        # 响应Play按钮操作        elif event.type == pygame.MOUSEBUTTONDOWN:            mouse_x, mouse_y = pygame.mouse.get_pos()   # 该函数返回一个元组--获取鼠标单击Play按钮时的位置            check_play_button(ai_settings, screen, game_stats, scoreb, play_button, ship,                              aliens, bullets, mouse_x, mouse_y)        # 判读飞船向左还是向右移动        elif event.type == pygame.KEYDOWN:            check_keydown_events(event, ai_settings, screen, ship, bullets, game_stats, scoreb, aliens)        # 飞船停下        elif event.type == pygame.KEYUP:            check_keyup_events(event, ship)def update_screen(ai_settings, screen, game_stats, scoreb, ship, aliens, bullets, play_button):    """        更新屏幕上的图像并切换到新屏幕    """    # 每次循环时都重绘屏幕    screen.fill(ai_settings.bg_color)   # 先填充背景后绘制飞船    ship.blitem()    aliens.draw(screen)    # 在飞船后重绘所有子弹    for bullet in bullets.sprites():        bullet.draw_bullet()    # 显示得分    scoreb.show_score()    # 如果游戏处于非活动状态就绘制Play按钮    if not game_stats.game_active:        play_button.draw_button()    # 让最近绘制的屏幕可见    pygame.display.flip()def start_new_level(ai_settings, screen, game_stats, scoreb, ship, aliens, bullets):    """        当消灭干净外星人提高一个等级    """    if len(aliens) == 0:        # 删除现有子弹        bullets.empty()        # 逐渐提高速度加快游戏节奏        ai_settings.increase_speed()        # 当前屏幕外星人全部被消灭就提高一个等级        game_stats.level += 1        scoreb.prep_level()        # 创建一群新的外星人        create_fleet(ai_settings, screen, ship, aliens)  # 调用创建外星人群的函数def check_bullet_alien_collisions(ai_settings, screen, game_stats, scoreb, ship, aliens, bullets):    """子弹与外星人相撞后的操作"""    # 检查是否有子弹击中外星人    # 如果击中了就删除相应的子弹与外星人    collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)    """方法sprite.groupcollide()检查两个编组的成员之间的碰撞(碰撞是指游戏元素重叠在一起):    将每颗子弹同每个外星人的rect作比较 并返回一个字典 字典中的键为子弹  值为被击中的外星人"""    # 每消灭一个外星人都将加一个points且显示最新得分的图像    if collisions:        music.voice_small()                 # 子弹与外星人相撞的声音        for aliens in collisions.values():  # aliens指被同一颗子弹击中的外星人---是一个列表            game_stats.score += ai_settings.alien_points * len(aliens)            scoreb.prep_score()        check_high_score(game_stats, scoreb)    start_new_level(ai_settings, screen, game_stats, scoreb, ship, aliens, bullets)def update_bullets(ai_settings, screen, game_stats, scoreb, ship, aliens, bullets):    """        更新子弹位置并删除已消失的子弹    """    # 更新子弹位置    bullets.update()    # 删除已消失的子弹    for bullet in bullets.copy():        if bullet.rect.bottom <= 0:  # 当子弹底部越过屏幕顶部(0)时删除子弹            bullets.remove(bullet)    check_bullet_alien_collisions(ai_settings, screen, game_stats, scoreb, ship, aliens, bullets)def get_number_aliens_X(ai_settings, alien_width):    """        计算每行可容纳多少个外星人    """    availabble_space_x = ai_settings.screen_width - 2 * alien_width  # 一行可可容纳的水平长度    number_aliens_x = int(availabble_space_x / (2 * alien_width))  # 一行可容纳多少个外星人    return number_aliens_xdef get_number_rows(ai_settings, alien_height, ship_height):    """        计算屏幕可容纳多少行外星人    """    availables_space_y = (ai_settings.screen_height-ship_height-                          (3*alien_height))    number_rows = int(availables_space_y / (2 * alien_height))    return number_rowsdef create_alien(ai_settings, screen,  aliens, alien_number, row_number):    """        创建一个外星人并将其放在当前行    """    alien = Alien(ai_settings, screen)    alien_width = alien.rect.width    alien_height = alien.rect.height + 3    # 让外星人之间间隔大些    alien.x = alien_width + 2 * alien_width * alien_number  # 获取新建外星人所移动的位置    alien.rect.x = alien.x  # 新建外星人的位置    alien.rect.y = alien_height + 2 * alien_height * row_number  # 新行的位置    aliens.add(alien)def create_fleet(ai_settings, screen, ship, aliens):    """        创建外星人群    """    # 创建一个外星人并计算一行可容纳多少个外星人    # 外星人间距为外星人的宽度    alien = Alien(ai_settings, screen)    number_aliens_x = get_number_aliens_X(ai_settings, alien.rect.width)  # 一行可容纳外星人的个数    number_rows = get_number_rows(ai_settings, alien.rect.height,                                  ship.rect.height)   # 屏幕上可容纳外星人的行数    # 内外双循环创建外星人群    for row_number in range(number_rows):       # 外循环创建外星人行数        for alien_number in range(number_aliens_x):     # 内循环创建外星人            create_alien(ai_settings, screen, aliens, alien_number, row_number)  # 调用创建外星人的函数def check_fleet_edges(ai_settings, aliens):        """            有外星人到达边缘时采取相应的措施        """        for alien in aliens.sprites():            if alien.check_edges():                change_fleet_direction(ai_settings, aliens)                breakdef change_fleet_direction(ai_settings, aliens):    """        将整全外星人下移并改变它们的方向    """    for alien in aliens.sprites():        alien.rect.y += ai_settings.fleet_drop_speed    ai_settings.fleet_direction *= -1def check_aliens_bottom(ai_settings, game_stats, scoreb, screen, ship, aliens, bullets):    """检测外星人是否到达屏幕底部"""    screen_rect = screen.get_rect()    for alien in aliens.sprites():        if alien.rect.bottom >= screen_rect.bottom:            # 外星人触底爆炸声            music.voice_large()            # 有外星人到达屏幕后进行像飞船被撞后一样的操作            ship_aliens_hit(ai_settings, game_stats, scoreb, screen, ship, aliens, bullets)            breakdef ship_aliens_hit(ai_settings, game_stats, scoreb, screen, ship, aliens, bullets):    """        响应外星人飞船相撞的后续操作    """    # 外星人飞船相撞时 发出碰撞声音 ship_left减1    if game_stats.ships_left > 0:        music.voice_large()        game_stats.ships_left -= 1        # 更新屏幕上飞船的艘数        scoreb.prep_ships()    else:        game_stats.game_active = False        ai_settings.increase_wen()      # 游戏结束后alien的速度得回到最初为        pygame.mouse.set_visible(True)  # 游戏结束后Play按钮显示出来    # 清空外星人列表和子弹列表    aliens.empty()    bullets.empty()    # 创建一群新的外星人并将飞船重新出现在屏幕在底部中央    create_fleet(ai_settings, screen, ship, aliens)    ship.center_ship()    # 暂停让用户反应一会    sleep(0.5)def update_aliens(ai_settings, game_stats, scoreb, screen, ship, aliens, bullets):    """        更新外星人群中所有外星人的位置    """    check_fleet_edges(ai_settings, aliens)    aliens.update()    if pygame.sprite.spritecollideany(ship, aliens):        """        接收俩个实参--检测飞船和外星人是否发生碰撞:发生了---往下走;没发生---返回None        """        ship_aliens_hit(ai_settings, game_stats, scoreb, screen, ship, aliens, bullets)    # 检测是否有外星人到达屏幕底部    check_aliens_bottom(ai_settings, game_stats, scoreb, screen, ship, aliens, bullets)def check_high_score(game_stats, scoreb):    """检查是否诞生了新的最高得分"""    if game_stats.score > game_stats.high_score:        game_stats.high_score = game_stats.score        scoreb.prep_high_score()        
3.alien.py(外星人)
# coding: UTF-8# 创建外星人Alien类import pygamefrom pygame.sprite import Spriteclass Alien(Sprite):    """        表示单个外星人的类    """    def __init__(self, ai_sttings, screen):        super(Alien, self).__init__()        self.screen = screen        self.ai_settings = ai_sttings        # 加载外星人的图片并设置其rect属性        self.image = pygame.image.load('images/alien.bmp')        self.rect = self.image.get_rect()        # 设置外星人之间的间隔        self.rect.x = self.rect.width    # 将外星人左边距设置为外星人的宽度        self.rect.y = self.rect.height    # 将上边距设置为外星人的高度        # 存储外星人的准确位置        self.x = float(self.rect.x)    def check_edges(self):        """            如果外星人位于屏幕边缘就返回True        """        screen_rect = self.screen.get_rect()        if self.rect.right >= screen_rect.right:  # 外星人元素右边将要越过屏幕右边时的状态---此时处于触及屏幕右边缘            return True        elif self.rect.left <= 0:     # 外星人元素左边<= 0时代表将要越过屏幕左边---此时处于触及屏幕的左边缘            return True    def update(self):        """            向左或向右移动外星人        """        self.x += (self.ai_settings.alien_speed_factor                   * self.ai_settings.fleet_direction)  # 速度 * 移动方向        self.rect.x = self.x    def blitem(self):        """            在指定位置绘制外星人的位置        """        self.screen.blit(self.image, self.rect)        
4.ship.py(飞船)
# coding: UTF-8# 创建飞船Ship类import pygamefrom pygame.sprite import Spriteclass Ship(Sprite):    """        初始化飞船并设置其初始位置    """    def __init__(self, ai_settings, screen):        super().__init__()        self.screen = screen        self.ai_settings = ai_settings                # 加载飞船图像并获取其外接矩形        self.image = pygame.image.load('images/ship.bmp')        self.rect = self.image.get_rect()     # 获取飞船图片外接矩形(即是让其可以像矩形一样被处理)        self.screen_rect = self.screen.get_rect()        # 获取屏幕图片外接矩形(即是让其可以像矩形一样被处理)                # 将每搜新飞船放在屏幕底部中央        self.rect.centerx = self.screen_rect.centerx  # 将飞船的centerx与屏幕的centerx捆绑在一起        self.rect.bottom = self.screen_rect.bottom     # 将飞船的bottom与屏幕的bottom捆绑在一起        # 在飞船的属性center中存储小数值        self.center = float(self.rect.centerx)        # 飞船水平移动标志        self.moving_right = False        self.moving_left = False    def update(self):        """            根据移动标志调整飞船水平位置        """        # 飞船持续向右移动        if self.moving_right and self.rect.right < self.screen_rect.right:            self.center += self.ai_settings.ship_speed_factor        # 飞船持续向左移动        if self.moving_left and self.rect.left > 0:            self.center -= self.ai_settings.ship_speed_factor        # 根据self.center更新image_rect对象        self.rect.centerx = self.center            def blitem(self):        """            在指定位置绘制飞船        """        self.screen.blit(self.image, self.rect)    def center_ship(self):        """让飞船在屏幕底部居中"""        self.ship_center = self.screen_rect.centerx
5.bullet.py(子弹)
# coding: UTF-8# 创建子弹Bullet类import pygamefrom pygame.sprite import Spriteclass Bullet(Sprite):    """        一个对飞船发射的子弹进行管理的类    """    def __init__(self, ai_settings, screen, ship):        """            在飞船所处的位置创建一个子弹对象        """        super(Bullet, self).__init__()  # 继承Sprite        self.screen = screen        # 在(0, 0)位置上创建一个表示子弹的矩形,并设置其位置        self.rect = pygame.Rect(0, 0, ai_settings.bullet_width, ai_settings.bullet_height)        self.rect.centerx = ship.rect.centerx    # 将子弹的centerx设置为飞船的centerx        self.rect.top = ship.rect.top            # 将子弹的top属性设置为飞船的top属性  让子弹看起来是从飞船中射出的        # 将子弹的垂直位置用小数表示,方便调节速度        self.y = float(self.rect.y)        # 获取子弹其他属性        self.bullet_color = ai_settings.bullet_color        self.bullet_speed_factor = ai_settings.bullet_speed_factor    def update(self):        """           向上移动子弹        """        # 更新表示子弹位置的小数值        self.y -= self.bullet_speed_factor        # 更新表示子弹的rect的位置        self.rect.y = self.y    def draw_bullet(self):        """            在屏幕上绘制子弹        """        pygame.draw.rect(self.screen, self.bullet_color, self.rect)  # 顺序为1 2 3 :2填充3,出现在1屏幕上
6.button.py(play按钮)
# coding: UTF-8# 创建开启游戏的play按钮import pygame.fontclass Button():    """初始化按钮的属性"""    def __init__(self, ai_settings, screen, msg):        self.screen = screen        self.screen_rect = screen.get_rect()        # 设置按钮的尺寸和其他属性        self.width, self.height = 200, 50        self.button_color = (0, 208, 0)     # 按钮框的颜色--和外星人一样的颜色        self.text_color = (255, 0, 0)   # 文本颜色--红色        self.font = pygame.font.SysFont(None, 48)   # 使用默认字体,字号为48        # 设置按钮的rect并使其居中        self.button_rect = pygame.Rect(0, 0, self.width, self.height)        self.button_rect.center = self.screen_rect.center        # 按钮的标签只需要创建一次        self.prep_msg(msg)    def prep_msg(self, msg):        """            将文本渲染成图像并使其在按钮上居中        """        self.msg_image = self.font.render(msg, True, self.text_color)    # 将存储在msg中的文本转换成图像        self.msg_image_rect = self.msg_image.get_rect()        self.msg_image_rect.center = self.button_rect.center    def draw_button(self):        """绘制一个用颜色填充的按钮,然后绘制文本"""        self.screen.fill(self.button_color, self.button_rect)        self.screen.blit(self.msg_image, self.msg_image_rect)        
7.settings.py(游戏属性设置)
# coding: UTF-8# 创建Settings设置类---功能对应的设置class Settings():    """        《外星人入侵》的所有设置的类    """    def __init__(self):        """            初始化游戏的静态设置        """        # 屏幕宽度和高度、背景颜色设置        self.screen_width = 1200        self.screen_height = 800        self.bg_color = (230, 230, 230)        # 飞船数量的设置        self.ship_limit = 3        # 子弹设置        self.bullet_width = 3        self.bullet_height = 10        self.bullet_color = 255, 0, 0        # 设置屏幕上可同时出现的子弹数        self.bullet_allowed = 8        # 外星人设置        self.fleet_drop_speed = 10        # 加快游戏的节奏的速度        self.speedup_scale = 1.1        # 提高外星人得分节奏        self.score_scale = 1.5        self.initialize_dynamic_settings()    def initialize_dynamic_settings(self):        """初始化随游戏进行而变化的动态设置"""        # 飞船移动速度        self.ship_speed_factor = 2.5        # 子弹移动速度        self.bullet_speed_factor = 2        # 外星人移动速度        self.alien_speed_factor = 1        # 每个外星人初始得分点        self.alien_points = 50        # fleet_direction为1表示向右移动  为-1表示向左移动        self.fleet_direction = 1    def increase_wen(self):        """返回最初速度"""        self.alien_speed_factor = 1        # print("游戏重新开始后的初始速度:" + str(self.alien_speed_factor))    def increase_speed(self):        """逐渐提高速度设置"""        self.ship_speed_factor *= self.speedup_scale        self.bullet_speed_factor *= self.speedup_scale        self.alien_speed_factor *= self.speedup_scale        # print("游戏过程中依次累加的速度:" + str(self.alien_speed_factor) + "\n")        # 逐渐提高外星人单次得分        self.alien_points = int(self.alien_points * self.score_scale)        # print(self.alien_points)
8.scoreboard.py(分数)
# # coding: UTF-8# # 创建得分Score类import pygamefrom pygame.sprite import Groupfrom ship import Shipclass Scoreboard():    """显示得分信息的类"""    def __init__(self, ai_settings, screen, game_stats):        """初始化显示得分涉及的属性"""        self.screen = screen        self.screen_rect = screen.get_rect()        self.ai_settings = ai_settings        self.game_stats = game_stats        # 显示得分信息时使用的字体设置        self.text_color = (30, 30, 30)        self.font = pygame.font.SysFont(None, 48)        self.prep_images()    def prep_images(self):        """准备包含 最高得分、当前得分、游戏等级、飞船 的图像"""        # 当前得分图像        self.prep_score()        # 最高得分图像        self.prep_high_score()        # 等级图像        self.prep_level()        # 飞船组图像        self.prep_ships()    def prep_score(self):        """将当前得分转换为一幅渲染的图像"""        round_score = round(self.game_stats.score, -1)  # 使得分为10的倍数  -1----10的倍数   -2--100的倍数  -3--1000的倍数        score_str = "score:" + "{:,}".format(round_score)        self.score_image = self.font.render(score_str, True, self.text_color,                                                self.ai_settings.bg_color)        # 将当前得分放在屏幕右上角        self.score_image_rect = self.score_image.get_rect()        self.score_image_rect.right = self.screen_rect.right - 20        self.score_image_rect.top = 20    def prep_high_score(self):        """将最高得分转换为一幅渲染的图像"""        high_round_score = round(self.game_stats.high_score, -1)  # 使得分为10的倍数  -1----10的倍数   -2--100的倍数  -3--1000的倍数        high_score_str = "Mscore:" + "{:,}".format(high_round_score)        self.high_score_image = self.font.render(high_score_str, True, self.text_color,                                            self.ai_settings.bg_color)        # 将最高得分放在顶部屏幕中央        self.high_score_image_rect = self.high_score_image.get_rect()        self.high_score_image_rect.centerx = self.screen_rect.centerx        self.high_score_image_rect.top = self.score_image_rect.top    def prep_level(self):        """将等级转换为一幅渲染的图像"""        self.level_image = self.font.render(("lev:" + str(self.game_stats.level)), True,                                            self.text_color, self.ai_settings.bg_color)        # 将等级放在等分下面        self.level_image_rect = self.level_image.get_rect()        self.level_image_rect.right = self.score_image_rect.right        self.level_image_rect.top = self.score_image_rect.bottom + 10    def prep_ships(self):        """显示还剩下多少艘飞船"""        self.ships = Group()        for ship_number in range(self.game_stats.ships_left):            ship = Ship(self.ai_settings, self.screen)            ship.rect.x = 10 + ship_number * ship.rect.width            ship.rect.top = 10            self.ships.add(ship)    def show_score(self):        """在屏幕上显示当前得分和最高得分"""        self.screen.blit(self.score_image, self.score_image_rect)        self.screen.blit(self.high_score_image, self.high_score_image_rect)        self.screen.blit(self.level_image, self.level_image_rect)        # 绘制飞船        self.ships.draw(self.screen)        
9.game_stats.py(游戏状态)
# coding: UTF-8# 创建跟踪游戏统计信息的Game_Stats类import jsonclass Game_Stats():    """跟踪游戏统计信息的类"""    def __init__(self, ai_settings):        self.ai_settings = ai_settings        self.reset_stats()        # 游戏刚启动时处于活动状态        self.game_active = False        # 在任何情况情况下都不应重置最高得分,加载历史最高分        self.high_score = 0        with open('Max_score.json', encoding='UTF-8') as file:            self.high_score = json.load(file)    def reset_stats(self):        """初始化在游戏运行期间可能变化的统计信息"""        self.ships_left = self.ai_settings.ship_limit        self.score = 0  # 每次有新的分数都应该重置        self.level = 1  # 设置游戏等级
10.music.py(音效)
# coding: UTF-8# 关于游戏中各种声音效果的模块import pygamedef voice_large():    # 外星人到达了屏幕底部或者撞到飞船的大爆炸声    explosion_large = pygame.mixer.Sound("musics/Explo_Large.wav")    explosion_large.play()def voice_small():    # 增加子弹和外星人碰撞的小爆炸声    explosion_small = pygame.mixer.Sound("musics/Explo_Small.wav")    explosion_small.play()def bullet_biu():    # 增加子弹射出的biu声    bullet_whiz = pygame.mixer.Sound("musics/Bullet_biu.wav")    bullet_whiz.play()def bg_music():    # 游戏背景音乐(若游戏开始就一直播放)    pygame.mixer.music.load("musics/order_music.mp3")    
11.游戏图片/音效素材获取

(1)链接:https://pan.baidu.com/s/1A4VS59igzuEQi1JoDBabnA

         提取码:8lp3 (包括图片以及音效)

(2)另外如果读者想换音效 可进下面链接进行寻找  

      链接:https://www.aigei.com/music(我也是从这扒的)

12.针对游戏过程中各种报错解决办法思路的提醒

(1)最关键的一点:要抓住最终报错语句 那句==很很很关键== 根据这句能够快速定位报错位置以及原因(2)学会百度筛选有效解决办法----==这个能力至关重要==(3)找文件中逻辑错误或书写前后不统一的错误---这个是大部分人会犯的错误的 ==你以为是那样的 实际不是那样的==

13.游戏完成阶段总结

从开始动手编写到游戏功能较完善的阶段 花了2周 我现阶段还是大学生每天有课要上 每天抽时间学 python也是自学一步一步慢慢走过来的  这其中遇到的问题也是千奇百怪的 让人头大 (难怪民间有种说法--计算机是玄学!!!)但很庆幸的是每个当时看起来艰难不可理解的报错都被我ko了 这种感觉 经历过的就会大大的懂 我个人是很享受那个过程的 进展缓慢每天打怪但每天都有收获 如该游戏过程中出现几次无某某库的时候 用“进入cmd 用pip install 报错缺少的库名”办法基本能够解决 嘻嘻…好啦 接下来让游戏放在朋友电脑上也可以玩 即使在没有相应的pycharm/python的环境也可。

三、主.py文件转可执行.exe文件

1.安装pyinstaller:
win+r进入cmd界面→pip install pyinstaller→等待成功(pip list可检测是否安装pyinstaller)

e24a7e4ff615311566d0c342cd9f0d46.png

2.主.py文件转可执行.exe文件

(1)在cmd界面中进入游戏中所有.py文件同在的那个文件夹:

d:→cd Python-Projects\a book of py\Projects\Project1(alien_invasion) chapter 12-14\alien_invasion

(2)打包主.py文件:

pyinstaller -F -w --add-data "musics/*.mp3;./musics" --add-data "musics/*.mav;./musics" alien_invasion.py

几点说明:

i.*通配符,表示music文件夹里所有的mp3文件、所有的wav文件 要使用双引号ii.windows系统要使用分号作为文件原本的路径和要存放的路径的分隔符,这一点和linux系统不一样,linux系统使用冒号iii.要存放的路径 ./music表示最外层目录下的music目录

参数解析:

pyinstaller  xxx.py   打包成一个需要依赖文件的exepyinstaller -F xxx.py  打包成一个单独的exe,但是会有黑窗口pyinstaller -F  -w xxx.py 打包成一个单独的exe去且除黑窗口==(游戏中没有用多媒文件用这条命令)==

ccb15a61af3529d0d0b83227c71f9952.png3e3f68971611c421acf08e4c84ee897e.png

3.转后事件处理

打包成功后 在alien_invasion文件夹在==新出现三个文件==---build文件夹、dist文件夹、alien_invasion.spec文件 :5d2a2f01f86056e40a4ac99ce31a8711.png可执行.exe文件在dish文件夹中 双击运行它就可:588478d2ad3fb34b282058ec7d825615.png最终出现游戏运行界面 play it 哈哈哈…看着蛮顺利的是不 其实不然各种报错后面详说9e2b6694f49842184fbf50d970314ca8.png

四、报错情况分析以及解决办法

1.双击alien_invasion.exe执行文件出现闪退

(1)闪退理由:打包的时候只打包了alien_invasion.py主文件 生成的alien_invasion.exe在dist文件夹 与游戏所依赖的其他.py不在同一个目录下 ==所以所以所以!==.exe文件在运行的时候找!不!到!相关的模块!故而不能执行!闪退(.exe在黄色箭头文件夹中 其他.py文件在红色框框所在文件夹中)55765390b1515ccb2182997858ef2455.png

(2)解决办法:把.exe文件抬到所导入模块所在的文件夹内就可以了。当然也可以把导入的模块搬到.exe文件所在的文件夹下,同一个道理的。

2.双击alien_invasion.exe执行文件弹出“Faied to execute script ***”错误

(1)分析:出现这个错误的时候 一头的雾水 就是简单一句话 错误定位也无处下手  度娘上针对这个错误也是各种说法 (2)思路:为了看到具体报错情况  后面所性把打包新出现的三个文件删除 重回到打包步骤----还记得上面有个“参数解析”不   ==把命令中的-w去掉==

pyinstaller -F --add-data "musics/*.mp3;./musics" --add-data "musics/*.mav;./musics" alien_invasion.py

这个时候再双击.exe可看到具体报错情况以及定位:

decdb6ea7df4983ff4aae76f72bee1c0.png

(3)看到没 说打不开音效文件 报错理由其实和报错情况1(1)是一样一样的 故解决办法也和报错情况1(2)一样一样的==(当然啦如果你解决了报错情况1的问题 原则上是不会出现情况2的错误的 ---因为你都移动到同一个目录下去啦)==

五、压缩.exe相关素材

终于!终于!终于!---要发给朋友玩啦(要记得把相关素材放进去哦 什么图片呀、音效呀等 使用说明是我自己为了朋友愉快的玩耍加进去哈)a9c5473e6300256305be9022cca3da90.png

这里我也把游戏放上来了哈  想试玩的朋友 可以下载玩玩链接:https://pan.baidu.com/s/1lu9RHKrxjyBC7vfxMALQZA 提取码:2qn0

ps:由于打包成.exe时自动默认把anaconda下无用的包或库也打包进去了 导致.exe文件过大 这个问题后期找时间倒腾倒腾 也会找时间会对游戏改进完善的  主要是时间…

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值