|
|
|
|
import random
|
|
|
|
|
import sys
|
|
|
|
|
import time
|
|
|
|
|
|
|
|
|
|
import pygame
|
|
|
|
|
import event as E
|
|
|
|
|
from settings import Settings
|
|
|
|
|
from ship import Ship
|
|
|
|
|
from background import BackGround
|
|
|
|
|
from alien import Rock, Alien1, Alien2, Alien3
|
|
|
|
|
from explode import Explode, Explode1
|
|
|
|
|
from stats import Stats
|
|
|
|
|
from explode import Explode2
|
|
|
|
|
from power import Prop
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AlienInvasion:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
# 初始化
|
|
|
|
|
pygame.init()
|
|
|
|
|
pygame.mixer.init()
|
|
|
|
|
# 设置对象
|
|
|
|
|
self.settings = Settings(self)
|
|
|
|
|
# 屏幕对象
|
|
|
|
|
self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
|
|
|
|
|
self.screen_rect = self.screen.get_rect()
|
|
|
|
|
pygame.display.set_caption("AlienInvasion")
|
|
|
|
|
# 飞船精灵
|
|
|
|
|
self.ship = Ship(self)
|
|
|
|
|
self.ships = self.settings.ships
|
|
|
|
|
self.ships.add(self.ship)
|
|
|
|
|
# boss
|
|
|
|
|
self.boss = Alien3(self)
|
|
|
|
|
# 子弹精灵
|
|
|
|
|
self.bullets = self.settings.bullets
|
|
|
|
|
# 外星人精灵
|
|
|
|
|
self.aliens = self.settings.aliens
|
|
|
|
|
self.boss_aliens = self.settings.boss_aliens
|
|
|
|
|
# 敌人子弹精灵
|
|
|
|
|
self.enemy_bullets = self.settings.enemy_bullets
|
|
|
|
|
self.boss_bullets = self.settings.boss_bullets
|
|
|
|
|
# 背景精灵
|
|
|
|
|
self.background = BackGround(self)
|
|
|
|
|
self.background1 = BackGround(self)
|
|
|
|
|
self.background1.rect.bottom = self.background.rect.top
|
|
|
|
|
self.backgrounds = self.settings.backgrounds
|
|
|
|
|
self.backgrounds.add(self.background, self.background1)
|
|
|
|
|
# 炸弹精灵
|
|
|
|
|
self.explodes = self.settings.explodes
|
|
|
|
|
# 道具类
|
|
|
|
|
self.props = self.settings.props
|
|
|
|
|
# 统计对象
|
|
|
|
|
self.stats = Stats(self) # 用于管理分数 需要传入ship,所以要写在ship创建后的后面
|
|
|
|
|
|
|
|
|
|
# 事件触发
|
|
|
|
|
self.flag1 = 0
|
|
|
|
|
self.flag1_time = pygame.time.get_ticks()
|
|
|
|
|
self.flag2 = 0
|
|
|
|
|
self.flag2_time = pygame.time.get_ticks()
|
|
|
|
|
self.flag3 = 0
|
|
|
|
|
self.flag3_time = pygame.time.get_ticks()
|
|
|
|
|
self.flag4 = 0
|
|
|
|
|
self.flag4_time = pygame.time.get_ticks()
|
|
|
|
|
self.init_time = pygame.time.get_ticks()
|
|
|
|
|
self.now_time = pygame.time.get_ticks()
|
|
|
|
|
# 出怪数量
|
|
|
|
|
self.number_of_enemy = 2
|
|
|
|
|
|
|
|
|
|
def run_game(self):
|
|
|
|
|
while True:
|
|
|
|
|
# 设置刷新率
|
|
|
|
|
self.settings.clock.tick(self.settings.clock_fps)
|
|
|
|
|
# 检测事件
|
|
|
|
|
self._check_events()
|
|
|
|
|
# 检测碰撞
|
|
|
|
|
self._check_collide()
|
|
|
|
|
# 游戏更新
|
|
|
|
|
self._update_sprites()
|
|
|
|
|
# 屏幕更新
|
|
|
|
|
self._update_screen()
|
|
|
|
|
|
|
|
|
|
def _check_events(self):
|
|
|
|
|
for event in pygame.event.get():
|
|
|
|
|
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_q):
|
|
|
|
|
sys.exit()
|
|
|
|
|
if event.type == E.CREATE_ENEMY:
|
|
|
|
|
for i in range(2):
|
|
|
|
|
rock = Rock(self)
|
|
|
|
|
self.aliens.add(rock)
|
|
|
|
|
self._create_enemy() # 生成外星人事件
|
|
|
|
|
|
|
|
|
|
def _create_enemy(self):
|
|
|
|
|
self.now_time = pygame.time.get_ticks()
|
|
|
|
|
if self.now_time - self.init_time > 10000: # 触发事件,当游戏时间超过10s后,没过3s出现一次一级飞船
|
|
|
|
|
if self.flag1 == 0:
|
|
|
|
|
self.flag1_time = self.now_time
|
|
|
|
|
self.flag1 = 1
|
|
|
|
|
if self.now_time - self.flag1_time > 3000 and self.flag1 == 1:
|
|
|
|
|
self.flag1_time = self.now_time
|
|
|
|
|
for i in range(self.number_of_enemy):
|
|
|
|
|
alien = Alien1(self)
|
|
|
|
|
self.aliens.add(alien)
|
|
|
|
|
|
|
|
|
|
if self.now_time - self.init_time > 15000: # 当游戏时间超过10s后,每隔4s出现一次ufo
|
|
|
|
|
if self.flag2 == 0:
|
|
|
|
|
self.flag2_time = self.now_time
|
|
|
|
|
self.flag2 = 1
|
|
|
|
|
if self.now_time - self.flag2_time > 4000 and self.flag2 == 1:
|
|
|
|
|
self.flag2_time = self.now_time
|
|
|
|
|
for i in range(self.number_of_enemy):
|
|
|
|
|
alien = Alien2(self)
|
|
|
|
|
self.aliens.add(alien)
|
|
|
|
|
|
|
|
|
|
if self.now_time - self.init_time > 60000: # 当游戏时间超过60s后,出现boss
|
|
|
|
|
if self.flag3 == 0:
|
|
|
|
|
self.boss_aliens.add(self.boss)
|
|
|
|
|
self.flag3 = 1
|
|
|
|
|
if self.flag3 == 1: # boss一出现,其它的外星人就不会出现
|
|
|
|
|
self.flag1 = 2
|
|
|
|
|
self.flag2 = 2
|
|
|
|
|
self.flag3 = 2
|
|
|
|
|
if 30000 >= self.now_time - self.init_time > 20000:
|
|
|
|
|
self.number_of_enemy = 3
|
|
|
|
|
elif 35000 < self.now_time - self.init_time < 40000:
|
|
|
|
|
self.number_of_enemy = 4
|
|
|
|
|
|
|
|
|
|
def _check_collide(self):
|
|
|
|
|
# 敌人与我方子弹碰撞
|
|
|
|
|
collisions = pygame.sprite.groupcollide(self.aliens, self.bullets, True, True)
|
|
|
|
|
for alien in collisions:
|
|
|
|
|
self.stats.score += int(alien.radius / 8)
|
|
|
|
|
explode = Explode(self)
|
|
|
|
|
explode.rect.center = alien.rect.center
|
|
|
|
|
self.explodes.add(explode)
|
|
|
|
|
if random.random() > 0.95:
|
|
|
|
|
prop = Prop(self)
|
|
|
|
|
prop.rect.center = alien.rect.center
|
|
|
|
|
self.props.add(prop)
|
|
|
|
|
|
|
|
|
|
# boss和我方子弹
|
|
|
|
|
if self.boss.alive and self.boss.rect.top > 0:
|
|
|
|
|
collisions = pygame.sprite.spritecollide(self.boss, self.bullets, True)
|
|
|
|
|
for hit in collisions:
|
|
|
|
|
explode = Explode(self)
|
|
|
|
|
explode.rect.center = hit.rect.center
|
|
|
|
|
if self.boss.hp >= 0:
|
|
|
|
|
self.boss.hp -= 1
|
|
|
|
|
elif self.boss.hp < 0:
|
|
|
|
|
self.boss.alive = 0
|
|
|
|
|
self.boss.kill()
|
|
|
|
|
|
|
|
|
|
# 敌人子弹和飞船碰撞
|
|
|
|
|
if self.ship.alive:
|
|
|
|
|
collisions = pygame.sprite.spritecollide(self.ship, self.enemy_bullets, True)
|
|
|
|
|
for hit in collisions:
|
|
|
|
|
explode = Explode2(self)
|
|
|
|
|
self.explodes.add(explode)
|
|
|
|
|
if self.ship.hp >= 0:
|
|
|
|
|
self.ship.hp -= 5
|
|
|
|
|
elif self.ship.hp < 0:
|
|
|
|
|
self.ship.alive = 0
|
|
|
|
|
self.ship.kill()
|
|
|
|
|
|
|
|
|
|
# boss子弹和飞船碰撞
|
|
|
|
|
if self.ship.alive:
|
|
|
|
|
collisions = pygame.sprite.spritecollide(self.ship, self.boss_bullets, True)
|
|
|
|
|
for hit in collisions:
|
|
|
|
|
explode = Explode2(self)
|
|
|
|
|
self.explodes.add(explode)
|
|
|
|
|
if self.ship.hp > 0:
|
|
|
|
|
self.ship.hp -= 20
|
|
|
|
|
elif self.ship.hp < 0:
|
|
|
|
|
self.ship.alive = 0
|
|
|
|
|
self.ship.kill()
|
|
|
|
|
|
|
|
|
|
# 敌人与飞机的碰撞
|
|
|
|
|
if self.ship.alive:
|
|
|
|
|
ship_collision = pygame.sprite.spritecollide(self.ship, self.aliens, True, pygame.sprite.collide_circle)
|
|
|
|
|
for enemy in ship_collision:
|
|
|
|
|
self.ship.hp -= (enemy.radius / 2)
|
|
|
|
|
explode1 = Explode(self)
|
|
|
|
|
explode1.rect.center = enemy.rect.center
|
|
|
|
|
explode = Explode2(self)
|
|
|
|
|
self.explodes.add(explode, explode1)
|
|
|
|
|
if self.ship.hp <= 0:
|
|
|
|
|
self.ship.alive = 0
|
|
|
|
|
explode1 = Explode1(self)
|
|
|
|
|
explode1.rect = self.ship.rect
|
|
|
|
|
self.explodes.add(explode1)
|
|
|
|
|
self.ship.kill()
|
|
|
|
|
|
|
|
|
|
# 宝物碰撞
|
|
|
|
|
if self.ship.alive:
|
|
|
|
|
prop_collision = pygame.sprite.spritecollide(self.ship, self.props, True)
|
|
|
|
|
for prop in prop_collision:
|
|
|
|
|
if prop.type == 'shield':
|
|
|
|
|
self.ship.hp += 10
|
|
|
|
|
sound = pygame.mixer.Sound('resource/Bonus/sfx_shieldUp.ogg')
|
|
|
|
|
sound.set_volume(0.3)
|
|
|
|
|
sound.play()
|
|
|
|
|
if self.ship.hp > 100:
|
|
|
|
|
self.ship.hp = 100
|
|
|
|
|
elif prop.type == 'bolt':
|
|
|
|
|
self.ship.grade_up()
|
|
|
|
|
|
|
|
|
|
if self.ship.alive == 0:
|
|
|
|
|
self._game_over()
|
|
|
|
|
|
|
|
|
|
def _update_sprites(self):
|
|
|
|
|
for group in [self.backgrounds, self.ships, self.bullets, self.aliens, self.boss_aliens,
|
|
|
|
|
self.enemy_bullets, self.boss_bullets, self.explodes, self.props]:
|
|
|
|
|
group.update()
|
|
|
|
|
|
|
|
|
|
def _update_screen(self):
|
|
|
|
|
for group in [self.backgrounds, self.ships, self.bullets, self.aliens, self.boss_aliens,
|
|
|
|
|
self.enemy_bullets, self.boss_bullets, self.explodes, self.props]:
|
|
|
|
|
group.draw(self.screen)
|
|
|
|
|
self.stats.update() # 更新统计
|
|
|
|
|
# print(self.explodes)
|
|
|
|
|
pygame.display.update()
|
|
|
|
|
# print(self.enemy_bullets)
|
|
|
|
|
|
|
|
|
|
def _game_over(self):
|
|
|
|
|
# print("game over")
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
ai = AlienInvasion()
|
|
|
|
|
ai.run_game()
|