当前位置: 移动技术网 > IT编程>脚本编程>Python > 《python编程:从入门到实践的》外星人入侵的代码

《python编程:从入门到实践的》外星人入侵的代码

2020年10月09日  | 移动技术网IT编程  | 我要评论
alien.py#管理外星人的类import pygamefrom pygame.sprite import Spriteclass Alien(Sprite): def __init__(self,ai_settings,screen): super(Alien,self).__init__() self.ai_settings = ai_settings self.screen = screen #加载外星人图片,并设

alien.py

#管理外星人的类

import pygame
from pygame.sprite import Sprite

class Alien(Sprite):
    def __init__(self,ai_settings,screen):
        super(Alien,self).__init__()
        self.ai_settings = ai_settings
        self.screen = screen

        #加载外星人图片,并设置rect属性,类类前面加载飞船图片
        self.image = pygame.image.load('images/alien.bmp')
        self.rect = self.image.get_rect()

        #将外星人放在屏幕的左上角附近(距离左边和上边有一个外星人的距离),若是要设置在左上角可以直接赋值0
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        #将外星人的坐标转化成可以存储小数的float类型,这样位置更加准确
        self.x = float(self.rect.x)
        self.y = float(self.rect.y)

    def blitme(self):
        #绘制外星人
        self.screen.blit(self.image,self.rect)

    #检查外星人是否撞到边缘
    def check_edges(self):
        """ 如果外星人位于屏幕边缘,就返回 True"""
        screen_rect = self.screen.get_rect()
        #如果外星人的 rect 的 right 属性大于或等于屏幕的 rect 的 right 属性,则位于右边缘
        if self.rect.right >= screen_rect.right:
            return True
        #如果外星人的 rect 的 left 属性小于或等于 0,则位于左边缘
        elif self.rect.left <= 0:
            return True

    def update(self):
        """ 向右或向左移动外星人 """
        self.x += (self.ai_settings.alien_speed_factor *
                   self.ai_settings.fleet_direction)
        self.rect.x = self.x

alien_invasion.py

#窗口居中需要
import os

#pygame包含游戏需要的功能
import pygame

from settings import Settings
from ship import Ship
import game_functions as gf
from alien import Alien
from game_stats import Gamestats
from button import Button
from scoreboard import Scoreboard

#导入了 pygame.sprite 中的 Group 类
from pygame.sprite import Group

def run_game():
    #初始化背景设置,让pygame可以正常工作
    pygame.init()
    #创建Settings的实例
    ai_settings = Settings()

    #设置窗口居中显示
    os.environ['SDL_VIDEO_CENTERED'] = '1'

    #创建显示窗口,(1200,800)是元组,要注意添加括号;创建了一个宽 1200 像素、高 800 像素的游戏窗口
    #screen是一个surface, surface 是屏幕的一部分,用于显示游戏元素,每个游戏元素都是一个surface(外星人或飞船)
    #激活动画循环后,每次循环都会重绘这个surface
    #screen = pygame.display.set_mode((1200,800))
    #设置背景色后会有黑色闪过,可以先初始化一个小窗口然后再初始化创建的窗口:screen = pygame.display.set_mode((1,1))
    screen = pygame.display.set_mode((1,1))
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    #设置窗口标题
    pygame.display.set_caption('外星人入侵')

    # 创建ship的实例:创建一艘飞船
    ship = Ship(screen,ai_settings)

    #创建外星人实例
    alien = Alien(ai_settings,screen)

    #创建一个编组group,用于存储所有有效的子弹,以便能够管理发射出去的所有子弹。这个编组将是 pygame.sprite.Group 类的一个实例
    #pygame.sprite.Group类类似于列表,但提供了有助于开发游戏的额外功能
    bullets = Group()

    #创建很多外星人,类似创建很多子弹
    aliens = Group()

    #默认的是黑色的,可以设置屏幕背景色
    #bg_color = (230,230,230)

    # 创建外星人群,这个不能放在while中,不然移动会很慢
    gf.creat_fleet(ai_settings, screen, ship, aliens)

    #创建存储游戏信息的类的实例
    stats = Gamestats(ai_settings)

    # 创建分数
    sb = Scoreboard(ai_settings, screen, stats)

    # 创建Play按钮
    play_button = Button(ai_settings, screen, "Play")

    #开始游戏主循环
    while True:
        #管理事件
        gf.check_events(ai_settings,screen,stats,sb, play_button,ship,aliens,bullets)
        #若是为True,这些都会更新,但若是为False,则飞船、子弹、外星人不会重新更新
        if stats.game_active:
            #飞船位置更新
            ship.update()
            #更新子弹
            gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets)
            #更新外星人
            #在更新子弹后再更新外星人的位置,因为稍后要检查是否有子弹撞到了外星人
            gf.update_aliens(ai_settings, stats, screen, sb, ship, aliens, bullets)
        #更新屏幕
        gf.update_screen(ai_settings, screen, stats, sb, ship,aliens, bullets, play_button)

