🤔 Para Refletir :
"Está faltando "animação" no projeto? Use um "estimulante"!"
- Core32

Ação ao tocar em uma Sprite (MV)

fabrizio

Plebeu
Membro
Membro
Juntou-se
28 de Março de 2017
Postagens
45
Bravecoins
2
Eu já consigo mostrar uma Sprite na tela do jogo, mas gostaria de colocar uma ação ao clicar nela. Como posso fazer isso?

Já tentei mapear com TouchInput.x e TouchInput.y mas isso não funciona da forma que eu quero. O personagem acab se movendo pra área onde cliquei.

EDIT.:

Imagine um botão de ação. Ele é mostrado na tela e ao clicar nele eu ativo um Evento Comum ou uma função JS. O conteúdo eu saberei colocar, o que busco é a condição e o NÃO movimento do personagem ao clicar/tocar.
 
Como primeira função da ação, bloqueie o movimento do personagem, assim ele não deverá caminhar até lá.
 
King Gerar comentou:
Como primeira função da ação, bloqueie o movimento do personagem, assim ele não deverá caminhar até lá.

Sim, mas como faço isso? Não conheço muitos comandos.
 
Se for uma programação por eventos, tu tem a possibilidade de ordenar uma rota de movimento com o único comando sendo “Esperar 1 frame”, que o personagem repetirá esse movimento. Todavia, ao terminar a ação, tu deverá ordená-lo à mesma rota, porém, sem repetição.

Se for por código, vai depender do que deseja fazer e onde o deseja executá-lo, por fins de desempenho e viabilidade.
 
Amigo, não querendo ser Rude mas não está ajudando em nada. Obrigado por tentar, mas irei aguardar algum programador, pois o Sprite é feito via script, então procuro algo para complementar isso.

Abraço
 
[member=1347]fabrizio[/member]  Eae, olha, você está perguntando isso: "gostaria de colocar uma ação ao clicar nela. Como posso fazer isso?" então se quer que um comando aconteça ao clicar em determinada coordenadas, é simples, basta que no seu script você faça uma condição para que :

QUANDO o mouse estiver na coord x e y especificadas por você  &&/AND ([e , pois tem que atender as duas condições dentro de um if]) CLICAR COM O BOTÃO (que você quer) do mouse
ENTÃO: ACONTECE TAL AÇÃO.

Pelo que você disse, o seu personagem($player)/ou o evento está movimentando quando você clica e isso não era para acontecer? Isso significa que você configurou em algum lugar nesse seu script a ação PARA ELE MOVIEMNTAR quando você clica, você terá que localizar isso e ajustar também.


Entenda uma coisa tambem, tipo conceitos como Sprite e qualquer outro objeto na linguagem de programação são conceitos mentais/abstratos humanos, na realidade para o computador é tudo a mesma coisa, um monte de pixels e dados, você não clica em sprite alguma, você clica em coordenadas.


 
Olha, eu recomendo fortemente que puxe um pouco os arreios dessa carroça aí porque os bois parecem meio cansados. Você sequer se dispôs a explicar o que deseja fazer, sugiro ter uma paciência mais moderada porque quem está na situação de ajudado aqui é tu, não eu, e minha bola de cristal está meio enevoada para tentar adivinhar seu propósito. Como eu disse, conforme for esta sua "ação", tu tem maneiras diferentes de fazer e fazê-las de modo errôneo pode resultar num freeze da sua Scene_Map, e daí tu vai ter outro problema.

Se for algo instantâneo, como o mostrar de uma janela ou algo que acontece no decorrer de mínimos frames, tu pode fazer uma função dentro da Scene_Map e colocar uma condição de que, se o x e o y do clique forem dentro das coordenadas ocupadas pela imagem, tu chama essa função. O código vai lê-la, e, por ser rápida, não vai ter problema algum.

