def create_map(ai_settings, screen): bricks = Group() steels = Group() seawater = Group() grassland = Group() row_index = 0 for row in ai_settings.map: row_index += 1 for i, item in enumerate(row): if item == MapType.brick.value: wall_brick = WallBrick(ai_settings, screen) wall_brick.x = i * 20 wall_brick.y = (row_index - 1) * 20 wall_brick.rect.x = wall_brick.x wall_brick.rect.y = wall_brick.y bricks.add(wall_brick) if item == MapType.steel.value: wall_steel = WallSteel(ai_settings, screen) wall_steel.x = i * 20 wall_steel.y = (row_index - 1) * 20 wall_steel.rect.x = wall_steel.x wall_steel.rect.y = wall_steel.y steels.add(wall_steel) if item == MapType.seawater.value: wall_seawater = WallSeawater(ai_settings, screen) wall_seawater.x = i * 20 wall_seawater.y = (row_index - 1) * 20 wall_seawater.rect.x = wall_seawater.x wall_seawater.rect.y = wall_seawater.y seawater.add(wall_seawater) if item == MapType.grassland.value: wall_grassland = WallGrassland(ai_settings, screen) wall_grassland.x = i * 20 wall_grassland.y = (row_index - 1) * 20 wall_grassland.rect.x = wall_grassland.x wall_grassland.rect.y = wall_grassland.y grassland.add(wall_grassland) tank_map.set_map(MapType.brick.name, bricks) tank_map.set_map(MapType.steel.name, steels) tank_map.set_map(MapType.seawater.name, seawater) tank_map.set_map(MapType.grassland.name, grassland) # 创建老家 my_home = WallHome(ai_settings, screen) my_home.rect.x = 240 my_home.rect.bottom = screen.get_rect().bottom - 20 tank_map.set_map(MapType.home.name, my_home)
def init_tank(tank, tank_flg, screen): # 移动标志 tank.moving_right = False tank.moving_left = False tank.moving_up = False tank.moving_down = False # 坦克运行的方向 tank.direction = Direction.up # 坦克移动方向优先度 tank.direction_priority = [] # 是不是无敌 tank.is_invincible = True tank.bullet_count = 0 tank.rect.bottom = screen.get_rect().bottom - 20 tank.y = tank.rect.y tank.moving_image = tank.image if tank_flg == 0: tank.x = 180 else: tank.x = 300 tank_map.set_map("double_flg", 1)
def check_events(ai_settings, screen, tank, tank2, bullets, stats): """相应键盘和鼠标事件""" for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: check_keydown_events(event, ai_settings, screen, tank, tank2, bullets, stats) elif event.type == pygame.KEYUP: check_keyup_events(event, tank, tank2, stats) elif event.type == pygame.MOUSEBUTTONDOWN: pos = pygame.mouse.get_pos() if stats.game_step == GameStep.login: if 150 < pos[0] < 360 and 300 < pos[1] < 430: user_id = tank_map.get_map("user_id") if len(user_id) == 0: user_id = "defaultUser" tank_map.set_map("user_id", user_id) run_register(user_id) # register(user_id) if stats.game_step == GameStep.login: stats.game_step = GameStep.init elif stats.game_step == GameStep.total: if 40 < pos[0] < 220 and 440 < pos[1] < 490: stats.game_step = GameStep.init stats.level = 1 score = tank_map.get_map("score") score = 0 tank_map.set_map("score", score) init_tank(tank, 0, screen) tank.x = 120 tank.y = 280 if tank2 is not None: init_tank(tank2, 1, screen) elif 300 < pos[0] < 480 and 440 < pos[1] < 490: stats.game_active = False
def run_game(): # 初期化一个 pygame.init() ai_settings = Settings() tank_map.set_map("user_id", "") tank_map.set_map("score", 0) tank_map.set_map("double_flg", 0) screen = pygame.display.set_mode( (ai_settings.screen_width, ai_settings.screen_height)) pygame.display.set_caption("Tank Battle") # 创建一个坦克 tank = Tank(ai_settings, screen) tank2 = None # 创建一个子弹分组 bullets = Group() # 创建一个敌人子弹分组 enemy_bullets = Group() # 创建一个敌人编组 enemies = Group() # 创建一个敌人 # enemy = Enemy(ai_settings, screen) # 创建外敌人群 gf.create_fleet(ai_settings, screen, enemies) # 创建一个砖墙编组 gf.create_map(ai_settings, screen) # 创建一个炸弹的编组 booms = Group() # bg_color = (230, 230, 230) stats = GameStats(ai_settings) # 创建一个Font对象 font = pygame.font.SysFont("arial", 36) font.set_bold(True) clock = pygame.time.Clock() wait_count = 0 invincible_count = 0 ranking_is_show = False # 开启游戏主循环 while True: clock.tick(100) # 监视键盘鼠标 gf.check_events(ai_settings, screen, tank, tank2, bullets, stats) if stats.game_active: if stats.game_step == GameStep.login: wait_count += 1 user_id = tank_map.get_map("user_id") gf.login(screen, wait_count, user_id) if wait_count > 100: wait_count = 0 elif stats.game_step == GameStep.init: wait_count = 0 gf.start_image_update(tank, screen) elif stats.game_step == GameStep.ready: gf.init_home(ai_settings, screen) # 关卡信息显示 wait_count += 1 text_surface = font.render(u'level {0}'.format(stats.level), False, ai_settings.failed_color) text_rect = text_surface.get_rect() text_rect.centerx = screen.get_rect().centerx text_rect.centery = screen.get_rect().centery screen.fill(ai_settings.bg_color) screen.blit(text_surface, text_rect) pygame.display.flip() if wait_count == 100: wait_count = 0 stats.game_step = GameStep.start elif stats.game_step == GameStep.start: ranking_is_show = False # 显示第二个英雄 if ai_settings.has_tank2 and tank2 is None: tank2 = Tank(ai_settings, screen, 2) tank2.x = 300 tank2.rect.bottom = screen.get_rect().bottom - 20 tank2.y = tank2.rect.y tank2.moving_image = tank2.image tank_map.set_map("double_flg", 1) if not ai_settings.has_tank2: tank2 = None wait_count += 1 # 每隔500,刷出敌人 if wait_count == 500: wait_count = 0 if len(enemies) < ai_settings.enemies_allowed: gf.create_fleet(ai_settings, screen, enemies) # 无敌的计算 if tank.is_invincible or (tank2 is not None and tank2.is_invincible): invincible_count += 1 if invincible_count == 400: invincible_count = 0 tank.is_invincible = False if tank2 is not None: tank2.is_invincible = False # 刷新英雄坦克位置 tank.update() if tank2 is not None: tank2.update() # enemy.upadte(bullets) # 其他显示精灵刷新 gf.update_bullets(ai_settings, enemies, tank, tank2, bullets, enemy_bullets, screen, stats, booms) gf.update_enemies(enemies, enemy_bullets, stats) gf.update_booms(booms) gf.update_screen(ai_settings, screen, tank, tank2, enemies, bullets, enemy_bullets, booms) # print(len(enemy_bullets)) elif stats.game_step == GameStep.levelChange: wait_count = 0 stats.level += 1 tank.x = 120 tank.y = 280 stats.game_step = GameStep.init ai_settings.enemies_allowed = ai_settings.enemies_all * stats.level gf.init_tank(tank, 0, screen) if tank2 is not None: gf.init_tank(tank2, 1, screen) stats.game_step = GameStep.ready elif stats.game_step == GameStep.total: # 显示排行榜 if not ranking_is_show: ranking_is_show = True gf.show_ranking_list(screen) else: gf.over_image_update(screen)
def input_text(value): user_id = tank_map.get_map("user_id") if len(user_id) < 10: user_id = user_id + str(value) tank_map.set_map("user_id", user_id)
def delete_bullets(ai_settings, enemies, tank, tank2, bullets, enemy_bullets, screen, stats, booms): # 删除已消失的子弹 for bullet in bullets.copy(): if bullet.rect.top <= 0: bullets.remove(bullet) bullet.owner.bullet_count -= 1 # 显示爆炸 show_boom(ai_settings, screen, booms, bullet.x, bullet.y) # print(len(bullets)) if bullet.rect.right >= screen.get_rect().right: bullets.remove(bullet) bullet.owner.bullet_count -= 1 # 显示爆炸 show_boom(ai_settings, screen, booms, bullet.x, bullet.y) # print(len(bullets)) if bullet.rect.left <= 0: bullets.remove(bullet) bullet.owner.bullet_count -= 1 # 显示爆炸 show_boom(ai_settings, screen, booms, bullet.x, bullet.y) # print(len(bullets)) if bullet.rect.bottom >= screen.get_rect().bottom: bullets.remove(bullet) bullet.owner.bullet_count -= 1 # 显示爆炸 show_boom(ai_settings, screen, booms, bullet.x, bullet.y) # print(len(bullets)) # 删除已消失的子弹 for bullet in enemy_bullets.copy(): if bullet.rect.top <= 0: enemy_bullets.remove(bullet) bullet.owner.bullet_count -= 1 # print(len(bullets)) if bullet.rect.right >= screen.get_rect().right: enemy_bullets.remove(bullet) bullet.owner.bullet_count -= 1 # print(len(bullets)) if bullet.rect.left <= 0: enemy_bullets.remove(bullet) bullet.owner.bullet_count -= 1 # print(len(bullets)) if bullet.rect.bottom >= screen.get_rect().bottom: enemy_bullets.remove(bullet) bullet.owner.bullet_count -= 1 # print(len(bullets)) # 碰撞检测,如果有碰撞,删掉碰撞的精灵 # 子弹碰到后抵消 collisions = pygame.sprite.groupcollide(bullets, enemy_bullets, True, True) for collide_bullet, collide_enemy_bullets in collisions.items(): collide_bullet.owner.bullet_count -= 1 for enemy_bullet in collide_enemy_bullets: enemy_bullet.owner.bullet_count -= 1 # 子弹攻击到敌人后,一起消失 collisions = pygame.sprite.groupcollide(bullets, enemies, True, True) # if len(collisions) > 0: # print(collisions) for bullet, kill_enemies in collisions.items(): score = tank_map.get_map("score") score += 100 * stats.level tank_map.set_map("score", score) bullet.owner.bullet_count -= 1 # 显示爆炸 show_boom(ai_settings, screen, booms, bullet.x, bullet.y) for enemy in kill_enemies: enemies.remove(enemy) ai_settings.enemies_allowed -= 1 if ai_settings.enemies_allowed == 0: bullets.empty() enemy_bullets.empty() booms.empty() stats.game_step = GameStep.levelChange # 子弹打到砖墙时动作 bricks = tank_map.get_map(MapType.brick.name) collisions = pygame.sprite.groupcollide(bullets, bricks, True, True) for bullet in collisions.keys(): bullet.owner.bullet_count -= 1 # 显示爆炸 show_boom(ai_settings, screen, booms, bullet.x, bullet.y) collisions = pygame.sprite.groupcollide(enemy_bullets, bricks, True, True) for bullet in collisions.keys(): bullet.owner.bullet_count -= 1 # 子弹打到钢铁墙时动作 steels = tank_map.get_map(MapType.steel.name) collisions = pygame.sprite.groupcollide(bullets, steels, True, False) for bullet in collisions.keys(): bullet.owner.bullet_count -= 1 # 显示爆炸 show_boom(ai_settings, screen, booms, bullet.x, bullet.y) collisions = pygame.sprite.groupcollide(enemy_bullets, steels, True, False) for bullet in collisions.keys(): bullet.owner.bullet_count -= 1 # 被敌人子弹攻击后触发 collisions = pygame.sprite.spritecollide(tank, enemy_bullets, True) if len(collisions) > 0 and not tank.is_invincible: for bullet in collisions: bullet.owner.bullet_count -= 1 # 显示爆炸 show_boom(ai_settings, screen, booms, bullet.x, bullet.y) score = tank_map.get_map("score") score -= 200 tank_map.set_map("score", score) init_tank(tank, 0, screen) # tank.is_invincible = True if tank2 is not None: collisions = pygame.sprite.spritecollide(tank2, enemy_bullets, True) if len(collisions) > 0 and not tank2.is_invincible: score = tank_map.get_map("score") score -= 200 tank_map.set_map("score", score) init_tank(tank2, 1, screen) # 老家被打到 home = tank_map.get_map(MapType.home.name) collisions = pygame.sprite.spritecollide(home, enemy_bullets, True) if len(collisions) > 0: WallHome.break_home(home) update_score() stats.game_step = GameStep.total bullets.empty() enemy_bullets.empty() booms.empty() collisions = pygame.sprite.spritecollide(home, bullets, True) if len(collisions) > 0: WallHome.break_home(home) update_score() stats.game_step = GameStep.total bullets.empty() enemy_bullets.empty() booms.empty()
def check_keydown_events(event, ai_settings, screen, tank, tank2, bullets, stats): if stats.game_step == GameStep.login: key = event.key unicode = event.unicode # print(key) # 只有 if pygame.K_0 <= key <= pygame.K_9 or pygame.K_a <= key <= pygame.K_z: if unicode != "": char = unicode else: char = chr(key) input_text(char) elif key == pygame.K_BACKSPACE: user_id = tank_map.get_map("user_id") print(user_id) print(type(user_id)) print(user_id[0:-1]) user_id = user_id[0:-1] tank_map.set_map("user_id", user_id) elif stats.game_step == GameStep.init: if event.key == pygame.K_UP: if tank.y == 280: tank.y = 385 tank.y -= 35 elif event.key == pygame.K_DOWN: if tank.y == 350: tank.y = 245 tank.y += 35 elif event.key == pygame.K_SPACE: if tank.y > 280: ai_settings.has_tank2 = True else: ai_settings.has_tank2 = False tank.x = 180 tank.rect.bottom = screen.get_rect().bottom - 20 tank.y = tank.rect.y tank.moving_image = tank.image stats.game_step = GameStep.ready elif stats.game_step == GameStep.start: if event.key == pygame.K_RIGHT: # 坦克右移 tank.moving_right = True tank.direction_priority.append(Direction.right) elif event.key == pygame.K_LEFT: tank.moving_left = True tank.direction_priority.append(Direction.left) elif event.key == pygame.K_UP: tank.moving_up = True tank.direction_priority.append(Direction.up) elif event.key == pygame.K_DOWN: tank.moving_down = True tank.direction_priority.append(Direction.down) elif event.key == pygame.K_SPACE: fire_bullet(ai_settings, screen, tank, bullets) if tank2 is not None: if event.key == pygame.K_d: # 坦克右移 tank2.moving_right = True tank2.direction_priority.append(Direction.right) elif event.key == pygame.K_a: tank2.moving_left = True tank2.direction_priority.append(Direction.left) elif event.key == pygame.K_w: tank2.moving_up = True tank2.direction_priority.append(Direction.up) elif event.key == pygame.K_s: tank2.moving_down = True tank2.direction_priority.append(Direction.down) elif event.key == pygame.K_j: fire_bullet(ai_settings, screen, tank2, bullets)