pygame 外星人飞船开发摘要

继承

# ship继承于Sprite(父类)
class Ship(Sprite):

参考:https://blog.csdn.net/qq_38787214/article/details/87902291

没有super(A, self).init()时只能调用父类Root的属性

加入super(A, self).init()时调用A的父类Root的属性方法

Sprites & collide

from pygame.sprite import Sprite
from pygame.sprite import Group
# 继承于Sprite
class Alien(Sprite):
  
bullets = Group()
# 遍历整个外星人组  
for alien in aliens.sprites():
  
# 删除编组中余下的所有精灵
bullets.empty()

# 删除发生碰撞的子弹和外星人,
# 新增的这行代码遍历编组bullets 中的每颗子弹,再遍历编组aliens 中的每个外星人。每当有子弹和外星人的rect 重叠时,groupcollide() 就在它返回的字典中添加一个键-值对。两个实参True 告诉Pygame删除发生碰撞的子弹和外星人。
collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)

# 检测外星人和飞船之间的碰撞
if pygame.sprite.spritecollideany(ship,aliens):
   print("ship hit!!!")
    
collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
    if collisions:
        for aliens in collisions.values():
            stats.score += ai_settings.alien_points * len(aliens)

当有一个个续命的也需要使用sprite

Sprite 下的draw 函数:

说明:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yeTPQNdV-1598948069078)(PYTHON 学习笔记.assets/截屏2020-08-31 下午7.48.34.png)]

具体用法:

    def show_score(self):
        --snip--
        # 绘制飞船,ships继承于Sprite的group
        self.ships.draw(self.screen)

blit

ship.blitme()

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

Screen:

设置背景图片

background = pygame.image.load('images/bg.png')  # 图片位置
screen.blit(background,(0,0))  #对齐的坐标

暂停

from time import sleep
sleep(0.5)

游戏结束

下面在GameStats 中添加一个作为标志的属性game_active ,以便在玩家的

飞船用完后结束游戏:

game_stats.py

def __init__(self, settings): 
  --snip--
# 游戏刚启动时处于活动状态 self.game_active = True

game_function.py

def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):
    """响应飞船被外星人撞到"""
    if stats.ships_left > 0:
        --snip--
    else:
      	# 飞机用完设置成false
        stats.game_active = False

在alien_invasion.py中,我们需要确定游戏的哪些部分在任何情况下都应运行,哪些部分仅在游戏处于活动状态时才运行:

按键

game_function.py

def update_screen(ai_settings, screen, stats, ship, aliens, bullets, play_button):
  --snip--
# 如果游戏处于非活动状态,就绘制Play按钮,所以一点按钮,状态改变按钮消失
    # 为让Play按钮位于其他所有屏幕元素上面,我们在绘制其他所有游戏元素后再绘制这个按钮,然后切换到新屏幕。
    if not stats.game_active:
        play_button.draw_button()

Button.py

import pygame.font
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 = (0, 255, 0)
        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

        # 按钮的标签只需创建一次
        self.prep_msg(msg)

    def prep_msg(self, msg):
        """将msg渲染为图像,并使其在按钮上居中"""
        # 用font.render() 将存储在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
        self.screen.fill(self.button_color, self.rect)
        self.screen.blit(self.msg_image, self.msg_image_rect)  #blit的参数是image,矩形

def check_play_button(ai_settings, screen, stats, play_button, ship, aliens, bullets, mouse_x, mouse_y):
    """在玩家单击Play按钮时开始新游戏"""
    button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
    # 当前,Play按钮存在一个问题,那就是即便Play按钮不可见,
    # 玩家单击其原来所在的区域时,游戏依然会作出响应。如下设置if 加上not 即可
    if button_clicked and not stats.game_active:
        # 重置游戏统计信息

play 按下之后要重置分数等

def check_play_button(ai_settings, screen, stats, sb, play_button, ship, aliens, bullets, mouse_x, mouse_y):
    """在玩家单击Play按钮时开始新游戏"""
    button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
    if button_clicked and not stats.game_active:
        # 重置游戏设置
        ai_settings.initialize_dynamic_settings()

        # 重置记分牌图像
        sb.prep_score()
        sb.prep_high_score()
        sb.prep_level()
鼠标事件
def check_play_button(stats, play_button, mouse_x, mouse_y):
    """在玩家单击Play按钮时开始新游戏"""
    if play_button.rect.collidepoint(mouse_x, mouse_y):
        stats.game_active = True

def check_events(ai_settings, screen, stats, play_button, ship, bullets):
    """响应按键和鼠标事件"""
    for event in pygame.event.get():
        --snip--
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_x, mouse_y = pygame.mouse.get_pos()  # 注意这种写法
            check_play_button(stats, play_button, mouse_x, mouse_y)

无论玩家单击屏幕的什么地方,Pygame都将检测到一个MOUSEBUTTONDOWN 事件,但我们只想让这个游戏在玩家用鼠标单击Play按钮时作出响应。为此,我们使用 了pygame.mouse.get_pos() ,它返回一个元组,其中包含玩家单击时鼠标的x 和y 坐标,我们将这些值传递给函数check_play_button() ,而这个函 数使用collidepoint() 检查鼠标单击位置是否在Play按钮的rect 内。如果是这样的,我们就将game_active 设置为True ,让游戏就此开始!

隐藏&显示光标

点击play后隐藏,游戏结束后显示光标以进行下一步选择

def check_play_button(ai_settings, screen, stats, play_button, ship, aliens, bullets, mouse_x, mouse_y):
    """在玩家单击Play按钮时开始新游戏"""
    button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
    if button_clicked and not stats.game_active:
        # 隐藏光标
        pygame.mouse.set_visible(False)
def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):
    """响应飞船被外星人撞到"""
    if stats.ships_left > 0:
        --snip--
    else:
        stats.game_active = False
        #显示光标
        pygame.mouse.set_visible(True)

提高难度

游戏setting分为静态设置和动态设置

重置参数

一旦是那些动态变化的参量,比如分数,子弹个数,外星人位置,还有游戏速度设置

数字用100,000隔开

def prep_score(self): """将得分转换为渲染的图像"""
❶  	rounded_score = int(round(self.stats.score, -1))
❷    score_str = "{:,}".format(rounded_score)
    self.score_image = self.font.render(score_str, True, self.text_color,
    self.ai_settings.bg_color)

函数round() 通常让小数精确到小数点后多少位,其中小数位数是由第二个实参指定的。然而,如果将第二个实参指定为负数,round() 将圆整到最近的10、100、1000等整 数倍。❶让Python将stats.score 的值圆整到最近的10的整数倍,并将结果存储到rounded_score 中。

​ 注意 在Python 2.7中,round() 总是返回一个小数值,因此我们使用int() 来确保报告的得分为整数。如果你使用的是Python 3,可省略对int() 的调用。

❷处使用了一个字符串格式设置指令,它让Python将数值转换为字符串时在其中插入逗号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值