Me expliquem como fazer um sistema?

10 Respostas   347 Visualizações

0 Membros e 1 Visitante estão vendo este tópico.

Nunnu

  • *
  • Posts: 39
  • Ouros: 2
  • cala boca
Tópico criado em: 27/09/2016 às 13:14 - Última modificação por Alisson em 28/09/2016 às 21:36

Olá, eu queria saber como eu faço um sistema onde os personagens andam em uma formação diferente daquela de um atrás do outro (Catterpillar eu acho...).

Tipo, os 4 andando um do lado do outro, ao invés de um atrás do outro. Não importa muito a formação, e sim a ideia de fazer uma formação nova em que os personagens andam nela.
Feito por:   King Gerar          ManecBR3
                   
                   (um gato)            (outro gato)

TonyHart

  • *
  • Posts: 144
  • Ouros: 126
  • Born in 95 to die
Resposta 1: 27/09/2016 às 17:07

Alguma razão especial para fazer isso? É possível fazer apenas com auxílio de script, mas considerando por cima, pode ser que cause um pouco de lag ao jogo, tendo em mente que é necessário sempre calcular se é possível ou não o membro da party poder estar naquela formação (por exemplo: em um caminho estreito de um tile).

Se você explicar melhor seu objetivo, e talvez diminuir um pouco os requisitos, talvez alguém da comunidade te ajude com o sistema
Born in 95 to die

Nunnu

  • *
  • Posts: 39
  • Ouros: 2
  • cala boca
Resposta 2: 27/09/2016 às 18:50 - Última modificação por Nunnu em 27/09/2016 às 18:52

@tonyhart
Eu preciso disso, é pra um jogo que estou fazendo. Eu estou colocando em mente tudo isso dos tiles estreitos, mas mesmo assim eu quero.

Estou estudando Ruby para dar conta dos sistemas que eu precisar, mas ainda sou muito leigo e como esse é um sistema que eu vou usar e adaptar de várias formas, acho interessante alguém me explicar como fazer, ou então apontar um caminho, uma dica.
Feito por:   King Gerar          ManecBR3
                   
                   (um gato)            (outro gato)

Syureri

Resposta 3: 27/09/2016 às 19:19

Os followers são como uma cópia do primeiro membro, eles seguem a mesma rota dele, andam por onde ele andou, então mudar o tipo de "formação" seria algo que levaria muito tempo, principalmente para reajustar ao andar em áreas de 1 tile.
É possível sim, mas exigiria tempo, e mais importante, paciência por parte do programador. Muita paciência e café.
Não se esqueça do café.

Nunnu

  • *
  • Posts: 39
  • Ouros: 2
  • cala boca
Resposta 4: 27/09/2016 às 21:43

@Alisson

Hheusaheusa, olha, com isso pelo menos descobri que não sou tão leigo assim. Pensei nisso como algo muito difícil de fazer, por conta dessas coisas que tu disse, e descubro que realmente era difícil.

Elevou meu autoestima, pretendo fazer isso de qualquer forma, mas me sinto confortável em deixar isso para depois.

Paciência consigo lidar, agora café já não gosto tanto xD
Feito por:   King Gerar          ManecBR3
                   
                   (um gato)            (outro gato)

TonyHart

  • *
  • Posts: 144
  • Ouros: 126
  • Born in 95 to die
Resposta 5: 28/09/2016 às 06:31

Seria alguma coisa parecida com isso? Como falei anteriormente, em lugares abertos uma funcionalidade dessas funciona bem, o problema é em lugares estreitos mesmo...

Born in 95 to die

Nunnu

  • *
  • Posts: 39
  • Ouros: 2
  • cala boca
Resposta 6: 28/09/2016 às 12:56

@tonyhart

Isso mesmo, foi você que fez? Ficou muito bom! Se puder disponibilizar os scripts pra mim ver o que você fez ficaria grato.

Só um detalhe, eu planejo usar em RPG Maker VX Ace
Feito por:   King Gerar          ManecBR3
                   
                   (um gato)            (outro gato)

TonyHart

  • *
  • Posts: 144
  • Ouros: 126
  • Born in 95 to die
Resposta 7: 28/09/2016 às 18:48 - Última modificação por tonyhart em 28/09/2016 às 19:34

Então, eu fiz o script de duas formas:

Na primeira forma estou usando e sobrescrevendo apenas funções da própria Engine. O unico problema é que as vezes os followers acabam se perdendo do player por que não conseguem encontrar o caminho (por bloqueio ou algo do tipo)...

