当前位置: 首页 > news >正文

星际争霸之小霸王之小蜜蜂(十二)--猫有九条命

系列文章目录

星际争霸之小霸王之小蜜蜂(十一)--杀杀杀

 星际争霸之小霸王之小蜜蜂(十)--鼠道

星际争霸之小霸王之小蜜蜂(九)--狂鼠之灾

 星际争霸之小霸王之小蜜蜂(八)--蓝皮鼠和大脸猫

  星际争霸之小霸王之小蜜蜂(七)--消失的子弹

 星际争霸之小霸王之小蜜蜂(六)--让子弹飞

 星际争霸之小霸王之小蜜蜂(五)--为小蜜蜂降速

 星际争霸之小霸王之小蜜蜂(四)--事件监听-让小蜜蜂动起来


目录

系列文章目录

文章目录

前言

一、按键事件无法监听情况

二、游戏结束的几种情形

三、检测小老鼠和小花猫碰撞

 四、猫有九条命

 五、雅典娜被攻击

 六、游戏结束

总结


前言

昨天我们已经完成了游戏的主要部分之一,就是子弹的碰撞监测,我们还有一些事情需要解决,比如判断游戏失败、游戏记分等等,今天我们先来实现判断游戏失败功能。


一、按键事件无法监听情况

这是跟今天的内容关系不大的部分,但是之前一直存在的问题没有解决。之前我们写了一段代码,通过按键盘上的Q键可以实现程序的关闭:

elif event.key == pygame.K_q:sys.exit()

 当写完这个代码之后,我发现按Q键并没有任何反应,因为不影响我用鼠标点击关闭游戏,所以一直没有管它,今天再写新代码之前我试着解决,首先我在判断按键为Q后添加输出语句,但当我点击Q时,控制台没有任何输出内容。于是我怀疑按Q时,有没有触发按键事件,我在判断监听键盘按键下 elif event.type==pygame.KEYDOWN:,添加输出,结果发现,按字母都没有输出,也就是没监听到,但是按其他键比如空格、方向键、数字都可以,从逻辑上来说不应该发生这种事情。经过多方查找资料,终于知道原因:我们在运行程序时,键盘输入默认是中文输入法,这时按字母键是监听不到的,我们把切换成英文输入法就解决了这个问题。

二、游戏结束的几种情形

言归正传,今天我们要编写的是判定游戏结束,玩游戏的人都知道,游戏结束有几种情况:一是小老鼠和小花猫进行了撞击,可以判定游戏结束,二是小老鼠进入了屏幕最下边,就像塔防一样,放跑了小怪,雅典娜就死了,游戏判定结束,三是时间到了,判定游戏结束。如果存在生命值或者好几条命的情况,上面的前两种情形还要加判断,判断是否没有命了,如果没有命则游戏结束。

 基于上面的思考,我们根据各种情形编写代码。

三、检测小老鼠和小花猫碰撞

我们在更新每只小老鼠的位置后判断其是否和小花猫碰撞。

def update_aliens(new_setting,,ship,aliens):check_fleet_edges(new_setting,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):print('完了')

 看到上面的代码我们想到写子弹和老鼠碰撞时调用的函数pygame.sprite.groupcollide,这里我们也使用了一个函数,使实现过程变得非常简单。

 pygame.sprite.spritecollideany(ship, aliens)是Pygame库中的一个函数,用于检测一个精灵是否与一组精灵中的任意一个发生了碰撞。其中,ship是一个精灵对象,aliens是一个精灵组对象。如果ship与aliens中的任意一个精灵发生了碰撞,该函数会返回True,否则返回False。

 这里判断撞击后,书上并没有编写后续过程,我猜后面要统一编写,只是写了一个输出,证明实现了判断的功能,我们将老鼠的速度加大,来测试下。

 

 可以看到控制台上出现很多的“完了”,因为小老鼠有很多,左右撞击都会判定成功。

 四、猫有九条命

 这个游戏最终还是赋予了玩家好几条命,但是书上的思路我觉得还是非常好的,正常我们想到的是重新创建一个新的小花猫,就像爆炸的子弹和老鼠一样,书上给的思路是不创建新的花猫,只创建一个变量来记录花猫死的次数,花猫还是那个花猫。为此,创建一个类GameStats保存游戏里面需要统计的信息。

class GameStats():def __init__(self,new_setting):self.new_setting = new_settingself.reset_stats()def reset_stats(self):self.ships_left = self.new_setting.ship_limit

这里的self.new_setting.ship_limit,我们马上在settings模块设置

class Settings():def __init__(self):self.screen_width = 800self.screen_height = 600self.bg_color = (255,255,255)self.ship_speed_factor = 0.1self.ship_limit = 9self.bullet_speed_factor = 0.5self.bullet_width = 2self.bullet_hight = 5self.bullet_color = 60,60,60self.bullets_allowed = 20self.alien_speed_factor = 2self.fleet_drop_speed = 50self.fleet_direction = 1

 至此我们应该想到需要在哪些地方使用这个函数,首先想到的就是我们上面写的老鼠和花猫碰撞之后,但是在update_aliens调用之前,我们需呀将其实例化,传入实参。

