[PURE MAGIC][INDIE][PIXEL][PYGAME] Segunda semana, tem coisa pra fazer em.
Eai galera tudo bem? Então sou eu de novo, pra quem não viu tenho feito alguns posts sobre o game, estão listados abaixo.
1 - [PURE MAGIC][INDIE][PYGAME] Meu início na criação de jogos.
2 - [PEDIDO DE AJUDA][PURE MAGIC][INDIE][PYGAME] MOVIMENTO DO PERSONAGEM
Atualização da semana dois.
Com os dias se passando eu completando meu estágio de farmacêutico, é , não sou programador, todos os dias um pouco tentando otimizar o game, ainda falta muito e vou precisar de ajuda pois muito conhecimento sobre qualidade de código ainda preciso obter, e só com a vóz da experiência poderia me ajudar.
A classe movement, foi um upgrade muito importante no projeto que ainda precisa ser otimizado, o os calculos foram baseasdos no Canary Server, porém algumas coisas são dificeis de entender por não compreender c++ e tampouco produção de jogos.
Ainda estou com alguns problemas no movimento, relacionado a macies em que ele percorre o caminho, portanto se alguem tiver uma dica que poderia me dar.
Com o caminhar do jogo, preciso dar prioridade para renderização, sinto que ainda tenho muito a melhorar, existem muitos loops for dentro do código para gerenciar mapa, player, e minimap, isso gera um gasto "desnecessário" pois até estão não encontrei uma maneira melhorar de reduzir o código.
Porém para melhorar o desempenho utilizo o pygame.sprite.DirtySprite que gerencia o cache as imagens para que assim as posições sejam apenas atualizadas e não recarregadas colocadas e exlcuidas em algum momento, reduzindo o consumo de processamento.
O video está um pouco com lag, mas é por causa que o computador é ruim, mas o movement speed tem funcionado muito bem, apenas necessita de ajustes quanto ao deslizamento da imagens de forma mais suave.
creature.py
def move(self):
key = pygame.key.get_pressed()
new_posx = self.rect.x
new_posy = self.rect.y
if key[pygame.K_LEFT] or key[pygame.K_a] and not self.is_walking:
self.is_walking = True
self.target_pos = [new_posx - TILESIZE, new_posy]
direction = "WEST"
self.context["direction"] = direction
if key[pygame.K_RIGHT] or key[pygame.K_d] and not self.is_walking:
self.is_walking = True
self.target_pos = [new_posx + TILESIZE, new_posy]
self.context["direction"] = "EAST"
if key[pygame.K_UP] or key[pygame.K_w] and not self.is_walking:
self.is_walking = True
self.target_pos = [new_posx, new_posy - TILESIZE]
self.context["direction"] = "NORTH"
if key[pygame.K_DOWN] or key[pygame.K_s] and not self.is_walking:
self.is_walking = True
self.target_pos = [new_posx, new_posy + TILESIZE]
self.context["direction"] = "SOUTH"
if not self.check_map_collision(self.target_pos[0],
self.target_pos[1]):
self.update_movement()
else:
self.is_walking = False
def update_movement(self):
"""
Nesta versão, calculamos a diferença em x e y entre a posição atual e a posição alvo.
Em seguida, verificamos se a distância a ser percorrida em x ou y é maior do que a
distância que podemos percorrer em um passo. Se for, ajustamos a posição atual em
ireção à posição alvo com base na distância permitida. Se não, definimos a posição
atual diretamente como a posição alvo. Isso deve garantir que o objeto se mova
uavemente em direção à posição alvo, independentemente do número de TILESIZE.
"""
if self.target_pos is not None and self.is_walking:
dx = self.target_pos[0] - self.rect.x
dy = self.target_pos[1] - self.rect.y
distance = TILESIZE // self.movement.step_tile()
if abs(dx) > distance:
self.rect.x += (dx / abs(dx)) * distance
else:
self.rect.x = self.target_pos[0]
if abs(dy) > distance:
self.rect.y += (dy / abs(dy)) * distance
else:
self.rect.y = self.target_pos[1]
self.frame_motion()
if [self.rect.x, self.rect.y] == self.target_pos:
self.is_walking = False
self.target_pos = [self.rect.x, self.rect.y]
self.context["posx"] = self.rect.x
self.context["posy"] = self.rect.y
movement.py
class Movement:
"""
O calculo foi baseado no post feito no site 'https://tibia.fandom.com/wiki/Speed_Breakpoints'.
A formula utilizada na função calculate_step_speed foi retirada do código base do canary,
o mesmo tem a função de gerar um valor o qual será utilizado na função get_break_point,
que tem como funcionalidade retornar em qual reange do breakpoint entra o valor, para
então calcular o delay na função calculate_speed_delay que retorna o ms utilizado
para aquele personagem naquele tile.
"""
def __init__(self, context: dict):
self.context = context
self.speedA = 857.36
self.speedB = 261.29
self.speedC = -4795.01
self.breakpoints = json.loads(open(f"{BASE_DIR}\\data\\configurations\\speed_break_points.json", "r").read())
self.ground_friction = self.get_ground_speed()
self.is_walking = False
self.new_pos = 0
self.direction = None
def get_break_point(self, friction: int) -> int:
walk_speed = self.calculate_step_speed(self.speed())
for bpoint in self.breakpoints:
if bpoint["friction"] == friction:
for key, min_speed in bpoint["breakpoints"].items():
if walk_speed >= min_speed:
if int(key) + 1 > 17:
return 17
if walk_speed in range(min_speed, bpoint["breakpoints"][f"{int(key) + 1}"]):
return int(key)
@staticmethod
def get_ground_speed():
return 110
def step_delay(self):
ground_friction = self.ground_friction
break_point = self.get_break_point(ground_friction)
return self.calculate_speed_delay(break_point)
def step_tile(self):
walk_speed = self.calculate_step_speed(self.speed())
if self.step_delay() <= 100:
return 1 + ((1000 * 2 // walk_speed))
elif 100 < self.step_delay() <= 400:
return 1 + ((1000 * 4 // walk_speed))
elif 400 < self.step_delay() <= 800:
return 1 + ((1000 * 8 // walk_speed))
elif self.step_delay() > 800:
return 1 + ((1000 * 16 // walk_speed))
def speed(self):
base_speed = 109
level_speed = self.context["level"]
debuff_speed = [x["speed"] for x in self.context["debuffs"]]
return base_speed + level_speed - debuff_speed[0]
@staticmethod
def calculate_speed_delay(bpoint: int):
if 1 <= bpoint <= 17:
calc = 850 - ((850 // 17) * bpoint) + 50
return calc
else:
raise Exception("Invalid breakpoint")
def calculate_step_speed(self, step_speed):
if step_speed > -self.speedB:
formula = math.floor((self.speedA * math.log(step_speed + self.speedB) + self.speedC) + 0.5)
return max(int(formula), 1)
else:
return 1
speed_break_points.json
[
{
"friction": 70,
"breakpoints": {
"1": 0,
"2": 0,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0,
"10": 0,
"11": 0,
"12": 0,
"13": 111,
"14": 142,
"15": 200,
"16": 342,
"17": 1070
}
},
{
"friction": 90,
"breakpoints": {
"1": 0,
"2": 0,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0,
"10": 0,
"11": 0,
"12": 0,
"13": 120,
"14": 147,
"15": 192,
"16": 278,
"17": 499
}
},
...