Na segunda forma estou utilizando um codigo meu de path find, baseado em um algoritmo de busca chamado A* (bgrins.github.io/javascript-astar/demo/). Dessa forma os followers nunca se perdem do jogador, MAS é complicado de mexer e adaptar para a engine, e portar meu codigo (Rpg Maker MV) para o VX/ACE.

Tente utilizar a primeira forma, e caso essa questão de o follower se perder se torne um problema, eu posso te passar meu código customizado, mas aí já não teria muito como te dar suporte pra adaptar, já que não programo em Ruby.

Vídeo comparando o problema do follower se perder:


Código da Versão Simples no RPG Maker MV (Você precisa mapear as regiões em que os followers poderão andar na variável Formation.regionID);

Código: [Selecionar]
//=============================================================================
// Spring_Simple_Formation.js
//=============================================================================

/*:
 * @plugindesc Spring's Simple Formation Code.
 * @author Tony Hart
 *
 * @help This plugin does not provide plugin commands.
 */

(function() {
    "use strict";

    //---------------------------------------------------------------------------
    // Formation
    //
    // Classe de controle a rotina dos personagens do jogo

    function Formation() {
        throw new Error('This is a static class');
    }

    /*
     * Região permitida para os followers andarem
     */
    Formation.regionID = 1;

    /*
     * Posicao x,y e direção inicial do player
     */
    Formation.playerDir = 2;
    Formation.playerX = 0;
    Formation.playerY = 0;

    /*
     *  Posições que serão pesquisadas para os followers em relação
     *  ao Player (P)
     *
     *  | | | |D| | | |
     *  | | |I|9|K| | |
     *  | |H|5|3|6|J| |
     *  |G|C|1|P|2|B|F|
     *  | |L|7|4|8|N| |
     *  | | |M|A|O| | |
     *  | | | |E| | | |
     *
     */
    var _Game_Followers_initialize = Game_Followers.prototype.initialize;
    Game_Followers.prototype.initialize = function() {
        _Game_Followers_initialize.call(this);
        this._followersPosition = [
            {x: -1, y:  0, dirBlocked: 4}, // 1
            {x:  1, y:  0, dirBlocked: 6}, // 2
            {x:  0, y: -1, dirBlocked: 8}, // 3
            {x:  0, y:  1, dirBlocked: 2}, // 4
            {x: -1, y: -1, dirBlocked: 4}, // 5
            {x:  1, y: -1, dirBlocked: 6}, // 6
            {x: -1, y:  1, dirBlocked: 4}, // 7
            {x:  1, y:  1, dirBlocked: 6}, // 8
            {x:  0, y: -2, dirBlocked: 8}, // 9
            {x:  0, y:  2, dirBlocked: 2}, // A
            {x:  2, y:  0, dirBlocked: 6}, // B
            {x: -2, y:  0, dirBlocked: 4}, // C
            {x:  0, y: -3, dirBlocked: 8}, // D
            {x:  0, y:  3, dirBlocked: 2}, // E
            {x:  3, y:  0, dirBlocked: 6}, // F
            {x: -3, y:  0, dirBlocked: 4}, // G
            {x: -2, y: -1, dirBlocked: 4}, // H
            {x: -1, y: -2, dirBlocked: 4}, // I
            {x:  2, y: -1, dirBlocked: 6}, // J
            {x:  1, y: -2, dirBlocked: 6}, // K
            {x: -2, y:  1, dirBlocked: 4}, // L
            {x: -1, y:  2, dirBlocked: 4}, // M
            {x:  2, y:  1, dirBlocked: 6}, // N
            {x:  1, y:  2, dirBlocked: 6}  // O
        ]
    };

    /*
     *  Verifica se tal posição já está ocupada por algum follower
     *  ou na frente do Player
     */
    Game_Followers.prototype.isOccupied = function(x, y, member) {
        for (var i = $gamePlayer._followers._data.length - 1; i >= 0; i--) {
            var f =  $gamePlayer._followers._data[i];
            // Ocupado se outro membro já estiver na posição x,y
            if(f.nextX == x && f.nextY == y && f._memberIndex != member) {
                return true;
            }
            // Ocupado se o player já estiver na posição x,y
            if(Formation.playerX == x && Formation.playerY == y) {
                return true;
            }
            // Ocupado se o a posição x,y estiver na frente do player
            switch(Formation.playerDir) {
                case 8 :
                    for(var pos = -1; pos >= -3; pos--) {
                        if(Formation.playerX == x && (Formation.playerY + pos) == y) {
                            return true;
                        }
                    }
                    break;
                case 6 :
                    for(var pos = 1; pos <= 3; pos++) {
                        if((Formation.playerX + pos) == x && Formation.playerY == y) {
                            return true;
                        }
                    }
                    break;
                case 2 :
                    for(var pos = 1; pos <= 3; pos++) {
                        if(Formation.playerX == x && (Formation.playerY + pos) == y) {
                            return true;
                        }
                    }
                    break;
                case 4 :
                    for(var pos = -1; pos >= -3; pos--) {
                        if((Formation.playerX + pos) == x && Formation.playerY == y) {
                            return true;
                        }
                    }
                    break;
            }
        }
        return false;
    };

    /*
     *  Retorna a posição x,y que o follower deve ficar
     */
    Game_Followers.prototype.getDirections = function(x, y, member) {
        var thisFollowers = this;
        for(var i = 0; i < this._followersPosition.length; i++) {
            var newX = this._followersPosition[i].x+x;
            var newY = this._followersPosition[i].y+y;
            var sameDirectionPlayer = this._followersPosition[i].dirBlocked == Formation.playerDir;
            // Retorna posicao x,y se a região for igual a 1, não está ocupada por outro follower e não está na mesma direcao que o player
            if($gameMap.regionId(newX, newY) == Formation.regionID && !thisFollowers.isOccupied(newX, newY, member) && !sameDirectionPlayer) {
                return {x: newX, y: newY};
            }
        }
        return {x: x, y: y};
    };

    /*
     *  Salva a posicaoe direção do player
     */
    var _Game_Player_moveStraight = Game_Player.prototype.moveStraight;
    Game_Player.prototype.moveStraight = function(d) {
        _Game_Player_moveStraight.call(this, d);
        if (this.canPass(this.x, this.y, d)) {
            Formation.playerX = $gameMap.roundXWithDirection(this.x, d);
            Formation.playerY = $gameMap.roundYWithDirection(this.y, d);
            Formation.playerDir = d;
        }
    };

    /*
     *  Sobrescreve comportamento padrão (Catterpillar)
     */
    Game_Followers.prototype.updateMove = function() {};

    /*
     *  Sobrescreve comportamento padrão moveTowardCharacter para follower se mover
     *  em direçao proxima ao player
     */
    Game_Follower.prototype.moveTowardCharacter = function(character, i) {
        var position = character._followers.getDirections(character.x, character.y, this._memberIndex);
        this.nextX = position.x;
        this.nextY = position.y;
        var sx = this.deltaXFrom(position.x);
        var sy = this.deltaYFrom(position.y);
        if (Math.abs(sx) > Math.abs(sy)) {
            this.moveStraight(sx > 0 ? 4 : 6);
            if (!this.isMovementSucceeded() && sy !== 0) {
                this.moveStraight(sy > 0 ? 8 : 2);
            }
        } else if (sy !== 0) {
            this.moveStraight(sy > 0 ? 8 : 2);
            if (!this.isMovementSucceeded() && sx !== 0) {
                this.moveStraight(sx > 0 ? 4 : 6);
            }
        }
    };

    /*
     *  Mover em direção ao proxima ao player
     */
    var _Game_Follower_update = Game_Follower.prototype.update;
    Game_Follower.prototype.update = function() {
        _Game_Follower_update.call(this);
        if(this.isStopping()) {
            this._through = false;
            this.moveTowardCharacter($gamePlayer, this._memberIndex);
            // Set direção ao finalizar movimento
            if(this._x == this._realX && this._y == this._realY) {
                this.setDirection(Formation.playerDir);
            }
        }
    };

})();

Qualquer dúvida só falar.
Born in 95 to die

Nunnu

  • *
  • Posts: 39
  • Ouros: 2
  • cala boca
Resposta 8: 28/09/2016 às 21:09

@tonyhart

Acho que vou usar a primeira forma mesmo, ficou muito bom por sinal. No meu caso vou colocar umas diferenças que acho que vai facilitar um pouco e até deixar menos bugado, que seria apertar teclas para as formações, e não da forma automática como você fez. Que por sinal é uma ótima ideia também.

Mas é isso, muito obrigado pelo esforço, quando eu precisar de alguma ajuda eu edito aqui.

Valeu.
Feito por:   King Gerar          ManecBR3
                   
                   (um gato)            (outro gato)

TonyHart

  • *
  • Posts: 144
  • Ouros: 126
  • Born in 95 to die
Resposta 9: 28/09/2016 às 21:30

Sem problemas. Feliz em ajudar
Born in 95 to die

Syureri

Resposta 10: 28/09/2016 às 21:43

Assumo que esteja resolvido.
Qualquer dúvida a mais basta avisar que destrancaremos o/