#初始化游戏,开始运行主循环
run_game()

bullet.py

#子弹的类

import pygame
from pygame.sprite import Sprite

#Bullet继承了从模块pygame.sprite中导入的类Sprite
#在pygame.sprite模块里面包含了一个名为Sprite类,他是pygame本身自带的一个精灵
# 通过使用精灵,可将游戏中相关的元素编组,进而同时操作编组中的所有元素
class Bullet(Sprite):
    def __init__(self,ai_setings,screen,ship):
        #python3也可以这样写: super().__init__()
        super(Bullet,self).__init__()
        self.screen = screen

        #创建一个子弹,但是子弹并非是基于图像的(跟前面的飞船不同),因此必须使用pygame.Rect()类从空白开始创建一个矩形
        #创建时必须提供矩形左上角x,y的坐标以及宽和高
        self.rect = pygame.Rect(0,0,ai_setings.bullet_screen_width,ai_setings.bullet_screen_height)
        #将子弹的x位置设置的与飞船的相同
        self.rect.centerx = ship.rect.centerx
        #将子弹的top设置的与飞行的top相同,这样看起来子弹是从飞船射出的
        self.rect.top = ship.rect.top

        #将子弹的y坐标设置成小数(移动的速度不一定是整数)
        self.y = float(self.rect.y)

        #获取子弹的颜色
        self.color = ai_setings.bullet_bg_color
        #获取子弹的速度
        self.speed_factor = ai_setings.bullet_speed_factor

    def update(self):
        #子弹向上移动,y会变小
        self.y -= self.speed_factor
        #更新子弹的位置
        self.rect.y = self.y

    def draw_bullet(self):
        #在屏幕上绘制子弹
        pygame.draw.rect(self.screen,self.color,self.rect)

button.py

#创建按钮

import pygame

class 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 = (120, 255, 100)
        self.text_color = (255, 255, 255)
        #字体
        self.font = pygame.font.SysFont(None, 48)

        # 创建按钮的rect对象,并使其居中
        self.rect = pygame.Rect(0, 0, self.width, self.height)
        self.rect.center = self.screen_rect.center

        # 按钮的标签只需创建一次
        #Pygame通过将你要显示的字符串渲染为图像来处理文本
        self.prep_msg(msg)

    #将msg渲染为图像,并使其在按钮上居中
    def prep_msg(self, msg):
        #将存储在msg中的文本转换为图像,然后将该图像存储在msg_image中
        #方法font.render()还接受一个布尔实参,该实参指定开启还是关闭反锯齿功能(反锯齿让文本的边缘更平滑)。余下的两个实参分别是文本颜色和背景色
        #启用了反锯齿功能,并将文本的背景色设置为按钮的颜色
        self.msg_image = self.font.render(msg, True, self.text_color, self.button_color)
        self.msg_image_rect = self.msg_image.get_rect()
        self.msg_image_rect.center = self.rect.center

    # 绘制一个用颜色填充的按钮,再绘制文本
    def draw_button(self):
        #调用screen.fill()来绘制表示按钮的矩形
        self.screen.fill(self.button_color, self.rect)
        #调用screen.blit(),并向它传递一幅图像以及与该图像相关联的rect对象,从而在屏幕上绘制文本图像
        self.screen.blit(self.msg_image, self.msg_image_rect)

game_functions.py

#管理函数,避免 alien_invasion.py 太长

#退出游戏时需要用sys.exit()
import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleep

#按下按键
def check_keydown_events(event,ai_settings,screen,ship,bullets):
    # 如果按右箭头,移动标志为True
    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
    #如果按空格键,就发射子弹
    elif event.key == pygame.K_SPACE:
        fire_bullets(ai_settings, bullets, screen, ship)
    #按q键退出游戏
    elif event.key == pygame.K_q:
        sys.exit()

#松开按键
def check_keyup_events(event,ship):
    # 如果松开右箭头,移动标志位False
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    elif event.key == pygame.K_LEFT:
        ship.moving_left = False

