Executando verificação de segurança...
5

[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.

O RESULTADO

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
    }
  },
  ...

Carregando publicação patrocinada...
2

Oi, sou eu de novo do post anterior, minha sugestao seria utilizar a bliblioteca numba em https://numba.pydata.org/ voce pode encontrar mais informações mas basicamente ele posibilita compilar partes do codigo, assim tendo um desempenho melhor na ultima vez que vi o numba, ele utilizava o JIT da JVM do java, mas nao sei agora pois sempre a atualizaçoes. mas como o diz ele compila uma parte do codigo posibilitando o aprimoramento do codigo, mas para isso e nessecario executar o codigo uma vez para na segunda vez funcionar e ele funciona melhor com calculos de arrays e tem uma otima compatibilidade com o numpy. e como voce pretende que seja on line e legal voce tambem conhecer o numpy para calculos e algumas bibliotecas de criptografia e a biblioteca socket.

1
1