You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
6.1 KiB

4 months ago
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