import pygame
import settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Group
from alien import Alien
from game_stats import GameStatsdef run_game():pygame.init()new_setting=settings.Settings()screen = pygame.display.set_mode((new_setting.screen_width,new_setting.screen_height))ship = Ship(screen,new_setting)alien = Alien(new_setting,screen)pygame.display.set_caption("狂敲代码的橘子")bullets = Group()aliens = Group()gf.create_fleet(new_setting,screen,aliens)stats = GameStats(new_setting)while True:gf.check_events(new_setting,screen,ship,bullets)ship.update()gf.update_bullets(new_setting,screen,bullets,aliens)gf.update_aliens(new_setting,stats,ship,aliens)gf.update_screen(new_setting,screen,ship,bullets,aliens)run_game()

 我们在主函数对其实例化,然后再调用update_aliens函数时将其传入。在update_aliens里面我们要实现一是将小花猫的命减一,二是删除原来的老鼠,创建一群新的老鼠,三是将小花猫放在初始位置,也就是窗口的中央。

def ship_hit(new_setting,stats,screen,ship,aliens,bullets):stats.ships_left -= 1aliens.empty()bullets.empty()create_fleet(new_setting, screen, aliens)ship.center_ship()time.sleep(0.5)def update_aliens(new_setting,stats,screen,ship,aliens,bullets):check_fleet_edges(new_setting,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(new_setting, stats, screen, ship, aliens, bullets)

 这段代码不难理解,我们发现 ship.center_ship()这个函数我们没有在ship类中定义,它的功能就是将小花猫放到中央去,其实可有可无,我觉得原地复活也不错,但是按照书上我们还是在ship类中添加  

def center_ship(self):self.center = self.screen_rect.centerx

 我们运行试试效果

 

 五、雅典娜被攻击

 之前我们分析过,除了老鼠和小猫进行撞击,小猫会掉血以外,还有就是老鼠触及屏幕底端,相当于塔防游戏失守,怪物跑老家了。实现这个功能非常简单,我们只需要在判断老鼠和花猫碰撞后,再增加一个判断,如果碰撞了,后续操作和老鼠碰到猫一样,我们直接调用ship_hit函数就行了。

def check_aliens_bottom(new_setting,stats,screen,ship,aliens,bullets):screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:ship_hit(new_setting,stats,screen,ship,aliens,bullets)breakdef update_aliens(new_setting,stats,screen,ship,aliens,bullets):check_fleet_edges(new_setting,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(new_setting, stats, screen, ship, aliens, bullets)
check_aliens_bottom(new_setting, stats, screen, ship, aliens, bullets)

 我们不像写小老鼠和小花猫碰撞那样直接在update_aliens里进行判断,而是将代码写在 check_aliens_bottom函数里。为了测试代码效果,我们将判断老鼠和花猫碰撞的代码注释掉,避免发生干扰。

 

 可以看见,老鼠穿过花猫后没有问题,然后老鼠重新生成。

 六、游戏结束

 游戏结束的各种情形已经写完,但是目前老鼠和小猫还在不断重生,我们设置的猫的命属性还没有用上,我们加上判断语句,小猫每归位一次,生命就减一。

def ship_hit(new_setting,stats,screen,ship,aliens,bullets):stats.ships_left -= 1aliens.empty()bullets.empty()create_fleet(new_setting, screen, aliens)ship.center_ship()if stats.ships_left > 0:stats.ships_left -= 1time.sleep(0.5)else:stats.game_active = False

 书上用stats.game_active属性表示游戏是否结束,我个人觉得没必要这么麻烦,就用stats.ships_left=0表示游戏结束就不行了。


总结

有始有终,今天我们完成了游戏的失败判定。

http://www.lryc.cn/news/163927.html

相关文章:

  • 【软件分析/静态分析】chapter8 课程11/12 指针分析—上下文敏感(Pointer Analysis - Context Sensitivity)
  • 时间复杂度与空间复杂度详解
  • 目录操作函数
  • PlantUML入门教程:画时序图
  • C#范围运算符
  • 云数据库知识学习——云数据库产品、云数据库系统架构
  • C++中引用详解!
  • VUE3+TS项目无法找到模块“../version/version.js”的声明文件
  • 数据结构-堆的实现及应用(堆排序和TOP-K问题)
  • Spring 条件注解没生效?咋回事
  • 96. 不同的二叉搜索树
  • Android Jetpack 中Hilt的使用
  • 批量采集的时间管理与优化
  • uniApp监听左右滑动事件
  • 十八、MySQL添加外键?
  • 图像文件的操作MATLAB基础函数使用
  • 【k8s】Kubernetes版本v1.17.3 kubesphere 3.1.1 默认用户登录失败
  • Mysql加密功能
  • redis-win10安装和解决清缓存报错“Error: Protocol error, got “H“ as reply type byte”
  • 【视觉检测】电源线圈上的导线弯直与否视觉检测系统软硬件方案
  • Java elasticsearch scroll模板实现
  • 嵌入式基础知识-信息安全与加密
  • TCP的三次握手与四次挥手
  • 【Face Swapping综述】Quick Overview of Face Swap Deep Fakes
  • etcd选举源码分析和例子
  • Android 网络配置
  • 【网络通信 -- WebRTC】Open WebRTC Toolkit 环境搭建指南
  • 文件上传漏洞(CVE-2022-30887)
  • LeetCode-77-组合
  • Oracle中instr,rtrim,XMLPARSE,XMLAGG,GETCLOBVAL函数的使用