import pygame from code.engine.a_star import AStar from code.engine.animation import Animation from code.engine.sprite import Sprite from code.game_global import g class Walker: """ 行走者,8个方向的行走图 """ config = { 0: [56, 96, 6, 9], 1: [40, 68, 6, 4], 2: [36, 64, 6, 4], 4: [96, 112, 15, 4] } def __init__(self, walker_id, mx, my, face=0): """ mx:人物在地图小格子里的坐标 my:人物在地图小格子里的坐标 """ self.mx = mx self.my = my self.x = mx * 16 self.y = my * 16 self.walker_id = walker_id # 根据walker_id获取不同的cell_w,cell_h的参数 self.cell_w = self.config[walker_id][0] self.cell_h = self.config[walker_id][1] self.offset_y = self.config[walker_id][2] self.column = self.config[walker_id][3] # 渲染坐标 self.render_x = int(self.x - self.cell_w / 2) + 8 self.render_y = self.y - self.cell_h + self.offset_y + 16 # 加载动画 self.walker_img = pygame.image.load(f'./resource/PicLib/all_char/{walker_id}.png').convert_alpha() self.animations = [] for i in range(8): animation = Animation(self.render_x, self.render_y, self.walker_img, self.cell_w, self.cell_h, 700, True, [self.column * i, self.column * (i + 1) - 1]) self.animations.append(animation) # 初始化面向 self.face = face # 0上 1下 2左 3右 4上左 5下右 6下左 7上右 self.walking = False # false静止状态 true行走状态 # 角色下一步需要去的格子 self.next_mx = 0 self.next_my = 0 self.step = 2 # 每帧移动的像素 # 寻路路径 self.path = [] # 当前路径下标 self.path_index = 0 def logic(self): # 更新动画 if self.walking: self.animations[self.face].update() # 移动 self.move() # 自动走下一步 self.auto_goto() def render(self, map_x, map_y): """ 渲染行走者 """ render_x = map_x + self.render_x render_y = map_y + self.render_y if render_x < -self.cell_w or render_x > 640 or render_y < -self.cell_h or render_y > 480: """ 人物在屏幕外,不需要渲染 """ return if self.walking: self.animations[self.face].draw_src(g.screen, render_x, render_y) else: Sprite.draw(g.screen, self.walker_img, render_x, render_y, 0, self.face, self.cell_w, self.cell_h) def goto(self, mx, my): """ :param mx: 地图小格子中的目标点 :param my: 地图小格子中的目标点 """ self.next_mx = mx self.next_my = my self.walking = True # 设置人物面向 if self.next_mx == self.mx and self.next_my < self.my: # 上 self.face = 0 elif self.next_mx == self.mx and self.next_my > self.my: # 下 self.face = 1 elif self.next_mx < self.mx and self.next_my == self.my: # 左 self.face = 2 elif self.next_mx > self.mx and self.next_my == self.my: # 右 self.face = 3 elif self.next_mx < self.mx and self.next_my < self.my: # 上左 self.face = 4 elif self.next_mx > self.mx and self.next_my > self.my: # 下右 self.face = 5 elif self.next_mx < self.mx and self.next_my > self.my: # 下左 self.face = 6 elif self.next_mx > self.mx and self.next_my < self.my: # 上右 self.face = 7 else: self.walking = False def move(self): if not self.walking: return dest_x = self.next_mx * 16 dest_y = self.next_my * 16 # 向目标位置靠近 if self.x < dest_x: self.x += self.step if self.x >= dest_x: self.x = dest_x elif self.x > dest_x: self.x -= self.step if self.x <= dest_x: self.x = dest_x if self.y < dest_y: self.y += self.step if self.y >= dest_y: self.y = dest_y elif self.y > dest_y: self.y -= self.step if self.y <= dest_y: self.y = dest_y # 更新渲染坐标 self.render_x = int(self.x - self.cell_w / 2) + 8 self.render_y = self.y - self.cell_h + self.offset_y + 16 # 角色当前位置 self.mx = int(self.x / 16) self.my = int(self.y / 16) # 到达了目标点 if self.x == dest_x and self.y == dest_y: self.walking = False def find_path(self, map2d, end_point): """ :param map2d: 地图 :param end_point: 寻路终点 """ if end_point[0] == self.mx and end_point[1] == self.my: return start_point = (self.mx, self.my) path = AStar(map2d, start_point, end_point).start() if path is None: return self.path = path self.path_index = 0 def move_by_path(self, path): """ 通过已经准备好的路径,直接移动 """ self.path = path self.path_index = 0 def auto_goto(self): """ 自动寻路 """ if self.walking: return # 如果寻路走到终点了 if self.path_index == len(self.path): self.path = [] self.path_index = 0 # self.walking = False # 如果没走到终点,就往下一个格子走 else: self.goto(self.path[self.path_index].x, self.path[self.path_index].y) self.path_index += 1 # self.walking = True def set_point(self, mx, my): """ 设置位置 """ self.mx = mx self.my = my self.x = mx * 16 self.y = my * 16 # 渲染坐标 self.render_x = int(self.x - self.cell_w / 2) + 8 self.render_y = self.y - self.cell_h + self.offset_y + 16