#发射子弹
def fire_bullets(ai_settings,bullets,screen,ship):
    # 若是屏幕上的子弹数目少于设置的数目,则可以创建新的子弹,否则点击空格无效
    if len(bullets) < ai_settings.bullet_allowed:
        # 按下空格键后,创建一个子弹
        new_bullet = Bullet(ai_settings, screen, ship)
        # 将子弹加入编组中
        bullets.add(new_bullet)

#检查鼠标点击位置是否在按钮的区域内
def check_play_button(ai_settings, screen, stats, sb,play_button, ship, aliens, bullets, mouse_x, mouse_y):
    """在玩家单击Play按钮时开始新游戏"""
    # 重置游戏设置,将游戏中的子弹等速度重置
    ai_settings.initialize_dynamic_settings()
    # 开始游戏,隐藏光标
    pygame.mouse.set_visible(False)
    button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
    #判断当点击了按钮且游戏的状态为不活跃状态时
    if button_clicked and not stats.game_active:
        # 重置游戏统计信息
        stats.reset_stats()
        #分数重置
        sb.prep_score()
        #等级重置
        sb.prep_level()
        #刷新飞船数目
        sb.prep_ships()
        #游戏状态为活跃
        stats.game_active = True
        # 清空外星人列表和子弹列表
        aliens.empty()
        bullets.empty()

        # 创建一群新的外星人,并让飞船居中
        creat_fleet(ai_settings, screen, ship, aliens)
        ship.center_ship()

#管理事件的函数
def check_events(ai_settings,screen,stats, sb,play_button,ship,aliens,bullets):
    # 监视键盘和鼠标事件
    for event in pygame.event.get():
        # 单击窗口关闭按钮,退出游戏
        if event.type == pygame.QUIT:
            sys.exit()

        #按下按键
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,ai_settings,screen,ship,bullets)
        #松开按键
        elif event.type == pygame.KEYUP:
            check_keyup_events(event,ship)

        #点击开始按钮
        elif event.type == pygame.MOUSEBUTTONDOWN:
            #获取点击鼠标时的x和y坐标
            mouse_x, mouse_y = pygame.mouse.get_pos()
            #检查是否点击鼠标,若是则开始游戏
            check_play_button(ai_settings, screen, stats,sb, play_button, ship, aliens, bullets, mouse_x, mouse_y)

#更新屏幕
def update_screen(ai_settings,screen,stats,sb,ship,aliens,bullets,play_button):
    # 每次循环都重绘屏幕的背景色
    # screen.fill(bg_color)
    screen.fill(ai_settings.bg_color)
    # 绘制飞船,并确保在背景色前面,不然会被遮挡
    ship.blitme()
    #绘制外星人
    #aliens.blitme()
    aliens.draw(screen)
    # 方法bullets.sprites() 返回一个列表,其中包含编组bullets 中的所有精灵
    # 在屏幕上发射所有子弹,在飞船和外星人后面绘制
    for bullet in bullets.sprites():
        bullet.draw_bullet()

    # 显示得分
    sb.show_score()
    # 如果游戏处于非活动状态,就绘制Play按钮
    if not stats.game_active:
        play_button.draw_button()

    # 不断更新屏幕,来显示元素的新位置
    # 每次运行while时都显示一个新屏幕,并擦去旧屏幕
    pygame.display.flip()

#更新子弹
def update_bullets(ai_settings, screen, stats, sb, ship, aliens,bullets):
    # 子弹位置更新,对编组调用 update() 时,编组将自动对其中的每个精灵调用 update()
    bullets.update()
    # 删除已经消失的子弹
    # 不能在列表或者编组中删除,可以用copy()来遍历编组的副本
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)
    check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship, aliens, bullets)

