'''
Function:
用于运行某一游戏关卡
Author:
Charles
微信公众号:
Charles的皮卡丘
'''
import sys
import pygame
import random
from modules.sprites.home import *
from modules.sprites.tanks import *
from modules.sprites.scenes import *
'''用于运行某一游戏关卡'''
class GameLevel():
def __init__(self, gamelevel, levelfilepath, sounds, is_dual_mode, cfg, **kwargs):
# 关卡地图路径
self.gamelevel = gamelevel
self.levelfilepath = levelfilepath
# 音效
self.sounds = sounds
# 是否为双人模式
self.is_dual_mode = is_dual_mode
# 地图规模参数
self.border_len = cfg.BORDER_LEN
self.grid_size = cfg.GRID_SIZE
self.width, self.height = cfg.WIDTH, cfg.HEIGHT
self.panel_width = cfg.PANEL_WIDTH
# 图片路径
self.scene_image_paths = cfg.SCENE_IMAGE_PATHS
self.other_image_paths = cfg.OTHER_IMAGE_PATHS
self.player_tank_image_paths = cfg.PLAYER_TANK_IMAGE_PATHS
self.bullet_image_paths = cfg.BULLET_IMAGE_PATHS
self.enemy_tank_image_paths = cfg.ENEMY_TANK_IMAGE_PATHS
self.food_image_paths = cfg.FOOD_IMAGE_PATHS
self.home_image_paths = cfg.HOME_IMAGE_PATHS
# 字体
self.font = pygame.font.Font(cfg.FONTPATH, cfg.HEIGHT//30)
# 关卡场景元素
self.scene_elems = {'brick_group': pygame.sprite.Group(), 'iron_group': pygame.sprite.Group(),
'ice_group': pygame.sprite.Group(), 'river_group': pygame.sprite.Group(),
'tree_group': pygame.sprite.Group()}
# 解析关卡文件
self.__parseLevelFile()
'''开始游戏'''
def start(self, screen):
screen = pygame.display.set_mode((self.width+self.panel_width, self.height))
# 背景图片
background_img = pygame.image.load(self.other_image_paths.get('background'))
# 定义精灵组
player_tanks_group = pygame.sprite.Group()
enemy_tanks_group = pygame.sprite.Group()
player_bullets_group = pygame.sprite.Group()
enemy_bullets_group = pygame.sprite.Group()
foods_group = pygame.sprite.Group()
# 定义敌方坦克生成事件
generate_enemies_event = pygame.constants.USEREVENT
pygame.time.set_timer(generate_enemies_event, 20000)
# 我方大本营
home = Home(position=self.home_position, imagepaths=self.home_image_paths)
# 我方坦克
tank_player1 = PlayerTank('player1', position=self.player_tank_positions[0], player_tank_image_paths=self.player_tank_image_paths, border_len=self.border_len, screensize=[self.width, self.height], bullet_image_paths=self.bullet_image_paths, protected_mask_path=self.other_image_paths.get('protect'), boom_image_path=self.other_image_paths.get('boom_static'))
player_tanks_group.add(tank_player1)
if self.is_dual_mode:
tank_player2 = PlayerTank('player2', position=self.player_tank_positions[1], player_tank_image_paths=self.player_tank_image_paths, border_len=self.border_len, screensize=[self.width, self.height], bullet_image_paths=self.bullet_image_paths, protected_mask_path=self.other_image_paths.get('protect'), boom_image_path=self.other_image_paths.get('boom_static'))
player_tanks_group.add(tank_player2)
# 敌方坦克
for position in self.enemy_tank_positions:
enemy_tanks_group.add(EnemyTank(enemy_tank_image_paths=self.enemy_tank_image_paths, appear_image_path=self.other_image_paths.get('appear'), position=position, border_len=self.border_len, screensize=[self.width, self.height], bullet_image_paths=self.bullet_image_paths, food_image_paths=self.food_image_paths, boom_image_path=self.other_image_paths.get('boom_static')))
# 游戏开始音乐
self.sounds['start'].play()
clock = pygame.time.Clock()
# 该关卡通过与否的flags
is_win = False
is_running = True
# 游戏主循环
while is_running:
screen.fill((0, 0, 0))
screen.blit(background_img, (0, 0))
# 用户事件捕捉
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# --敌方坦克生成
elif event.type == generate_enemies_event:
if self.max_enemy_num > len(enemy_tanks_group):
for position in self.enemy_tank_positions:
if len(enemy_tanks_group) == self.total_enemy_num:
break
enemy_tank = EnemyTank(enemy_tank_image_paths=self.enemy_tank_image_paths, appear_image_path=self.other_image_paths.get('appear'), position=position, border_len=self.border_len, screensize=[self.width, self.height], bullet_image_paths=self.bullet_image_paths, food_image_paths=self.food_image_paths, boom_image_path=self.other_image_paths.get('boom_static'))
if (not pygame.sprite.spritecollide(enemy_tank, enemy_tanks_group, False, None)) and (not pygame.sprite.spritecollide(enemy_tank, player_tanks_group, False, None)):
enemy_tanks_group.add(enemy_tank)
# --用户按键
key_pressed = pygame.key.get_pressed()
# 玩家一, WSAD移动, 空格键射击
if tank_player1.num_lifes >= 0:
if key_pressed[pygame.K_w]:
player_tanks_group.remove(tank_player1)
tank_player1.move('up', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
player_tanks_group.add(tank_player1)
elif key_pressed[pygame.K_s]:
player_tanks_group.remove(tank_player1)
tank_player1.move('down', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
player_tanks_group.add(tank_player1)
elif key_pressed[pygame.K_a]:
player_tanks_group.remove(tank_player1)
tank_player1.move('left', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
player_tanks_group.add(tank_player1)
elif key_pressed[pygame.K_d]:
player_tanks_group.remove(tank_player1)
tank_player1.move('right', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
player_tanks_group.add(tank_player1)
elif key_pressed[pygame.K_SPACE]:
bullet = tank_player1.shoot()
if bullet:
self.sounds['fire'].play() if tank_player1.tanklevel < 2 else self.sounds['Gunfire'].play()
player_bullets_group.add(bullet)
# 玩家二, ↑↓←→移动, 小键盘0键射击
if self.is_dual_mode and (tank_player2.num_lifes >= 0):
if key_pressed[pygame.K_UP]:
player_tanks_group.remove(tank_player2)
tank_player2.move('up', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
player_tanks_group.add(tank_player2)
elif key_pressed[pygame.K_DOWN]:
player_tanks_group.remove(tank_player2)
tank_player2.move('down', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
player_tanks_group.add(tank_player2)
elif key_pressed[pygame.K_LEFT]:
player_tanks_group.remove(tank_player2)
tank_player2.move('left', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
player_tanks_group.add(tank_player2)
elif key_pressed[pygame.K_RIGHT]:
player_tanks_group.remove(tank_player2)
tank_player2.move('right', self.scene_elems, player_tanks_group, enemy_tanks_group, home)
player_tanks_group.add(tank_player2)
elif key_pressed[pygame.K_KP0]:
bullet = tank_player2.shoot()
if bullet:
player_bullets_group.add(bullet)
self.sounds['fire'].play() if tank_player2.tanklevel < 2 else self.sounds['Gunfire'].play()
# 碰撞检测
# --子弹和砖墙
pygame.sprite.groupcollide(player_bullets_group, self.scene_elems.get('brick_group'), True, True)
pygame.sprite.groupcollide(enemy_bullets_group, self.scene_elems.get('brick_group'), True, True)
# --子弹和铁墙
for bullet in player_bullets_group:
pygame.sprite.spritecollide(bullet, self.scene_elems.get('iron_group'), bullet.is_stronger, None)
pygame.sprite.groupcollide(enemy_bullets_group, self.scene_elems.get('iron_group'), True, False)
# --子弹撞子弹
pygame.sprite.groupcollide(player_bullets_group, enemy_bullets_group, True, True)
# --我方子弹撞敌方坦克
for tank in enemy_tanks_group:
if pygame.sprite.spritecollide(tank, player_bullets_group, True, None):
if tank.food:
foods_group.add(tank.food)
tank.food = None
if tank.decreaseTankLevel():