O TEMA DO FÓRUM ESTÁ EM MANUTENÇÃO. FEEDBACKS AQUI: ACESSAR

Teria como identificar no RPG MAKER MV se o personagem está em movimento ou não?

Iniciado por Mathy1x, 21/05/2020 às 23:41

Olá!! Tudo bem? Estou querendo uma ajuda, que gostaria de saber, se no RPG Maker MV, tem como por meio de plugin próprio(sem ser de outros makers) ou por meio de evento ou variáveis, fazer com que, seja identificado se o personagem está em movimento ou não, pois eu gostaria de fazer alternância de gráficos se caso ele estiver parado, e se caso ele estiver em movimento, o gráfico e animação ficarem normais. Por favor, gostaria muito de uma ajuda.

Obrigado e abraço!! :XD:
This is a JoJo's Reference?!

O que você quer é $gamePlayer.isMoving(). Retorna true se o jogador está se movendo e false caso contrário. O mesmo vale pra qualquer objeto Game_CharacterBase (inclui eventos, veículos e membros do grupo), basta acessar o objeto certo.
~ Masked

Apesar do nome muito sugestivo, o isMoving por si só não funcionará nesse caso. Fazendo uma leitura do código fonte da própria função:
Game_CharacterBase.prototype.isMoving = function() {
    return this._realX !== this._x || this._realY !== this._y;
};

  Isso quer dizer que retornará true caso as coordenadas reais (usadas para posicionamento dos sprites) forem diferentes das coordenadas lógicas (usadas para identificar colisões) e false caso contrário. Isso seria perfeito para o que você almeja fazer, se não, por um único frame enquanto o jogador está em movimento, as coordenadas reais e lógicas fossem equivalentes.
Felizmente, todos os objetos de personagem tem uma variável que armazena há quantos frames este está parado. Logo, basta verificar se o personagem está parado há mais de um frame para se certificar de que deve exibir o gráfico dele nesta pose e, caso ele esteja parado há um frame ou menos, exibir a pose dele em movimento.
Exemplo em Script
if ($gamePlayer._stopCount > 1) {
  //Jogador Parado
} else {
  //Jogador Movendo
}
[close]
Exemplo por eventos + Script Call
[close]
Oxe

Caraca Jorge Maker... eu nunca tinha reparado nisso.
Fiz uns testes aqui com esse stop count, e realmente funciona muito melhor!
Show!!

Citação de: Jorge_Maker online 22/05/2020 às 12:56
Apesar do nome muito sugestivo, o isMoving por si só não funcionará nesse caso. Fazendo uma leitura do código fonte da própria função:
Game_CharacterBase.prototype.isMoving = function() {
    return this._realX !== this._x || this._realY !== this._y;
};

  Isso quer dizer que retornará true caso as coordenadas reais (usadas para posicionamento dos sprites) forem diferentes das coordenadas lógicas (usadas para identificar colisões) e false caso contrário. Isso seria perfeito para o que você almeja fazer, se não, por um único frame enquanto o jogador está em movimento, as coordenadas reais e lógicas fossem equivalentes.
Felizmente, todos os objetos de personagem tem uma variável que armazena há quantos frames este está parado. Logo, basta verificar se o personagem está parado há mais de um frame para se certificar de que deve exibir o gráfico dele nesta pose e, caso ele esteja parado há um frame ou menos, exibir a pose dele em movimento.
Exemplo em Script
if ($gamePlayer._stopCount > 1) {
  //Jogador Parado
} else {
  //Jogador Movendo
}
[close]
Exemplo por eventos + Script Call
[close]

Não sei se vale mesmo a pena acessar uma variável privada por conta de um frame, principalmente se tratando de uma mudança gráfica: pra cálculos faz sentido, porque isso dessincroniza as coisas e isso pode acumular e tals, mas a mudança de gráfico não deve ser perceptível a ponto do jogador reparar numa diferença de 0.016s

Depender de uma variável privada viola o encapsulamento: se a variável era privada, não tem garantia que ela vai continuar existindo no futuro ou mesmo que a informação nela vai ser consistente entre versões, e a chance de uma alteração na implementação que não deveria te afetar acabar afetando aumenta. É pra isso que servem modificadores de acesso.

Fica a critério do autor do tópico decidir o que prefere, mas pessoalmente eu sempre iria com o caminho que tem menos chance de me dar dor de cabeça no futuro.

O ideal era o RM ter uma função decente pra isso, mas sabemos que nem sempre dá pra ter tudo na vida xd
~ Masked

Eliaquim:
  o/
Brandt:
  De fato, não entendo nada de javascript e caí na maracutaia da facilidade de acessar a variável privada. xd Valeu pelo toque, Masked. o/


  Voltando o assunto do tópico, embora seja um evento que ocorrerá por apenas 0.016s, não se trata de algo imperceptível (contanto que não haja queda de frames), improvável ou impossível de ser previsto: Por via de regra, ao final de cada passo dado pelo personagem (vamos considerar que 1 passo == 1 tile), este irá parar, mesmo que haja progressão no movimento, por um mísero frame, o personagem será determinado como estando em repouso. Apesar disso ser essencial para que o sistema de movimentação tile-based funcione corretamente, um sistema de poses terá de usar uma lógica um pouco diferente tendo em vista esse pequeno delay.

  Felizmente², já há uma função embutida que serve para comparar o valor acumulado pela variável _stopCount, citada por mim anteriormente, sem a necessidade de ter que acessa-la diretamente.

  Use isso em uma condição na chamada de script:
