《python编程:从入门到实践的》外星人入侵的代码
程序员文章站
2022-09-21 15:09:08
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
alien.bmp
本文地址:https://blog.csdn.net/qq_41917061/article/details/108979419