# TurnGame.py import pygame from Constant import scrrr_width, scrrr_height, GAMEOVER import random from Map import Map from Sunshine import Sunshine from PeaShooter import PeaShooter from PeaBullet import PeaBullet from Zombie import Zombie # 主程序 class MainGame: score = 0 # 存储所有地图坐标点 map_points_list = [] # 存储所有的地图块 map_list = [] # 存储所有植物的列表 plants_list = [] plants_pool = [0, 0, 0, 0, 0, 0] plants_pool_list = [] # 存储所有豌豆子弹的列表 peabullet_list = [] peabullet_count = 0 # 新增存储所有僵尸的列表 zombie_list = [] window = pygame.display.set_mode([scrrr_width, scrrr_height]) # 0为植物回合,1为僵尸回合,2为玩家回合 game_turn = 2 something_in_mouse_store = False mouse_pressed = False mouse_get: PeaBullet = None mouse_store = [] timecount = 50 shoule_creat_zombie = False turn_count = 0 # 开始游戏 def start_game(self): # 初始化窗口 # pygame.display.init() # 初始化坐标和地图 self.init_plant_points() pygame.font.init() self.init_map() initmap = self.map_list[1][1] self.creat_plant(PeaShooter(initmap.position[0], initmap.position[1], 1), 1) self.creat_plant(PeaShooter(initmap.position[1], initmap.position[1], 1), 1) for i in range(0, 6): # self.creat_plant(PeaShooter((i - 1) * 80 + 4 * 80, 0, 1), 1) peashooter = PeaShooter((i - 1) * 80 + 5 * 80, 0, i + 1) MainGame.plants_pool_list.append(peashooter) # 只要游戏没结束,就一直循环 while not GAMEOVER: self.load_ui() # 需要反复加载地图 self.load_map() # 调用加载植物的方法 self.load_plants() # 调用加载所有子弹的方法 self.load_peabullets() # 调用事件处理的方法 # 调用展示僵尸的方法 self.load_zombies() # 计数器增长,每数到100,调用初始化僵尸的方法 self.turn() self.update_pool() self.debugg() # pygame自己的休眠 pygame.time.wait(10) # 实时更新 pygame.display.update() # 显示哪里种植了植物和棋盘上有多少植物 def debugg(self): self.timecount += 1 if self.timecount > 500: for i in range(len(self.map_list)): print() for j in range(len(self.map_list[i])): print(self.map_list[i][j].can_grow, end="\t") print() print(len(self.peabullet_list)) self.timecount = 0 # 绘制物体和提示文本 def draw_object(self, object): self.window.blit(object.image, object.rect) if not isinstance(object, Sunshine): self.window.blit( self.draw_text(f"{object.damage}", 26, (255, 0, 0)), object.rect ) else: self.window.blit( self.draw_text(f"{object.money}", 26, (255, 0, 0)), object.rect ) # 更新植物池列表 def update_pool(self): for i in range(0, 6): self.plants_pool_list[i].count = self.plants_pool[i] self.window.blit( self.draw_text(f"{self.plants_pool_list[i].count}", 26, (255, 0, 0)), self.plants_pool_list[i].rect.move(50, 45), ) # 加载僵尸或者移除僵尸 def load_zombies(self): for zombie in MainGame.zombie_list: if zombie.live: self.draw_object(zombie) # self.window.blit(zombie.image, zombie.rect) else: MainGame.zombie_list.remove(zombie) def turn(self): # 主死循环每一次更新一帧 # 0为植物回合,1为僵尸回合,3为操控回合 if self.game_turn == 0: self.plants_event() # self.load_peabullets() if self.peabullet_count <= 0: self.zombie_turn_start() elif self.game_turn == 1: if self.shoule_creat_zombie == True: self.init_zombies() self.shoule_creat_zombie = False self.zombies_event() # self.zombie_turn_count += 1 if self.is_zombie_end(): self.play_turn_start() elif self.game_turn == 2: self.move_plant() pass # 初始化玩家回合 def play_turn_start(self): self.game_turn = 2 # 僵尸回合结束 def is_zombie_end(self): for zombie in MainGame.zombie_list: if zombie.stop == False: return False return True # 植物回合开始 def plant_turn_start(self): self.turn_count += 1 self.game_turn = 0 for plant in MainGame.plants_list: plant.should_fire = True plant.should_count_fire = True plant.shoot_number_count = plant.shoot_number # 僵尸回合开始 def zombie_turn_start(self): self.shoule_creat_zombie = True self.game_turn = 1 for zombie in MainGame.zombie_list: zombie.stop = False zombie.distance_count = zombie.distance # 加载ui def load_ui(self): self.window.fill((255, 255, 255)) self.window.blit( self.draw_text( f"当前回合数{self.turn_count}", 26, (255, 0, 0), ), (5, 40), ) text1 = self.draw_text("按右键拖动豌豆射手", 26, (255, 0, 0)) self.window.blit(text1, (5, 5)) # 文本绘制 def draw_text(self, content, size, color): font = pygame.font.SysFont("kaiti", size) text = font.render(content, True, color) return text # 植物创建逻辑 def creat_plant(self, plant, grade): a = plant.rect[1] // 80 - 1 b = plant.rect[0] // 80 map = MainGame.map_list[a][b] map.can_grow = False peashooter = PeaShooter(map.position[0], map.position[1], grade) MainGame.plants_list.append(peashooter) # 移动植物逻辑 def move_plant(self): # try: eventList = pygame.event.get() for event in eventList: if event.type == pygame.QUIT: self.gameOver() elif event.type == pygame.MOUSEBUTTONDOWN: x = event.pos[0] // 80 y = (event.pos[1] // 80) - 1 if y == -1: map = MainGame.map_list[6][x - 4] else: map = MainGame.map_list[y][x] print(event.pos) print(y, x) print(map.position) self.mouse_pressed = True if y == -1: number = (map.position[0] // 80) - 3 print(f"number={number}") # 此植物位置存mouse_store,植物存mouse_get self.mouse_get = PeaShooter( map.position[0], map.position[1], MainGame.plants_pool_list[number - 1].grade, ) self.mouse_store = [ [map.position[1], map.position[0]], MainGame.plants_pool_list[number - 1].grade, ] MainGame.plants_pool_list[number - 1].count -= 1 MainGame.plants_pool[number - 1] -= 1 else: # 有东西 can_grow = map.can_grow if not can_grow: print(f"{map.position} 1 not can grow") # 此植物位置存mouse_store,植物存mouse_get for plant in MainGame.plants_list: if ( plant.rect.x == map.position[0] and plant.rect.y == map.position[1] ): self.mouse_get = plant self.mouse_store = [ [map.position[1], map.position[0]], plant.grade, ] print("mouse_store get", self.mouse_store) # 删除原植物 MainGame.plants_list.remove(plant) MainGame.map_list[y][x].can_grow = True else: print(f"{map.position} 1 can grow") elif event.type == pygame.MOUSEBUTTONUP: x = event.pos[0] // 80 y = (event.pos[1] // 80) - 1 if y == -1: map = MainGame.map_list[6][x - 4] else: map = MainGame.map_list[y][x] print(map.position) self.mouse_pressed = False # 能放,清空mouse_store,此位置创建植物 can_grow = map.can_grow if can_grow: print(f"{map.position} 2 can grow") # 清空mouse_store if self.mouse_get is not None: self.creat_plant( self.mouse_get, self.mouse_get.grade, ) # self.turn_count += 1 self.plant_turn_start() else: print("1 Empty mouse_get") self.mouse_get = None else: print(f"{map.position} 2 not can grow") if not can_grow: # 不能放,且等级同,清空mouse_store,mouse_get,本植物等级加一 for plant in MainGame.plants_list: if ( plant.rect.x == map.position[0] and plant.rect.y == map.position[1] ): if self.mouse_store[1] == plant.grade: plant.grade += 1 MainGame.plants_list.remove(plant) self.creat_plant(plant, plant.grade) self.mouse_store = None self.mouse_get = None self.plant_turn_start() # 不能放,且等级不同,在原位置恢复,清空mouse_store,mouse_get print(f"{map.position} 3 not can grow") if self.mouse_get is not None: self.creat_plant( PeaShooter( self.mouse_store[0][1], self.mouse_store[0][0], self.mouse_store[1], ), self.mouse_store[1], ) print("mouse_store out", self.mouse_store) self.mouse_store = None self.mouse_get = None else: print("2 Empty mouse_store") else: print(f"{map.position} 3 can grow") if self.mouse_pressed: if self.mouse_get is not None: self.mouse_get.rect = pygame.mouse.get_pos() self.draw_object(self.mouse_get) # self.window.blit(self.mouse_get.image, self.mouse_get.rect) else: print("3 Empty mouse_get") # except IndexError: # print("Empty Index!") # 初始化坐标点 def init_plant_points(self): for y in range(1, 7): points = [] for x in range(10): point = (x, y) points.append(point) MainGame.map_points_list.append(points) print("MainGame.map_points_list", MainGame.map_points_list) points = [] for x in range(4, 10): point = (x, 0) points.append(point) MainGame.map_points_list.append(points) print("MainGame.map_points_list", MainGame.map_points_list) # 初始化地图 def init_map(self): for points in MainGame.map_points_list: temp_map_list = list() for point in points: # map = None if (point[0] + point[1]) % 2 == 0: map = Map(point[0] * 80, point[1] * 80, 0) else: map = Map(point[0] * 80, point[1] * 80, 1) # 将地图块加入到窗口中 temp_map_list.append(map) print("temp_map_list", temp_map_list) MainGame.map_list.append(temp_map_list) print("MainGame.map_list", MainGame.map_list) # 新增初始化僵尸的方法 def init_zombies(self): # 不同的 first_numbers = random.sample(range(1, 7), random.randint(1, 5)) # 生成0或1的随机数,列表推导式 second_numbers = [random.choice([0, 1]) for _ in range(len(first_numbers))] # 组合成元组 random_tuples = list(zip(first_numbers, second_numbers)) for i in random_tuples: if i[1] == 1: sunshine = Sunshine(800, i[0] * 80) MainGame.zombie_list.append(sunshine) else: zombie = Zombie(800, i[0] * 80) MainGame.zombie_list.append(zombie) # 将地图加载到窗口中 def load_map(self): for temp_map_list in MainGame.map_list: for map in temp_map_list: # map.load_map() self.window.blit(map.image, map.position) # 更新加载植物或移除植物 def load_plants(self): for plant in MainGame.plants_list + MainGame.plants_pool_list: if plant.live: self.draw_object(plant) # self.window.blit(plant.image, plant.rect) else: MainGame.plants_list.remove(plant) # 植物处理 def plants_event(self): for plant in MainGame.plants_list: self.draw_object(plant) # self.window.blit(plant.image, plant.rect) # 如果活着 if plant.should_fire: if plant.should_count_fire == True: self.peabullet_count += plant.shoot_number print("plus", self.peabullet_count) plant.should_count_fire = False self.plant_shoot(plant) # 植物射击逻辑 def plant_shoot(self, plant): plant.shot_count += 1 # 计数器到25发射一次 if plant.shot_count >= 25 and plant.shoot_number_count >= 1: # 基于当前豌豆射手的位置,创建子弹 print(plant.shoot_number_count) plant.shoot_number_count -= 1 peabullet = PeaBullet(plant, plant.bullet_damage) # 将子弹存储到子弹列表中 MainGame.peabullet_list.append(peabullet) plant.shot_count = 0 # 加载所有子弹的方法 def load_peabullets(self): for bullet in MainGame.peabullet_list: if bullet.live: self.draw_object(bullet) # self.window.blit(bullet.image, bullet.rect) bullet.move_bullet() # 调用子弹是否打中僵尸的方法 for enemy in MainGame.zombie_list: if pygame.sprite.collide_rect(bullet, enemy): # 打中僵尸之后,修改子弹的状态, bullet.live = False # 僵尸掉血 enemy.damage -= bullet.damage if enemy.damage <= 0: enemy.live = False if isinstance(enemy, Sunshine): self.plants_pool[enemy.money - 1] += 1 else: MainGame.peabullet_list.remove(bullet) self.peabullet_count -= 1 # 将所有僵尸加载到地图中 def zombies_event(self): for enemy in MainGame.zombie_list: if enemy.live: self.zombie_move(enemy) else: MainGame.zombie_list.remove(enemy) # 僵尸移动逻辑 def zombie_move(self, zombie): self.draw_object(zombie) # self.window.blit(zombie.image, zombie.rect) if zombie.live and not zombie.stop: zombie.distance_count -= zombie.speed zombie.rect.x -= zombie.speed if zombie.rect.x < -80: # 调用游戏结束方法 MainGame().gameOver() if zombie.distance_count <= 0: zombie.stop = True # 程序结束方法 def gameOver(self): self.window.blit(self.draw_text("游戏结束", 50, (255, 0, 0)), (300, 200)) print("游戏结束") pygame.time.wait(400) global GAMEOVER GAMEOVER = True