Se for algo maior, que realmente requeira paralisar o personagem, para fins mais lúdicos eu recomendo separar uma switch especificamente para proibir o movimento do personagem quando necessário. A função responsável por verificar se houve um clique o mover o personagem para o destino definido é a updateDestination, e ela é chamada a cada lida do update para fazer essa verificação. Se tu colocar algo como if ($gameSwitches.value(10)) { this.updateDestination() }; no lugar, a verificação só será chamada se a switch em questão (10, no exemplo) estiver ativa. Ou seja, é só desativar a switch que o personagem não se moverá quando clicar.

Como tu não mencionou querer pausar o movimento pelo teclado, vou entender que não há a possibilidade disso o atrapalhar.
 
Bom, lendo outros scripts que criam SPRITES, eu consegui desenhar (mostrar a imagem) e bloquear o movimento dessa forma:

BLOQUEIO:
Código:
    Bizu.onButton = function() {
        // Mapeando área de clique
        var area = {};
        area.Xa = 924;
        area.Xb = area.Xa + 100; // 100 = Largura da imagem
        area.Ya = 476;
        area.Yb = area.Ya + 100; // 100 = Altura da imagem

        var result = false;

        if( (area.Xa <= TouchInput.x && TouchInput.x <= area.Xb) && (area.Ya <= TouchInput.y && TouchInput.y <= area.Yb) ){
            console.log("Área clicada com sucesso!");
            console.log(area);
            result = true;
        };

        return result;
    };

    //-----------------------------------------------------------------------------
    //  GAME TEMP
    //-----------------------------------------------------------------------------

    var Game_Temp_setDestination = Game_Temp.prototype.setDestination;
    Game_Temp.prototype.setDestination = function(x, y) {
        if ( Bizu.onButton() ) return;
        Game_Temp_setDestination.call(this,x,y);
    };

Agora, só falta eu conseguir transformar isso em algo genérico, pois sair mapeando todo SPRITE é complicado e deixaria o código MUITO grande. Tentei

[member=1196]Riven[/member] o movimento acontece pelo simples fato do mouse está ativo. Isso vem por padrão da Engine, eu precisava de algo que ignorasse o click.

[member=45]King Gerar[/member] a ideia da Switcher, eu teria que procurar essa updateDestination pra colocar essa condição nela? Acho que posso aplicar essa mesma lógica em Game_Temp.prototype.setDestination, como no script citado acima.



Edit.: (também coloquei no meu tópico principal agora)

Imagine um botão de ação. Ele é mostrado na tela e ao clicar nele eu ativo um Evento Comum ou uma função JS. O conteúdo eu saberei colocar, o que busco é a condição e o NÃO movimento do personagem ao clicar/tocar.
 
[member=1347]fabrizio[/member] Saquei o que você quis dizer, então, eu uso o XP e nunca usei o MV, mas talvez isso funcione, tipo condição segue a mesma lógica que te falei, e você disse estar funcionando certo?:
Código:
 if( (area.Xa <= TouchInput.x && TouchInput.x <= area.Xb) && (area.Ya <= TouchInput.y && TouchInput.y <= area.Yb) ){
            console.log("Área clicada com sucesso!");
            console.log(area);
            result = true;
        };

Então, assim: caso essa condição aconteça/seja executada/haja o "click" antes do " console.log("Área clicada com sucesso!");", tenta LIMPAR o DESTINATION do movimento, tipo isso $gameTemp.clearDestination();

Olha, essas configurações não tem no xp (que é o que eu uso, ele nem tem script padrão para isso) então tive que olhar o código do MV mesmo na net, dá uma olhada aí se esse comando funciona, se não ter tenta com um outro comando PARECIDO.

