我们接下来要基于pygame.sprite.Sprite创建自己的类,首先必须是主角的,创建一个己方飞机的类,并且给飞机加上子弹哈!
首先我们还是先分析一下,己方飞机需要有哪些部分构成:
class myPlane(pygame.sprite.Sprite): # 创建己方飞机的类
def __init__(self,screen,screen_size): # 有两个传参,第一个是创建的主屏幕,第二个是屏幕的大小
# 因为要绘制飞机和飞行范围的限制
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('./images/me1.png').convert_alpha() # 己方飞机的第一张图片
self.image2 = pygame.image.load('./images/me2.png').convert_alpha() # 己方飞机的第二张图片,两张图片就是轮流切换形成动画效果的
self.mask = pygame.mask.from_surface(self.image) # 飞机的轮廓,被撞击或被击中的判断条件
self.rect = self.image.get_rect() # 获取飞机的rect信息
self.width,self.height = screen_size[0],screen_size[1] # 获取屏幕的大小
self.rect.left,self.rect.bottom = (self.width-self.rect.width)//2, self.height-10 # 飞机的初始位置
self.screen = screen # 获得绘制的窗体
self.speed = 10 # 每次移动的距离
self.switch_image = True # 己方飞机的两张图片的切换标志
self.delay = 100 # 两张图片切换的延时时间(相当于运行周期)
self.destroy_images = [] # 飞机坠毁的图片序列
self.destroy_images.extend([ # 加载坠毁的四张图片,并添加到列表
pygame.image.load('./images/me_destroy_1.png').convert_alpha(),
pygame.image.load('./images/me_destroy_2.png').convert_alpha(),
pygame.image.load('./images/me_destroy_3.png').convert_alpha(),
pygame.image.load('./images/me_destroy_4.png').convert_alpha()])
self.active = True # 标注飞机的初始状态
def moveUp(self): # 飞行移动并判断边界
if self.rect.top > 0:
self.rect.top -= self.speed
else:
self.rect.top = 0
def moveDown(self):
if self.rect.bottom < self.height-10:
self.rect.bottom += self.speed
else:
self.rect.bottom = self.height-10
def moveLeft(self):
if self.rect.left > 0:
self.rect.left -= self.speed
else:
self.rect.left = 0
def moveRight(self):
if self.rect.right < self.width:
self.rect.right += self.speed
else:
self.rect.right = self.width
def animation(self): # 动画的实现及效果绘制
if self.switch_image:
self.screen.blit(self.image, self.rect)
else:
self.screen.blit(self.image2, self.rect)
if self.delay % 5 == 0: # 每隔五个指令周期切换一次
self.switch_image = not self.switch_image
self.delay -= 1 # 每次延时时间减一
if self.delay == 0:
self.delay = 100
上面就是我们创建的己方飞机的类,接下来我们来看下子弹的类需要如何定义:
class Bullet(pygame.sprite.Sprite):
def __init__(self,position,direction):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("./images/bullet2.png").convert_alpha() # 加载子弹的图片
self.rect = self.image.get_rect() # 获取子弹的rect对象
self.rect.left, self.rect.top = position # 设置子弹的初始位置
self.speed = 12 # 设置子弹移动的速度
self.active = True # 表示子弹是否超出窗体
self.mask = pygame.sprite.from_surface(self.image) # 获取子弹的轮廓
self.direction = direction # 子弹的方向
def move(self):
if self.direction: # 如果子弹的方向是向上的,direction为True
self.rect.top -= self.speed # 移动子弹
if self.rect.top < 0: # 判断子弹有没有超出边界
self.active = False # 超出边界及修改标志位
else:
self.rect.top += self.speed
if self.rect.top > 700:
self.active = False
def reset(self,position):
self.rect.left, self.rect.top = position # 子弹重生
self.active = True # 修改标志位
现在我们的两个类定义好了,接下来看看主程序应该要怎么写:
import pygame
import sys
from pygame.locals import *
import myclass
pygame.init()
screen_size = width, height = 480, 700
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption('飞机大战')
bg = pygame.image.load('./images/background.png').convert()
pygame.mixer.music.load('./sound/game_music.ogg')
pygame.mixer.music.set_volume(0.5)
pygame.mixer.music.play(-1)
def main():
clock = pygame.time.Clock()
heroPlane = myclass.myPlane(screen, screen_size) # 生成己方飞机
bullet1 = [] # 生成己方飞机的子弹序列
bullet1_index = 0 # 子弹的序号
BULLET1_NUM = 5 # 表示五颗子弹连发,刚好超过屏幕
for i in range(BULLET1_NUM): # 序列生成子弹
bullet1.append(myclass.Bullet(heroPlane.rect.midtop,True)) # 子弹在飞机的中上方生成,方向向上
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
key_pressed = pygame.key.get_pressed() # 获取按键信息,这种方式可以使操控更加平滑
if key_pressed[K_UP]: # 如果方向上键按下
heroPlane.moveUp() # 让飞机向上移动
if key_pressed[K_DOWN]:
heroPlane.moveDown()
if key_pressed[K_LEFT]:
heroPlane.moveLeft()
if key_pressed[K_RIGHT]:
heroPlane.moveRight()
screen.blit(bg,(0,0)) # 绘制背景图片
heroPlane.animation() # 显示飞机
if not (heroPlane.delay % 10): # 每十个指令周期发射一枚子弹
bullet1[bullet1_index].reset(heroPlane.rect.midtop)
bullet1_index = (bullet1_index + 1) % BULLET1_NUM
for each in bullet1: # 绘制子弹
each.move()
screen.blit(each.image, each.rect)
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()