def need_transform(self, stats): if self.moving_right and self.rect.right >= self.screen_rect.right: return True if self.moving_left and self.rect.left <= 0: return True if self.moving_up and self.rect.top <= 0: return True if self.moving_down and self.rect.bottom >= self.screen_rect.bottom - 20: return True # 随机改变行走方向 rand_int = random.randint(0, 1000) if rand_int > 900: self.ai_settings.enemy_transform += 1 if self.ai_settings.enemy_transform > 10: # 转向太过频繁,再次均衡 self.ai_settings.enemy_transform = 0 return True collisions = pygame.sprite.spritecollide( self, tank_map.get_map(MapType.brick.name), False) if len(collisions) > 0: self.back_for_collide(stats) return True collisions = pygame.sprite.spritecollide( self, tank_map.get_map(MapType.steel.name), False) if len(collisions) > 0: self.back_for_collide(stats) return True collisions = pygame.sprite.spritecollide( self, tank_map.get_map(MapType.seawater.name), False) if len(collisions) > 0: self.back_for_collide(stats) return True return False
def must_stop(self): if self.moving_right and self.rect.right >= self.screen_rect.right: return True if self.moving_left and self.rect.left <= 0: return True if self.moving_up and self.rect.top <= 0: return True if self.moving_down and self.rect.bottom >= self.screen_rect.bottom - 20: return True # if self.hasCollide: # self.hasCollide = False # else: collisions = pygame.sprite.spritecollide( self, tank_map.get_map(MapType.brick.name), False) if len(collisions) > 0: return self.back_for_collide(collisions) collisions = pygame.sprite.spritecollide( self, tank_map.get_map(MapType.steel.name), False) if len(collisions) > 0: self.back_for_collide(collisions) return True collisions = pygame.sprite.spritecollide( self, tank_map.get_map(MapType.seawater.name), False) if len(collisions) > 0: self.back_for_collide(collisions) return True return False
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 update_score(): sql = "select * from user_info WHERE user_id = %s and double_flg = %s" args = (tank_map.get_map("user_id"), tank_map.get_map("double_flg")) results = coonDB.query(sql, args) score = 0 for row in results: score = row[1] if score < tank_map.get_map("score"): sql = "update user_info set score = %s where user_id = %s and double_flg = %s" args = (tank_map.get_map("score"), tank_map.get_map("user_id"), tank_map.get_map("double_flg")) update(sql, args)
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 init_home(ai_settings, screen): # 创建一个砖墙编组 create_map(ai_settings, screen) home = tank_map.get_map(MapType.home.name) WallHome.normal_home(home)
def update_screen(ai_settings, screen, tank, tank2, enemies, bullets, enemy_bullets, booms): """更新屏幕上的图像,并切换到新屏幕""" # 每次循环时都重绘屏幕 screen.fill(ai_settings.bg_color) # 后面重绘所有子弹 for bullet in bullets.sprites(): bullet.draw_bullet() # 后面重绘所有子弹 for bullet in enemy_bullets.sprites(): bullet.draw_bullet() # 重绘所有敌人 for enemy in enemies.sprites(): enemy.blit_me() tank.blit_me() tank.blit_invincible() if tank2 is not None: tank2.blit_me() tank2.blit_invincible() # enemy.blitme() # enemies.draw(screen) # 重绘所有炸弹 for boom in booms.sprites(): boom.blit_me() # 重绘地图 bricks = tank_map.get_map(MapType.brick.name) bricks.draw(screen) steels = tank_map.get_map(MapType.steel.name) steels.draw(screen) seawater = tank_map.get_map(MapType.seawater.name) seawater.draw(screen) grassland = tank_map.get_map(MapType.grassland.name) grassland.draw(screen) home = tank_map.get_map(MapType.home.name) home.blit_me() # 积分维护 font = pygame.font.SysFont("arial", 20) area_y = screen.get_rect().bottom - 20 rect = pygame.Rect(0, area_y, screen.get_rect().width, 20) pygame.draw.rect(screen, (60, 60, 60), rect) text_user_id_lbl = font.render("User :"******"user_id") text_user_id = font.render(user_id, False, (255, 255, 255)) text_rect = text_user_id.get_rect() text_rect.x = 80 text_rect.y = area_y text_score_lbl = font.render("Score :", False, (255, 255, 255)) score_rect_lbl = text_score_lbl.get_rect() score_rect_lbl.x = 220 score_rect_lbl.y = area_y score = tank_map.get_map("score") text_score = font.render(str(score), False, (255, 255, 255)) score_rect = text_score.get_rect() score_rect.x = 300 score_rect.y = area_y screen.blit(text_user_id_lbl, text_rect_lbl) screen.blit(text_user_id, text_rect) screen.blit(text_score_lbl, score_rect_lbl) screen.blit(text_score, score_rect) # 让最近绘制的屏幕可见 pygame.display.flip()
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)