#击中外星人后清除子弹和外星人,当外星人为0时再生成新的外星人
def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship, aliens, bullets):
    # 检查是否有子弹击中外星人,有则删除相应的子弹和外星人
    # 码遍历编组bullets中的每颗子弹,再遍历编组aliens中的每个外星人。每当有子弹和外星人的rect重叠时,groupcollide()就在它返回的字典中添加一个键值对
    # 两个实参True告诉Pygame删除发生碰撞的子弹和外星人
    # 若是要模拟能够穿行到屏幕顶端的高能子弹——消灭它击中的每个外星人,可将第一个布尔实参设置为False,并让第二个布尔实参为True。这样被击中的外星人将消失,但所有的子弹都始终有效,直到抵达屏幕顶端后消失。
    collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
    #有子弹撞到外星人时,Pygame返回一个字典(collisions)。我们检查这个字典是否存在,如果存在,就将得分加上一个外星人值的点数
    if collisions:
        #遍历字典,确保每个外星人都会计分
        for aliens in collisions.values():
            stats.score += ai_settings.alien_points * len(aliens)
            sb.prep_score()
        #每次有外星人被消灭都会重新更新最高分
        check_high_score(stats, sb)
    # 判断外星人是否为0,若是进行下面的操作
    if len(aliens) == 0:
        # 清空子弹
        bullets.empty()
        #增加飞船,子弹,外星人的速度
        ai_settings.increase_speed()
        # 提高等级,所有外星人被消灭就提升一个等级
        stats.level += 1
        sb.prep_level()
        # 创建新的外星人
        creat_fleet(ai_settings, screen, ship, aliens)

#计算可以放多少行外星人
def get_number_rows(ai_settings,ship_height,alien_height):
    available_space_y = (ai_settings.screen_height -
                         (3 * alien_height) - ship_height)
    number_rows = int(available_space_y / (2 * alien_height))
    return number_rows

#计算一行可以放多少个外星人
def get_number_aliens_x(ai_settings,alien_width):
    # 除去屏幕2边的间距(一个外星人的距离),剩余可以放外星人的宽度
    available_space_x = ai_settings.screen_width - 2 * alien_width
    # 每个外星人之间有一个外星人宽度的距离,用int获取可以放外星人的数目(整数)
    number_aliens_x = int(available_space_x / (2 * alien_width))
    return number_aliens_x

def create_alien(ai_settings, screen, aliens, alien_number, row_number):
    # 创建一个外星人实例
    alien = Alien(ai_settings, screen)
    # 获取外星人的宽度
    alien_width = alien.rect.width
    # 计算每个外星人的x坐标
    alien.x = alien_width + 2 * alien_width * alien_number
    alien.rect.x = alien.x
    # 计算每个外星人的y坐标
    alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
    aliens.add(alien)

