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

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

Carregando publicação patrocinada...
2

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

1

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.

1

Poderia ser então 64 no lugar de 1 no movimento e o speed inicializar com algo como 1.2?

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

1

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??

1

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.

1

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/

2

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??

1

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.

1

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.

1

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?

1
0
0
0