[关闭]
@websec007 2020-06-18T22:35:16.000000Z 字数 5735 阅读 988

Alien Invasion - 13.5 让外星人群移动

2020.Python从入门到实践-过程消化


让外星人群移动 - Version1.0

  1. self.alien_speed_factor = 1
  1. def update(self):
  2. self.x = self.x + game_settings.alien_speed_factor
  3. self.rect.x = self.x
  1. while True:
  2. gf.update_aliens(aliens)
  1. def update_aliens(self):
  2. aliens.update()
  1. self.fleet_drop_speed = 10
  2. self.fleet_direction = 1
  1. def check_edges(self):
  2. scree_rect = self.screen.get_rect()
  3. if self.rect.right >= screen_rect.right:
  4. return True
  5. elif self.rect.left <= 0:
  6. return True
  7. def update(self):
  8. # 左右移动方向的动态更新调整
  9. self.x += self.game_settings.alien_speed_factor*self.game_settings.fleet_direction
  10. self.rect.x = self.x
  1. # 检查外星人边缘,下移并改变aliens方向
  2. def check_fleet_edges(game_settings, aliens):
  3. for alien in aliens.sprites():
  4. if check_edges():
  5. change_fleet_direction(game_settings, aliens)
  6. break
  7. # 将外星人整体下移,并改变其方向
  8. def change_fleet_direction(game_settings, aliens):
  9. for alien in aliens.sprites():
  10. alien.rect.y += game_settings.fleet_drop_speed
  11. game_settings.fleet_direction *= -1
  12. # 检查外星人群是否位于屏幕边缘,更新群外星人的位置
  13. def update_aliens(game_settings, aliens):
  14. check_fleet_edges(game_settings, aliens)
  15. aliens.update()

(8) 游戏主循环调用(alien_invasion.py)

  1. while True:
  2. ....
  3. gf.update_aliens(game_settings, aliens)
  4. gf.update_screen(...., aliens)

学习消化

1.1 单个外星人移动方法

  1. self.alien_speed_factor = 1
  1. self.speed_factor = game_settings.alien_speed_factor
  2. ...
  3. def update(self):
  4. self.x = self.x + self.speed_factor

1.2 所有外星人移动更新和绘制

  1. def update_aliens(aliens):
  2. aliens.update()
  1. def update_screen(screen, bg_color, ship, bullets, aliens):
  2. ...
  3. ship.update()
  4. # 重构后的调用:飞船的更新&绘制
  5. update_bullets(bullets)
  6. # 重构后的调用:更新外星人群
  7. update_aliens(aliens)
  8. # 绘制外星人
  9. aliens.draw(screen)
  1. while True:
  2. ...
  3. gf.update_aliens(aliens)

1.3 外星人碰撞处理

所有外星人左/右移动碰壁后处理动作有:
(1)首先,监控碰壁检查事件是否发生;
(2)随后,确认碰撞后开始整体下移;
(3)同时,调转方向进行移动;

针对碰撞检查收,外星人的下移与方向调整属性进行提前设置
-> 1)外星人移动速度因子
-> 2)外星人移动方向属性
-> 3)外星人下移速度属性

  1. self.alien_speed_factor = 1
  2. self.alien_fleet_direction = 1
  3. self.alien_drop_speed = 1

检测外星人移动是否有碰撞事件发生,如发生则直接返回一个事件属性值:True

  1. def check_edges(self):
  2. screen_rect = self.screen.get_rect()
  3. if self.rect.right >= screen_rect.right:
  4. return True
  5. if self.rect.left <= 0:
  6. return True

(依据碰壁检测)更新单个外星人移动方向方法
-> 1)单个外星人更新方法:alien.update()
-> 2)外星人移动方向属性:game_setting.alien_fleet_direction

  1. self.fleet_direction = game_settings.alien_fleet_direction
  2. def update(self):
  3. self.x = self.x + self.speed_factor*self.fleet_dirction
  4. self.rect.x = self.x

外星人发生碰撞事件的检测判断,以及后续的下移与方向调整动作的整合

  1. def check_fleet_edges(aliens, game_settings):
  2. # 对所有外人逐个进行边缘检测,依据检测的属性值返回做事件响应处置
  3. for alien in aliens.spriters():
  4. # 如果边缘碰撞事件发生,则对应的事件响应处置
  5. if alien.check_edges():
  6. change_fleet_direction(aliens, game_settings)
  7. break