Agora isso seria para quando clicar, agora se o personagem se movimenta só de mexer o mouse, você tem que fazer uma outra condição que é PARECIDA COM ISSO, é simples, você vai fazer o seguinte, você vai INTERROMPER o destionation ou movimento (não sei como é no MV)  ASSIM QUE O MÉTODO/SCRIPT estiver sendo ativado, E QUANDO ISSO VAI ACONTECER? Assim que o cursor entrar na tela, vê se tem alguma coisa que verifica cursor ativo.
 
[member=1196]Riven[/member]

O comando $gameTemp.clearDestination(); até que funciona, mas ele tem um pequeno delay. O personagem ainda chega a mover um quadro. Irei pesquisar mais sobre como usar essa função.
 
[member=1347]fabrizio[/member] O que está fazendo ele mover um quadro, provavelmente, é essa função que você disse que é padrão no MV que deixa o  mouse ficar ativo por padrão, esse método que faz isso deve estar acontecendo ANTES dessa condição ser executada, o que da tempo para ele andar um quadro com o movimento do mouse. Acho que se tiver como DESATIVAR esse padrão do mouse e ATIVAR SOMENTE QUANDO você QUER, ai você CRIARIA UMA VARIÁVEI para SETAR =  ativar o mouse DEPOIS DE VERIFICADAS AS CONDIÇÕES DE COORDENADAS DE BOTÕES, NPCS E TAL..  PARA CADA CLASSE (ONDE OCORRE MOVIMENTO DO PLAYER), mas provavelmente isso pode ser muito trabalhoso se seu projeto tiver muitas classes, MAS viável caso seja um game com poucas classes.

Se você descobrir alguma outra forma, posta aí, valeu.

Edit: Você também pode fazer DENTRO DA CONDIÇÃO
Código:
if( (area.Xa <= TouchInput.x && TouchInput.x <= area.Xb) && (area.Ya <= TouchInput.y && TouchInput.y <= area.Yb) ){
            console.log("Área clicada com sucesso!");
            console.log(area);
            result = true;
        };

E antes do $gameTemp.clearDestination();

Coloca para o player se MOVIMENTAR para a MESMA POSIÇÃO (this.position [não sei como é no mv])em que ele está, ou um loop para espear uns frames.
 
fabrizio comentou:
[...][member=45]King Gerar[/member] a ideia da Switcher, eu teria que procurar essa updateDestination pra colocar essa condição nela? Acho que posso aplicar essa mesma lógica em Game_Temp.prototype.setDestination, como no script citado acima.
[...]
Sim, tu vai dar um Ctrl + F procurando ela no rpg_scenes, ela vai estar no Scene_Map.protoype.update, na primeira linha. Tu vai apagar ela e colocar ela no else da condição que verifica se o clique foi em cima da imagem.

Talvez esse plugin possa lhe servir de algo.
 
Sim, tu vai dar um Ctrl + F procurando ela no rpg_scenes, ela vai estar no Scene_Map.protoype.update, na primeira linha. Tu vai apagar ela e colocar ela no else da condição que verifica se o clique foi em cima da imagem.

[member=45]King Gerar[/member]
Blz, fiz quase tudo certo, só não sei como chamar o updateDestination no meu Script. Tentei alguns comandos e nenhum deu certo chamar ele no ELSE criado por mim.

------
Edit.:
Eu tive que colocar um Scene_Map.prototype.update no meu script pra poder chamar o "this.updateDestination". Dai coloquei ele dentro de uma condição. Agora vou ver se consigo abstrair pra não ficar tantas linhas.
 
Seguinte, eu faria dessa maneira:

Primeiro colocaria a imagem para ser carregada no Boot, assim não correria o risco de, quando eu precisar dela, ela ter de ser carregada ainda e muito provavelmente não aparecer da primeira vez que eu a chame. Para isso, precisaria de um alias no create da Scene_Boot. Eu recomendaria criar uma função à parte para carregar as imagens customizadas, mas como é uma só, acho que não faz mal por no create mesmo, como está abaixo.

