[PEDIDO DE AJUDA][PURE MAGIC][INDIE][PYGAME] MOVIMENTO DO PERSONAGEM

Eai galera tudo bem? Então venho aqui pedir ajuda no meu game, estou com uma dificuldade na parte do código que é a seguinte, no video abaixo demonstra o que está acontecendo.

[PURE MAGIC] Movement | VIDEO

O que eu quero fazer é arrumar o movimento do personagem com o speed gerado por level , mais itens e o tipo de ground, igual ao do tibia, porém, primeiro preciso entender como fazer ele andar na velocidade correta só com o valor do speed. O que tem que ser feito é que o personagem deve andar 64pixels em uma direção a uma velocidade x, mas como fazer isso é o problema.

@staticmethod
    def check_map_colision(new_posx, new_posy):
        loaded_map = json.loads(open(os.path.join(BASE_DIR, "data", "map.json")).read())
        player_rect = pygame.Rect(new_posx, new_posy, 64, 64)
        for tile in loaded_map["tiles"]:
            for obj in tile["objects"]:
                if obj["id"] > 1:
                    obj_rect = pygame.Rect(int(tile["posx"]), int(tile["posy"]), 64, 64)
                    if player_rect.colliderect(obj_rect):
                        return True
        return False
        
def input(self):
    key = pygame.key.get_pressed()
    mods = pygame.key.get_mods()
    mouse = pygame.mouse.get_pressed()

    new_posx = self.rect.x
    new_posy = self.rect.y

    ############
    # MOVEMENT #
    ############
    if key[pygame.K_LEFT] or key[pygame.K_a]:
        new_posx -= 64
        self.context["direction"] = "WEST"
        self.frame_motion()
    if key[pygame.K_RIGHT] or key[pygame.K_d]:
        new_posx += 64
        self.context["direction"] = "EAST"
        self.frame_motion()

    if key[pygame.K_UP] or key[pygame.K_w]:
        new_posy -= 64
        self.context["direction"] = "NORTH"
        self.frame_motion()
        
    if key[pygame.K_DOWN] or key[pygame.K_s]:
        new_posy += 64
        self.context["direction"] = "SOUTH"
        self.frame_motion()
        if not self.check_map_colision(new_posx, new_posy):
            self.rect.x = new_posx
            self.rect.y = new_posy
            self.context["posx"] = self.rect.x
            self.context["posy"] = self.rect.y
            self.can_move = True
        else:
            self.can_move = False

Caso precisem verificar o código todo, só em solicitar que eu forneço sem problemas.

Quando faço a movimentação do personagem eu separo a speed e o passo para ter mais flexibilidade e aproveitar melhor a orientação a objetos.

Um exemplo seria mais ou menos assim:


# Apenas um exemplo de personagem
class Personagem(Objeto):
    
    def __init__(self):
        # Posições iniciais
        self.x = 0
        self.y = 0
        # Valor da velocidade
        self.speed = 2
        
    ...
    
    # Função que faz andar
    def walk(self, direction):
        self.x += direction[0] * self.speed
        self.y += direction.[1] * self.speed
        
    def level_up(self):
        self.speed += 1
        ...
        
        
# Criando o jogador
player = Personagem()
# Definindo as direções para a movimentação
movimento = { UP: (0, -1), DOWN: (0, 1), LEFT: (-1, 0), RIGHT: (1, 0)  }

# Andando
player.walk(movimento.DOWN)

É apenas um exemplo, mas dessa forma basta alterar a variavel speed da maneira que quiser. O passo do movimento pode ser alterado também para ser maior do que um pixel por padrão, tudo depende do quanto ele irá se movimentar na situação mais "lenta".