创建一个外星人边缘碰撞事件发生后:所有外星人全部下移,并随后调整方向的函数方法,以备后续整合调用;

  1. def change_fleet_direction(aliens, game_settings):
  2. # (1)外星人是整体的逐个下移
  3. for alien in aliens.spriters():
  4. alien.rect.y += game_settings.alien_drop_speed
  5. # (2)随后调整外星人移动方向属性值
  6. game_settings.alien_fleet_direction *= -1
  1. def aliens_update():
  2. # 碰撞检测与处置
  3. check_fleet_edges(aliens, game_settings)
  4. # 更新所有外星人
  5. aliens.update()
  1. def update_screen(..., aliens):
  2. ...
  3. # 绘制所有外星人到主屏幕
  4. aliens.draw(screen)
  1. while True:
  2. ...
  3. ....
  4. gf.update_aliens(game_settings, aliens)
  5. gf.update_screen(...., aliens)

总结第2次

1. 添加外星人属性 (@settings.py)

  1. # 外星人设置
  2. self.alien_speed_factor = 1
  3. self.fleet_drop_speed = 10
  4. # fleet_direction为1表示向右移,为-1表示向左移
  5. self.fleet_direction = 1

2. 向左或右移动外星人

排错:这里的放了最大的错误,给每个外星人单独初始化基本属性值,为什么,暂时不知道???
正解:直接赋值为self.game_settings = game_settings即可。

  1. def __init__(self, screen, game_settings):
  2. .
  3. .
  4. """外星人坐标值支持浮点数"""
  5. self.x = float(self.rect.x)
  6. # 外星人基本属性初始化
  7. self.game_settings = game_settings
  8. def update(self, game_settings):
  9. """向左或向右移动外星人"""
  10. self.x += (self.game_settings.alien_speed_factor*self.game_settings.fleet_direction)
  11. self.rect.x = self.x

3. 更新所有外星人

  1. # 开始游戏主循环
  2. while True:
  3. gf.check_events(ai_settings, screen, ship, bullets)
  4. ship.update()
  5. gf.update_bullets(bullets)
  6. gf.update_aliens(aliens)
  7. gf.update_screen(ai_settings, screen, ship, aliens, bullets)
  1. def update_aliens(aliens):
  2. """更新外星人群中所有外星人的位置"""
  3. aliens.update()

4. 创建“外星人碰撞属性”获取方法(alien.py)

  1. def check_edges(self):
  2. """如果外星人位于屏幕边缘,就返回True"""
  3. screen_rect = self.screen.get_rect()
  4. if self.rect.right >= screen_rect.right:
  5. return True
  6. elif self.rect.left <= 0:
  7. return True

5. 向下移动外星人,并改变移动方向 (@gf)

  1. def change_fleet_direction(game_settings, aliens):
  2. """将整群外星人下移,并改变它们的方向"""
  3. for alien in aliens.sprites():
  4. alien.rect.y = alien.rect.y + game_settings.fleet_drop_speed
  5. # print(alien.rect.x, alien.rect.y)
  6. game_settings.fleet_direction *= -1
  7. def check_fleet_edges(aliens, game_settings):
  8. # 对所有外人逐个进行边缘检测,依据检测的属性值返回做事件响应处置
  9. for alien in aliens.sprites():
  10. # 如果边缘碰撞事件发生,则对应的事件响应处置
  11. if alien.check_edges():
  12. change_fleet_direction(game_settings, aliens)
  13. break
  14. def update_aliens(game_settings, aliens, screen):
  15. """
  16. 检查是否有外星人位于屏幕边缘,并更新整群外星人的位置
  17. """
  18. check_fleet_edges(aliens, game_settings)
  19. aliens.update(screen)

6. 外星人更新与绘制

  1. def update_screen(screen, bg_color, ship, bullets, aliens, game_settings):
  2. # Update Game
  3. screen.fill(bg_color)
  4. # 飞船移动更新
  5. ship.update()
  6. # 绘制子弹
  7. for bullet in bullets.sprites():
  8. bullet.draw_bullet()
  9. # 绘制飞船
  10. ship.blitme()
  11. # 绘制外星人
  12. update_aliens(game_settings, aliens, screen)
  13. aliens.draw(screen)

知识点:只有“image对象”才有image对象的精灵族其采用 images.draw(screen) 这个绘图方法,已经实际测试子弹逐个Rect对象,其就没有bullets.draw(screen)。

7. 游戏主循环调用

  1. alien_invasion.py
  2. # 开始游戏主循环
  3. while True:
  4. # (1) process Input
  5. gf.check_events(ship, screen, game_settings, bullets)
  6. # (2) Update Game
  7. bullets.update()
  8. # 重构游戏画面绘制与更新
  9. gf.update_screen(screen, bg_color, ship, bullets, aliens, game_settings)
  10. # (3) render
  11. pygame.display.update()
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注