推荐一个电影吧,《超时空恋旅人》。
一、思路梳理
今天的内容:在上篇的基础上,为飞机加上子弹。
流程为:创建子弹的相关设置——>创建管理子弹发射的类——>开火——>优化小细节
1、所谓“子弹”不是图片,而是由像素点填涂成的小长方形。
2、所谓“发射子弹 ”,原理是让这个小长方形不断向上移动。
3、如何让小长方形移动呢?
通过不断改变小长方形的位置信息。和移动飞船是一个原理。
我们看到的游戏界面,称为一个surface,界面里的每个元素相对于这个surface都有具体的位置。具体来说,界面中无论什么形状的图形python都把它作为矩形来处理,每个元素都有它的外接矩形,矩形除了有长宽之外,还有上下边沿和左右边沿,每个边沿都可以取中点,这就让居中操作非常方便。例如我要让飞船在界面的下方而外星人在飞船的上方,那么我们让让飞船的外接矩形底边沿与窗口界面的底边沿相等,让外星人外接矩形的顶边沿与窗口界面的底边沿相等即可,代码非常简单。
通过让子弹的高度值值不断减小,产生的效果就是一个子弹发射了出去。
4、如何管理创建的子弹?
把子弹放在一个“编组”中,编组有一个特性是会对其中所有的元素进行统一的操作。按空格键发射子弹实际是两个动作完成的:
1按空格键后创建一个新子弹加入编组中,
2遍历编组,把编组中子弹画出来。
5、如何删除已经不在窗口界面的子弹?
通过移动矩形来造成“发射”效果的方法只是让矩形移动,矩形会移出窗口界面。我们需要让移动出窗口的矩消失,否则会占用太多系统内存。
二、基本操作梳理
子弹的相关设置:self.width self.height self.color self.speed
在飞船上创建一个子弹对象: self.rect=pygame.Rect( 0,0,width,height)
让子弹在飞船中间位置射出:self.rect.centerx=ship.rect.centerx
让子弹在飞船顶部位置开始射出:self.rect.top=ship.rect.top
为了让子弹的射出更流畅,选择用小数存储子弹位置:self.y=float(self.rect.y)
在屏幕上绘制子弹:pygame.draw.rect(self.screen,self.color,self.rect)
引入编组:from pygame.sprite import Group
监视空格键: if event.key==pygame.K_SPACE:
限制子弹数量:len(bullets)<bullet_allowed
三、代码实现
关于子弹的代码是加在上一篇的基础上的下,代码太多不方便看,为了便于理解, 下面代码只加关于子弹的内容。
#setting.py
#为了便于理解,这里只把关于子弹的内容加上
def __init__(self):
self.bullet_width=3
self.bullet_height=12
self.bullet_color=(60,60,60)
self.bullet_speed=1
self.bullet_allowed=3
#bullet.py
from pygame.sprite import Sprite
class Bullet(Sprite):
def __init__(self,ai_settings,screen,ship)
#sprite可将游戏中相关的元素编组,进而同时操作编组中所有元素。但需调用super()来继承
super(Bullet,self).__init__()
self.screen=screen
self.rect=pygame.Rect(0,0,ai_settings.bullet_width,ai_settings.bullet_height)
self.rect.top=ship.rect.top
self.rect.centerx=ship.rect.centerx
self.y=float(self.rect.y)
self.color=ai_settings.bullet_color
self.speed=ai_settings.bullet_speed
def update(self):
#向上移动子弹
self.y -=self.bullet_speed
self.rect.y=self.y
def draw_bullet(self):
pygame.draw.rect(self.screen,self.color,self.rect)
#alien_invasion.py
from pygame.sprite import Group
def run_game():
bullets=Group()
while True:
gf.check_events(si_settings,screen,ship,bullets)
ship.update()
gf.update_bullets(bullets)
gf.update_screen(ai_settings,screen,ship,bullets)
#game_function.py
from bullet import Bullet
def check_keydown_events(event,ai_settings,screen,ship,bullets):
elif event.key==pygame.K_SPACE:
if len(bullets)<ai_settings.bullets.allowed:
new_bullet=Bullet(ai_settings,screen,ship)
bullets.add(new_bullet)
def update_screen(ai_settings,screen,ship,bullets):
for bullet in bullets.sprites():
bullet.draw_bullet()
def update_bullets(bullets):
bullets.update()
for bullet in bullets.copy():
if bullet.rect.bottom<=0:
bullets.remove(bullet)