Código:
var Alt_Scene_Boot_create = Scene_Boot.prototype.create;
Scene_Boot.prototype.create = function() {
  Alt_Scene_Boot_create.call(this);
  ImageManager.loadPicture("Imagem");
};

Então eu iria aproveitar a função da Scene_Map que cria os objetos de tela, como a janela de nome do mapa e a janela de mensagem, para mandar ela desenhar a imagem também. Aí entra outro alias.

Código:
var Alt_Scene_Map_createDisplayObjects = Scene_Map.prototype.createDisplayObjects;
Scene_Map.prototype.createDisplayObjects = function() {
  Alt_Scene_Map_createDisplayObjects.call(this);
  this.image = new Sprite(ImageManager.loadPicture("Imagem"));
  this.addChild(this.image);
};

Agora, criaria uma função que, recebe a coordenada x do clique, a y, a imagem, a largura da imagem e a altura dela também, para verificar e retornar se o clique fora executado sobre a imagem ou não.

Código:
Scene_Map.prototype.clickOverImageVerify = function(clickX, clickY, picture, imageWidth, imageHeight) {
  var pictureWidth = picture.x + imageWidth;
  var pictureHeight = picture.y + imageHeight;
  if (clickX >= picture.x && clickX <= pictureWidth && clickY >= picture.y && clickY <= pictureHeight) {
    return true;
  } else {
    return false;
  };
};

Feita a função, editaria o update da Scene_Map para tirar a possibilidade de, ao clicar, verificar se o clique foi sobre a imagem. Se não, o código executaria o que faria normalmente. Para essa verificação, antes verificaria se houve um clique, e em sequência, se o clique foi sobre a imagem, usando a função que criei antes.
OBS.: Os valores 100 e 120 são, respectivamente, a altura e a largura fictícios da imagem fictícia.

Código:
Scene_Map.prototype.update = function() {
  if (TouchInput.isTriggered()) {
    if (this.clickOverImageVerify(TouchInput.x, TouchInput.y, this.image, 100, 120)) {
      console.log("Colocar o que fazer aqui");
    } else {
      this.updateDestination();
    };
  };
  this.updateMainMultiply();
  if (this.isSceneChangeOk()) {
    this.updateScene();
  } else if (SceneManager.isNextScene(Scene_Battle)) {
    this.updateEncounterEffect();
  }
  this.updateWaitCount();
  Scene_Base.prototype.update.call(this);
};

Não testei aqui, mas creio que funcionaria. Talvez possa ter algo errado na sintaxe, então é bom dar uma conferida.
 
[member=45]King Gerar[/member] cara, funcionou e não funcionou kkkk Ele mostra a imagem e o log aparece corretamente ao clica na área da imagem, o unico problema foi: Apareceu o Sprite completo de personagem.

Olha a imagem do jogo:
Nh6dT5O.jpg

Além disso, não consigo mover pra canto algum.

Edit.:
A minha imagem de exemplo foi essa "bola" aí que aparece. E eu adicionei umas linhas pra escolher a posição da imagem. Mesmo retirando isso, o bug continua.



Edit. 2:
Deu tudo certo. Achei um problema mas consegui resolver. De tudo que você me passou só tive que atualizar o Scene_Map.prototype.update. Segue o codigo:

Código:
    var Alt_Scene_Map_update = Scene_Map.prototype.update;
    Scene_Map.prototype.update = function() {
        Alt_Scene_Map_update.call(this);
        if (TouchInput.isTriggered() && this.clickOverImageVerify(TouchInput.x, TouchInput.y, this.image, this.image.width, this.image.height)) {
            console.log("Colocar o que fazer aqui");
        } else {
            this.updateDestination();
        };        
    };

Coloquei o TouchInput.isTriggered() junto da condição do clique porque estava dando um bug e a largura e altura da imagem coloquei pra pegar esse valor sozinho sem eu precisar setar ele. Funcionando perfeitamente agora! Muito obrigado!
 
Voltar
Topo Inferior