Ja tentei assim porém eu utilizo 64 pixels a cada movimento, se eu tento utilizar o speed multiplicando por um valor x, ele fica muito mais rapido e o que eu quero na real, é que ele desloque os 64 pixels em um tempo y o qual é definido pelo speed.
Poderia ser então 64 no lugar de 1 no movimento e o speed inicializar com algo como 1.2? ```py ... self.speed = 1.2 ... movimento = { UP: (0, -64), DOWN: (0, 64), LEFT: (-64, 0), RIGHT: (64, 0) } ``` Utilizando um número float pode dar mais controle para não aumentar tanto assim a velocidade. Sei que de primeira não parece, mas multiplicar o passo de 64 por um valor x não apenas "aumenta" o passo. Aumentar a velocidade, na prática, é apenas andar mais no mesmo tempo. Talvez tendo o código completo dê de a gente testar e entender melhor.
Acho que poderia funcionar, mas a um probleminha se vc multiplicar speed pelo 64 nao séria mais 64 pois houve uma multiplicação efetuada e na new_pos seria somada a um valor diferente e o personagem não se movimentaria em blocos de 64, entende??
isso ai, ele seria nesse caso apenas 20% maior que 64 e ele ficaria numa posição que eu nao quero, ele precisa andar 64 pixels porém, ele precisa correr esses 64 pixel em um tempo X.
voce pode tentar isso: ``` import time ti = time.time() while True: tf = time.time() dt = tf - ti ti = tf if dt >= 500: if key[pygame.K_LEFT] or key[pygame.K_a]: new_posx -= 64 self.context["direction"] = "WEST" self.frame_motion() if key[pygame.K_RIGHT] or key[pygame.K_d]: new_posx += 64 self.context["direction"] = "EAST" self.frame_motion() if key[pygame.K_UP] or key[pygame.K_w]: new_posy -= 64 self.context["direction"] = "NORTH" self.frame_motion() if key[pygame.K_DOWN] or key[pygame.K_s]: new_posy += 64 self.context["direction"] = "SOUTH" self.frame_motion() if not self.check_map_colision(new_posx, new_posy): self.rect.x = new_posx self.rect.y = new_posy self.context["posx"] = self.rect.x self.context["posy"] = self.rect.y self.can_move = True else: self.can_move = False ``` Desta forma o movimento so ira ocorrer com um certo delay, mas nao afetar os updates. Claro que o 500 do if e um exemplo coloque o valor que achar melhor. Este valor é produzido em milissegundos só para ficar mais declarado. Fonte: https://humberto.io/pt-br/blog/desbravando-o-pygame-5-movimento-e-colisao/

Olá, parece que voce esta fazendo um otimo trabalho, mas não consegui entender a questão de movimento, parece que o player está se movendo em blocos de 64 pixels, acho que o tercho de codigo fornecido não ajudou muito a compreenção. Não entendi o problema o player parece estar se movendo muito rapido no video fornecido, ou o video foi acelerado??

Esse é o problema , ele esta se movimentando muito rápido e eu queria melhorar isso, ter um influencia sobre a velocidade pois quando eu tento utilizar o o cálculo do tick / 1000 (dt) , ele não calcula o movimento correto. Do ponto A ao ponto B ele movimenta 64 pixels todas as vezes, porem eu quero que ele leve um tempo para percorrer esse movimento. Caso queira o código para me ajudar deixo publico sem problemas.
Entendo acho que isso ocorre, pois quando a tecla e precionada ela so continua a fazer os movimentos sem pausa. poderia talvez adicinar uma pausa de milissegundos de um movimento para o outro. ``` pygame.time.delay(30) # delay de 30 milissegundos ``` sugestão de onde colocar: ``` if key[pygame.K_LEFT] or key[pygame.K_a]: new_posx -= 64 self.context["direction"] = "WEST" self.frame_motion() pygame.time.delay(30) # adicione um em cada if ``` E por favor compartilhe o código se possível adoraria contribuir em um projeto como este. Além desta ajuda indicaria a deixar a parte do código responsável pelo movimento em uma função separada.
ja tentei, outro problema, quando eu aumento o key delay todos updates sãos atrasados e na verdade eu só queria que o movimento fosse separado da taxa de atualização do mundo, entende?
Como podemos entrar em contato pra conversar mais sobre ficaria feliz em ter com quem compartilhar ideias, e o projeto também.
Nao sei, qual é sua idea?? por onde podemos entra em contato?? acho melho no github
Acho que discord seria uma boa me add lá. igribeiro#9869
Tenho conta no discord nao, acha melhor pelo github com colaborador assim posso enviar pull request