#创建外星人
def creat_fleet(ai_settings, screen, ship, aliens):
    alien = Alien(ai_settings, screen)
    #number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)


    #一行创建多个外星人
    #for alien_number in range(number_aliens_x):
        #create_alien(ai_settings,screen,alien_number,aliens)

    number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)
    number_rows = get_number_rows(ai_settings, ship.rect.height,
                                  alien.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():
        #如果外星人位于边缘则返回True
        if alien.check_edges():
            #外星人位于边缘则下移并改变方向
            change_fleet_direction(ai_settings, aliens)
            #退出循环
            break

#若是外星人到达边缘,就将其下移,并改变方向
def change_fleet_direction(ai_settings, aliens):
    #遍历外星人群
    for alien in aliens.sprites():
        #所有的外星人都下移
        alien.rect.y += ai_settings.fleet_drop_speed
    #将外星人左右移动的值乘-1,以此来改变左右移动的方向
    ai_settings.fleet_direction *= -1

#如果外星人和飞船相撞,则清空屏幕,重新开始游戏
def ship_hit(ai_settings,stats,screen,sb,ship,aliens,bullets):
    #若是飞船数大于0,则可以重新开始
    if stats.ships_left > 0:
        #若外星人和飞船相撞则减去一个飞船
        stats.ships_left -= 1
        # 更新飞船
        sb.prep_ships()
        #清空飞船和子弹
        aliens.empty()
        bullets.empty()
        #重新创建外星人
        creat_fleet(ai_settings,screen,ship,aliens)
        #将飞船放到屏幕中间
        ship.center_ship()
        #休眠1s
        sleep(1)
    #若飞船数没有大于0,游戏结束
    else:
        stats.game_active = False
        #游戏为不活跃状态时,显示光标
        pygame.mouse.set_visible(True)

#如果外星人到达屏幕底部,游戏结束
def check_aliens_bottom(ai_settings,stats,screen,sb,ship,aliens,bullets):
    #屏幕属性
    screen_rect = screen.get_rect()
    #遍历外星人
    for alien in aliens.sprites():
        #若外星人的rect.bottom大于屏幕的rect.bottom,则外星人到达屏幕底部
        if alien.rect.bottom >= screen_rect.bottom:
            #外星人到达底部,则相当于外星人和飞船相撞
            ship_hit(ai_settings, stats, screen, sb,ship, aliens, bullets)
            #结束循环
            break

#更新外星人的位置
def update_aliens(ai_settings,stats,screen,sb,ship,aliens,bullets):
    # 检查是否有外星人位于边缘,若有则更新外星人的位置
    check_fleet_edges(ai_settings, aliens)
    aliens.update()
    #若是外星人和飞船碰到了就执行后面的
    #方法spritecollideany()接受两个实参:一个精灵和一个编组,在这里,它遍历编组aliens,并返回它找到的第一个与飞船发生了碰撞的外星人
    if pygame.sprite.spritecollideany(ship,aliens):
        ship_hit(ai_settings,stats,screen,sb,ship,aliens,bullets)
    #外星人到达底部,则相当于外星人和飞船相撞
    check_aliens_bottom(ai_settings, stats, screen, sb,ship, aliens, bullets)

#检查得分
def check_high_score(stats, sb):
    """检查是否诞生了新的最高得分"""
    #比较当前得分和最高分,若当前的大,则将分数赋值给最高分
    if stats.score > stats.high_score:
        stats.high_score = stats.score
        sb.prep_high_score()

game_stats.py

#根据游戏统计信息的类

class Gamestats():
    def __init__(self,ai_settings):
        self.ai_setting = ai_settings
        self.reset_stats()
        #游戏刚开始时游戏处于非活跃状态
        self.game_active = False
        # 在任何情况下都不应重置最高得分
        self.high_score = 0

    def reset_stats(self):
        #ships_left是飞船的数目
        self.ships_left = self.ai_setting.ship_limit
        #分数
        self.score = 0
        #等级
        self.level = 1

scoreboard.py

#计分

import pygame.font
from pygame.sprite import Group
from ship import Ship

class Scoreboard():
    """显示得分信息的类"""
    def __init__(self, ai_settings, screen, stats):
        """初始化显示得分涉及的属性"""
        self.screen = screen
        self.screen_rect = screen.get_rect()
        self.ai_settings = ai_settings
        self.stats = stats

        # 显示得分信息时使用的字体设置
        self.text_color = (30, 30, 30)
        #实例化一个字体对象
        self.font = pygame.font.SysFont(None, 48)
        # 准备初始得分图像
        self.prep_score()
        #最高分展示
        self.prep_high_score()
        #展示等级
        self.prep_level()
        #显示还剩多少飞船
        self.prep_ships()

    def prep_score(self):
        """将得分转换为一幅渲染的图像"""
        #将stats.score的值圆整到最近的10的整数倍
        rounded_score = int(round(self.stats.score, -1))
        #将数值转换为字符串时在其中插入逗号
        score_str = "{:,}".format(rounded_score)
        #将数字转换成字符串
        #score_str = str(self.stats.score)
        #将字符串传递成创建图片的render()
        self.score_image = self.font.render(score_str, True, self.text_color,self.ai_settings.bg_color)

        # 将得分放在屏幕右上角
        self.score_rect = self.score_image.get_rect()
        #右边缘与屏幕右边缘相距20像素
        self.score_rect.right = self.screen_rect.right - 20
        #上边缘与屏幕上边缘也相距20像素
        self.score_rect.top = 20

    def prep_high_score(self):
        """将最高得分转换为渲染的图像"""
        high_score = int(round(self.stats.high_score, -1))
        high_score_str = "{:,}".format(high_score)
        self.high_score_image = self.font.render(high_score_str, True,self.text_color, self.ai_settings.bg_color)

        # 将最高得分放在屏幕顶部中央
        self.high_score_rect = self.high_score_image.get_rect()
        self.high_score_rect.centerx = self.screen_rect.centerx
        self.high_score_rect.top = self.score_rect.top

    def prep_level(self):
        """将等级转换为渲染的图像"""
        self.level_image = self.font.render(str(self.stats.level), True,self.text_color, self.ai_settings.bg_color)

        '''将等级放在得分下方'''
        #方法prep_level()根据存储在stats.level中的值创建一幅图像
        self.level_rect = self.level_image.get_rect()
        #将其right属性设置为得分的right属性
        self.level_rect.right = self.score_rect.right
        #将top属性设置为比得分图像的bottom属性大10像素,以便在得分和等级之间留出一定的空间
        self.level_rect.top = self.score_rect.bottom + 10

    def prep_ships(self):
        """显示还余下多少艘飞船"""
        #创建一个空编组,存储飞船实例
        self.ships = Group()
        for ship_number in range(self.stats.ships_left):
            ship = Ship(self.screen,self.ai_settings)
            #x坐标,整个飞船编组都位于屏幕左边,且每艘飞船的左边距都为10像素
            ship.rect.x = 10 + ship_number * ship.rect.width
            #将y坐标设置为离屏幕上边缘10像素,让所有飞船都与得分图像对齐
            ship.rect.y = 10
            #将每艘新飞船都添加到编组ships中
            self.ships.add(ship)

    def show_score(self):
     """在屏幕上显示得分"""
     self.screen.blit(self.score_image, self.score_rect)
     #显示最高分
     self.screen.blit(self.high_score_image, self.high_score_rect)
     #显示等级
     self.screen.blit(self.level_image, self.level_rect)
     # 绘制飞船
     self.ships.draw(self.screen)

settings.py

#设置类,将所有的设置都放在一起,方便后续的修改

class Settings():
    def __init__(self):
        """初始化游戏的静态设置"""
        #屏幕设置(大小,背景色)
        self.screen_width = 840
        self.screen_height = 600
        self.bg_color = (230,230,230)

        #飞船的数目
        self.ship_limit = 3

        #设置子弹的大小,速度,颜色
        self.bullet_screen_width = 200
        self.bullet_screen_height = 15
        #self.bullet_ship_speed_factor = 1
        self.bullet_bg_color = (60, 60, 60)
        #子弹数目(用来限制屏幕上的子弹的数目)
        self.bullet_allowed = 5

        #外星人向下速度
        self.fleet_drop_speed = 20

        # 以什么样的速度加快游戏节奏,后面速度改变会乘以这个数值
        self.speedup_scale = 1.1
        # 外星人点数的提高速度
        self.score_scale = 1.5
        self.initialize_dynamic_settings()

        # 记分
        self.alien_points = 50

    def initialize_dynamic_settings(self):
        """初始化随游戏进行而变化的设置"""
        # 设置飞船的移动速度
        self.ship_speed_factor = 1.5
        #子弹的速度
        self.bullet_speed_factor = 1
        # 外星人水平速度
        self.alien_speed_factor = 1
        # 外星人,fleet_direction 为 1 表示向右移,为 -1 表示向左移
        self.fleet_direction = 1

    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
        #为了使分数为整数,使用int()
        self.alien_points = int(self.alien_points * self.score_scale)

ship.py

#创建管理飞船大部分行为的类

import pygame
from pygame.sprite import Sprite

#Ship继承Sprite,以便能够创建飞船编组
class Ship(Sprite):
    #screen指定飞船绘制到哪个地方
    def __init__(self,screen,ai_settings):
        super(Ship, self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings

        #加载飞船图片,表示返回一个飞船的surface
        self.image = pygame.image.load('images/ship.bmp')
        #获取surface的属性rect:get_rect()
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        #把飞船放在屏幕的中间:飞船中心=屏幕X方向的中心
        self.rect.centerx = self.screen_rect.centerx
        #self.rect.centerx只能存储整数,若是移动的速度有小数,可将此数值转化成float类型,并赋值给另一个变量
        self.center = float(self.rect.centerx)
        #飞船在屏幕底部:飞船底部=屏幕底部
        self.rect.bottom = self.screen_rect.bottom

        #移动标志,向右移动
        self.moving_right = False
        # 移动标志,向左移动
        self.moving_left = False

    #如果移动标志为True,则向右/左移动
    def update(self):
        #控制飞船不会右移到屏幕外面,self.rect.right表示飞船外接矩形右边缘x的位置,这个值小于屏幕的self.screen_rect.right说明没有未到边缘
        if self.moving_right and self.rect.right < self.screen_rect.right:
            #self.rect.centerx不能存储小数,可用self.center
            self.center += self.ai_settings.ship_speed_factor
        #self.rect.left左边缘的x坐标大于0,说明没有到屏幕左边缘
        if self.moving_left and self.rect.left > 0:
            self.center -= self.ai_settings.ship_speed_factor

        #再将self.center的数赋值给self.rect.centerx,虽然只存储整数位,但整体位置的影响不大
        self.rect.centerx = self.center

    def blitme(self):
        #在指定的位置绘制飞船
        self.screen.blit(self.image,self.rect)

    #让飞船在屏幕上居中
    def center_ship(self):
        self.center = self.screen_rect.centerx

直接运行alien_invasion.py即可
在这里插入图片描述

图片:
ship.bmp
ship.bmp
alien.bmp
alien.bmp

本文地址:https://blog.csdn.net/qq_41917061/article/details/108979419

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网