$gamePlayer.checkStop(1)


  E boa sorte. :XD:
Oxe

Citação de: Brandt online 22/05/2020 às 00:52
O que você quer é $gamePlayer.isMoving(). Retorna true se o jogador está se movendo e false caso contrário. O mesmo vale pra qualquer objeto Game_CharacterBase (inclui eventos, veículos e membros do grupo), basta acessar o objeto certo.

Muito Obrigado mesmo, ajudou muito.

Abraço!!
This is a JoJo's Reference?!

Citação de: Jorge_Maker online 22/05/2020 às 12:56
Apesar do nome muito sugestivo, o isMoving por si só não funcionará nesse caso. Fazendo uma leitura do código fonte da própria função:
Game_CharacterBase.prototype.isMoving = function() {
    return this._realX !== this._x || this._realY !== this._y;
};

  Isso quer dizer que retornará true caso as coordenadas reais (usadas para posicionamento dos sprites) forem diferentes das coordenadas lógicas (usadas para identificar colisões) e false caso contrário. Isso seria perfeito para o que você almeja fazer, se não, por um único frame enquanto o jogador está em movimento, as coordenadas reais e lógicas fossem equivalentes.
Felizmente, todos os objetos de personagem tem uma variável que armazena há quantos frames este está parado. Logo, basta verificar se o personagem está parado há mais de um frame para se certificar de que deve exibir o gráfico dele nesta pose e, caso ele esteja parado há um frame ou menos, exibir a pose dele em movimento.
Exemplo em Script
if ($gamePlayer._stopCount > 1) {
  //Jogador Parado
} else {
  //Jogador Movendo
}
[close]
Exemplo por eventos + Script Call
[close]

Muito obrigado pela ajuda, de verdade!!

Ajudou muito!
This is a JoJo's Reference?!

Citação de: Jorge_Maker online 22/05/2020 às 15:19
Eliaquim:
  o/
Brandt:
  De fato, não entendo nada de javascript e caí na maracutaia da facilidade de acessar a variável privada. xd Valeu pelo toque, Masked. o/


  Voltando o assunto do tópico, embora seja um evento que ocorrerá por apenas 0.016s, não se trata de algo imperceptível (contanto que não haja queda de frames), improvável ou impossível de ser previsto: Por via de regra, ao final de cada passo dado pelo personagem (vamos considerar que 1 passo == 1 tile), este irá parar, mesmo que haja progressão no movimento, por um mísero frame, o personagem será determinado como estando em repouso. Apesar disso ser essencial para que o sistema de movimentação tile-based funcione corretamente, um sistema de poses terá de usar uma lógica um pouco diferente tendo em vista esse pequeno delay.

  Felizmente², já há uma função embutida que serve para comparar o valor acumulado pela variável _stopCount, citada por mim anteriormente, sem a necessidade de ter que acessa-la diretamente.

  Use isso em uma condição na chamada de script:
$gamePlayer.checkStop(1)


  E boa sorte. :XD:

Olá eu só gostaria de um ajuda em relação a como fazer o código funcionar, eu fiz por meio das condições no evento que nem eu vi nas imagens, mas quando eu coloco pra funcionar, o gráfico realmente muda, mas quando ando o gráfico fica o mesmo e não volta pro original, se puder me ajudar, agradeceria muito.

Abraço!!

Mathy
This is a JoJo's Reference?!

Mathy1x: Por favor, evite postar sequencialmente do modo que você fez. Você poderia ter respondido a todos os posts em um único. :XD:


Quanto ao seu problema, se resolve adicionando uma exceção, eu mostrei isso logo acima:
Oxe

Opa, peço desculpas, sou novo no site e não tinha visto direito sobre responder, obrigado pelo aviso.  :ded:

E sobre a resposta, eu irei mandar foto de como eu fiz, meio que fiz isso, mas,bom, posso ter feito algo de errado, irei tentar e mandar uma foto nessa resposta de como fiz.

Obrigado. :XD:

KKKKKKKKK eu iria postar uma imagem mas n sei usar o recurso de imagem do site, sad;-;

This is a JoJo's Reference?!

Citação de: Jorge_Maker online 24/05/2020 às 14:11
Mathy1x: Por favor, evite postar sequencialmente do modo que você fez. Você poderia ter respondido a todos os posts em um único. :XD:


Quanto ao seu problema, se resolve adicionando uma exceção, eu mostrei isso logo acima:


Só por curiosidade.... esse evento da forma como está posto, também poderia ser usado para o VX Ace? ^^
Achei interessante isso... e envolvia uma gambiarra meio estranha de personagem X ou Y, com apenas esse código, me soa muito mais prático!

Citação de: aleth728 online 24/05/2020 às 20:37
Só por curiosidade.... esse evento da forma como está posto, também poderia ser usado para o VX Ace? ^^
Achei interessante isso... e envolvia uma gambiarra meio estranha de personagem X ou Y, com apenas esse código, me soa muito mais prático!
Não.

Pro VXAce você pode usar o $game_player.stopping?, mas para ele existe o mesmo problema já citado acima. O mesmo problema também se repete quanto a variável privada stop_count.

Citação de: Brandt online 22/05/2020 às 14:22
[...]
O ideal era o RM ter uma função decente pra isso, mas sabemos que nem sempre dá pra ter tudo na vida xd
Deal with it!