图片:(5张,子弹是白色,不明显)
代码:
"""
__project_ = 'python'
__file_name__ = 'python实战'
__author__ = 'Administrator'
__time__ = '2019/12/17 8:38'
__product_name = PyCharm
"""
'''
完成“飞机大战游戏“以下要求
1.实现背景精灵类和相关逻辑,背景可正常移动,加载合适的资源图片
2.实现飞机精灵类和相关逻辑,添加飞机发射子弹的方法shoot,加载合适的资源图片
3.实现普通敌机精灵类和相关逻辑,添加敌机类的生命值属性,加载合适的资源图片
4.实现加强版敌机精灵类和相关逻辑,加载合适的资源图片(图片可以和飞机图片相同)
5.实现子弹精灵类和相关逻辑,加载合适的资源图片
6.实现随机出现普通敌机或加强版敌机逻辑
7.实现敌机击毁逻辑:普通敌机遇到子弹被击毁,加强版敌将遇到5颗子弹被击毁
8.实现空格键一次发射5颗同方向的子弹逻辑
9.实现s键一次发送5颗不同方向的子弹逻辑
10.实现游戏逻辑,可进行游戏
注释简介清晰,编码规范,程序功能完整,无bug
拓展: 30秒只可以使用8次散弹 步骤9方法
time.clock()计算时间方法
'散弹时间机制'
now_clock = mytime.clock()
if now_clock - self.fire_h_clock < 30:
if self.fire_h_count<8:
self.fire_h_count+=1
self.myplane.shoot_H()
else:
pass# '不能发射子弹'
else:
self.fire_h_clocks = now_clock
self.myplane.shoot_H()
self.fire_h_count = 1
'''
import pygame
import random
import time as mytime
SCREEN_RECT = pygame.Rect(0, 0, 331,587) # 游戏窗口大小
FRAME_PER_SER = 60 # 帧率
CREATE_ENMY_EVENT = pygame.USEREVENT # 创建敌机事件ID
PLANE_FIRE_EVENT = pygame.USEREVENT + 1 # 自动开火事件ID
# 重写精灵类
class GameSprite(pygame.sprite.Sprite):
def __init__(self, image_name, speed=1):
''
super().__init__()
# 添加图片属性image、大小rect和速度 speed属性
self.image = pygame.image.load(image_name)
self.rect = self.image.get_rect()
self.speed = speed
def update(self, *args):
super().update(*args)
self.rect.y += self.speed
# 实现背景精灵类和相关逻辑,
class Background(GameSprite):
def __init__(self, is_alt=False):
super().__init__('bg.png')
# 背景可正常移动,加载合适的资源图片
if is_alt:
self.rect.y = SCREEN_RECT.height
def update(self, *args):
super().update(*args)
if self.rect.y > SCREEN_RECT.height:
self.rect.y = -SCREEN_RECT.height # 完成背景图滚动
# 实现普通敌机精灵类和相关逻辑,
class Enemy(GameSprite):
def __init__(self, image_name='dj.png', lives=1):
# 添加敌机类的生命值属性,加载合适的资源图片
super().__init__(image_name)
self.speed = random.randint(1, 3) # 敌机速度,随机1-3
self.lives = lives
# 敌机出现位置
self.rect.bottom = 0
max_x = SCREEN_RECT.width - self.rect.width
self.rect.x = random.randint(0, max_x)
def update(self, *args):
super().update(*args)
# # 实现敌机击毁逻辑:普通敌机遇到子弹被击毁,加强版敌将遇到5颗子弹被击毁
if self.lives == 0: # 加强版敌将遇到5颗子弹被击毁
self.kill()
if self.rect.y > SCREEN_RECT.height:
self.kill() # 敌机出屏幕销毁
# 实现飞机精灵类和相关逻辑,
class Myplane(GameSprite):
def __init__(self):
super().__init__('fj.png')
self.rect.centerx = SCREEN_RECT.centerx
self.rect.bottom = SCREEN_RECT.bottom - 30
self.bullets = pygame.sprite.Group()
def update(self, *args):
# super().update(*args)
self.rect.x += self.speed
# 飞机不飞出屏幕
if self.rect.x < 0:
self.rect.x = 0
elif self.rect.right > SCREEN_RECT.right:
self.rect.right = SCREEN_RECT.right
# 添加飞机发射子弹的方法shoot,加载合适的资源图片
def shoot(self):
# '子弹'
b = Bullet()
b.rect.bottom = self.rect.y - 20
b.rect.centerx = self.rect.centerx
self.bullets.add(b)
def shoot5(self):
'''8.实现空格键一次发射5颗同方向的子弹逻辑'''
for i in range(5):
b = Bullet()
b.rect.bottom = self.rect.y - 20 * i
b.rect.centerx = self.rect.centerx
self.bullets.add(b)
def shoot_H(self):
'''9.实现s键一次发送5颗不同方向的子弹逻辑'''
for i in range(-2, 3):
speed_h = i
b = Bullet(speed_h=speed_h)
b.rect.bottom = self.rect.y
b.rect.centerx = self.rect.centerx - 20 * i
self.bullets.add(b)
# 实现子弹精灵类和相关逻辑,
class Bullet(GameSprite):
def __init__(self, speed_h=0):
super().__init__('zd.png', -2) # 加载合适的资源图片
self.speed_h = speed_h
def update(self, *args):
super().update(*args)
if self.speed_h != 0:
self.rect.x -= self.speed_h
if self.rect.bottom < 0:
self.kill() # 移出屏幕销毁
class PlaneGame(object): # 游戏类
def __init__(self):
self.screen = pygame.display.set_mode(SCREEN_RECT.size)
self.clock = pygame.time.Clock()
self.fire_h_clock = mytime.clock()
self.fire_h_count = 0
# 创建精灵
self.__create_sprites()
# 监听
pygame.time.set_timer(CREATE_ENMY_EVENT, 1000)
pygame.time.set_timer(PLANE_FIRE_EVENT, 500)
# 设置标题-没考核
pygame.display.set_caption('飞机大战-初级版')
def __create_sprites(self):
bg0 = Background()
bg1 = Background(True)
self.back_group = pygame.sprite.Group(bg0, bg1)
self.enemy_group = pygame.sprite.Group()
self.myplane = Myplane()
self.myplane_group = pygame.sprite.Group(self.myplane)
def start_game(self):
while True:
self.clock.tick(FRAME_PER_SER) # 刷新帧率
# 事件监听
self.__event_handler()
# 检查碰撞
self.__check_collid()
# 更新绘制
self.__update_sprites()
pygame.display.update()
def __event_handler(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
# PlaneGame.del结束游戏
PlaneGame.game_over()
quit()
elif event.type == CREATE_ENMY_EVENT:
# 实现随机出现普通敌机或加强版敌机逻辑
is_enemy = random.randint(0, 5)
if is_enemy < 4:
enemy = Enemy()
self.enemy_group.add(enemy)
else:
enemy = Enemy(image_name='fj0.png', lives=5)
self.enemy_group.add(enemy)
elif event.type == PLANE_FIRE_EVENT:
self.myplane.shoot()
keys = pygame.key.get_pressed()
if keys[32] and event.type == pygame.KEYDOWN:
'实现空格键一次发射5颗同方向的子弹逻辑'
self.myplane.shoot5()
elif keys[115] and event.type == pygame.KEYDOWN:
# '9.实现s键一次发送5颗不同方向的子弹逻辑'
#self.myplane.shoot_H()
#''''散弹时间机制'
now_clock = mytime.clock()
if now_clock - self.fire_h_clock < 30:
if self.fire_h_count<8:
self.fire_h_count+=1
self.myplane.shoot_H()
else:
pass# '不能发射子弹'
else:
self.fire_h_clock = now_clock
self.myplane.shoot_H()
self.fire_h_count = 1#'''
if keys[pygame.K_RIGHT]:
self.myplane.speed = 2
elif keys[pygame.K_LEFT]:
self.myplane.speed = -2
else:
self.myplane.speed = 0
def __check_collid(self):
# 实现敌机击毁逻辑:普通敌机遇到子弹被击毁,
res_dict = pygame.sprite.groupcollide(self.enemy_group, self.myplane.bullets, False, True)
for i in res_dict.keys():
count = len(res_dict[i])
i.lives -= count
enemies = pygame.sprite.spritecollide(self.myplane, self.enemy_group, True)
if len(enemies) > 0:
self.myplane.kill()
PlaneGame.game_over()
def __update_sprites(self):
self.back_group.update()
self.back_group.draw(self.screen)
self.enemy_group.update()
self.enemy_group.draw(self.screen)
self.myplane_group.update()
self.myplane_group.draw(self.screen)
self.myplane.bullets.update()
self.myplane.bullets.draw(self.screen)
@staticmethod
def game_over():
pygame.quit()
exit()
if __name__ == '__main__':
g = PlaneGame()
g.start_game()