前言
昨天我们创建了一大群大老鼠,按照学习步骤,今天我们应该让他们动起来了,本来以为会像我们玩的飞机大战类游戏一样,随机产生飞机,然后向下移动,但是书上是每一只老鼠的运行轨迹一样,一口气吃不了个胖子,我们先按照书上来。
一、p向右移动小老鼠
很奇怪,书上的移动方式是先向右移动小老鼠,遇到边界再向下,然后再向左,遇到边界再向下,然后向右,依次类推,整体就是一个蛇形S走位,这样设置的话,我们只要站在第一只老鼠位置不停的射子弹,只要子弹的速度比老鼠的移动快,那么就能赢,慢就是输,没有任何操作可言。
不管游戏性如何,我们还是先按照书上的步骤来,要实现上面的功能,我们需要创建一个函数来实现向右移动,参照ship的update函数,我们来编写代码,首先我们在settings模块里创建小老鼠移动的变量。
class Settings(): def __init__(self): self.screen_width = 800 self.screen_height = 600 self.bg_color = (255,255,255) self.ship_speed_factor = 0.1 self.bullet_speed_factor = 0.3 self.bullet_width = 2 self.bullet_hight = 5 self.bullet_color = 60,60,60 self.bullets_allowed = 3 self.alien_speed_factor = 1
然后我们在alien模块创建update函数:
def update(self): self.x += self.new_setting.alien_speed_factor self.rect.x = self.x
下一步,我们就需要在game_functions模块设置让所有的小老鼠一起移动
def update_aliens(aliens): aliens.update()
我们在game_functions模块添加了update_aliens函数,aliens.update()语句的目的就是让aliens里所有的alien对象调用update函数
最后我们在主函数里调用update_aliens函数
while True: gf.check_events(new_setting,screen,ship,bullets) ship.update() gf.update_bullets(bullets) gf.update_aliens(aliens) gf.update_screen(new_setting,screen,ship,bullets,aliens)
到这里,向右移动我们全部写完了,我们运行一下看看效果。试了一下,1的速度太快了,我改成了0.1
我们发现,小老鼠全部跑到屏幕外面去了。
二、设置边界
1.设置属性变量
一是向下移动的速度,二是移动的方向。
class Settings(): def __init__(self): self.screen_width = 800 self.screen_height = 600 self.bg_color = (255,255,255) self.ship_speed_factor = 0.1 self.bullet_speed_factor = 0.3 self.bullet_width = 2 self.bullet_hight = 5 self.bullet_color = 60,60,60 self.bullets_allowed = 3 self.alien_speed_factor = 0.1 self.fleet_drop_speed = 1 self.fleet_direction = 1
这里要着重解释下 self.fleet_direction这个变量,初始的时候我们设置为1,在使用中我们可以设置其为1或者-1,当小老鼠到最右边时,我们设置其为-1,让它和self.alien_speed_factor相乘,那么每次移动self.x += self.new_setting.alien_speed_factor就相当于是减去alien_speed_factor,就实现了向左移动。
2.检查是否撞到边界
我们先创建一个函数判断是否撞到边界,后续在使用中调用
def update(self): self.x += (self.new_setting.alien_speed_factor*self.new_setting.fleet_direction) self.rect.x = self.x def check_edges(self): screen_rect = self.screen.get_rect() if self.rect.right >= screen_rect.right: return True elif self.rect.left<=0: return True
可以看出,函数的意思是超出边界就返回True。到现在我才明白这个游戏的机制,我一直担心上一行的小老鼠撞到边界后向下然后反方向移动会撞到下一行正在移动的小老鼠,其实不会,这个程序的设置是,如果有一只小老鼠撞到边界,所有的老鼠集体向下,然后换方向移动,他们虽然是独立的,但是行动是一个整体,我们一会看效果。
3、实现向下并转向
我们在game_functions模块里实现该功能,首先我们设置向下和改变方向的属性
def change_fleet_direction(new_setting,aliens): for alien in aliens.sprites(): alien.rect.y += new_setting.fleet_drop_speed new_setting.fleet_ direction *=-1
设置好属性后,我们编写函数判断是否撞到边界
def check_fleet_edges(new_setting,aliens): for alien in aliens.sprites(): if alien.check_edges(): change_fleet_direction(new_setting,aliens) Break
这个函数对每一个小老鼠对象判断,通过前面代码我们知道,当一只小老鼠撞到边界时,返回True,执行向下并转向,这时循环不用再执行了,所以break。
最后我们再update_aliens函数里调用check_fleet_edges函数,我们看下game_functions的完整代码:
import sys import pygame from bullet import Bullet from alien import Alien def check_keydown_events(event,new_setting,screen,ship,bullets): 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_bullet(new_setting, screen, ship, bullets) elif event.key ==pygame.K_q: sys.exit() def check_keyup_events(event,ship): if event.key == pygame.K_RIGHT: ship.moving_right = False if event.key == pygame.K_LEFT: ship.moving_left = False def check_events(new_setting,screen,ship,bullets): for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type==pygame.KEYDOWN: check_keydown_events(event,new_setting,screen,ship,bullets) elif event.type==pygame.KEYUP: check_keyup_events(event, ship) def fire_bullet(new_setting,screen,ship,bullets): if len(bullets) < new_setting.bullets_allowed: new_bullet = Bullet(new_setting, screen, ship) bullets.add(new_bullet) def update_bullets(bullets): bullets.update() for bullet in bullets.copy(): if bullet.rect.bottom <= 0: bullets.remove(bullet) def create_fleet(new_setting,screen,aliens): for row_number in range(3): for alien_number in range(12): alien = Alien(new_setting,screen) alien.x = alien.rect.width+2*alien.rect.width*alien_number alien.rect.x = alien.x alien.rect.y = alien.rect.height+2*alien.rect.height*row_number aliens.add(alien) def update_screen(new_setting,screen,ship,bullets,aliens): screen.fill(new_setting.bg_color) for bullet in bullets.sprites(): bullet.draw_bullet() ship.blitme() aliens.draw(screen) pygame.display.flip() def update_aliens(new_setting,aliens): check_fleet_edges(new_setting,aliens) aliens.update() def change_fleet_direction(new_setting,aliens): for alien in aliens.sprites(): alien.rect.y += new_setting.fleet_drop_speed new_setting.fleet_direction *=-1 def check_fleet_edges(new_setting,aliens): for alien in aliens.sprites(): if alien.check_edges(): change_fleet_direction(new_setting,aliens) break
运行之后我发现,一是向下的速度太快,二是我们初始设置的时候把小老鼠铺满了屏幕,在用子弹消灭之前,小老鼠没有左右移动的空间,所以我进行修改,减少了每一行的数量,由12只改成5只,大家看效果。
我发现,在修改12之前,小老鼠们是一直向下,当我改成5后,小老鼠们转向了,但是没有向下移动。经过反复测试,每行代码都正确运行后,我发现其实小老鼠向下移动了,只是肉眼难以发觉,于是我将向下的速度self.fleet_drop_speed改为15,效果就是非常好了。
总结
今天完成了小老鼠的移动,小老鼠有了自己的道,下一步我们就该除四害了,用子弹消灭他们。