/** /* @name: distancia /* @version: 1.0 /* @Descrition: Retorna a distancia deste até ponto, sem considerar diagonais. */ public int distancia(ponto2D ponto) { int distancia = 0; if (this.isEqual(ponto)) { return distancia; } if (this.x > ponto.x) { distancia += this.x - ponto.x; } else { distancia += ponto.x - this.x; } if (this.y > ponto.y) { distancia += this.y - ponto.y; } else { distancia += ponto.y - this.y; } return distancia; }
public void levantar(ponto2D ponto, Vector3 position, Vector3 levantarStartPosition) { this.wargrid = ponto; this.newPosition = position; this.estado = tileStates.subir; this.gameObject.transform.position = levantarStartPosition; }
/** /* @name: findPathTo /* @version: 1.0 /* @Descrition: encontra um caminho do ponto de inicio até o ponto final e retorna uma pilha contendo os passos. */ public Path findPathTo(ponto2D pontoInicio, ponto2D pontoFim) { /** ve se o no atual é o fim, se sim, empilha e retorna pilha de movimentos. caso contrário atualiza os nós proximos. Se o no proximo já existe, tenta atualizar Caso o euristic value for menor, sobrescreve. caso contrário, cria no e bota os valores. adiciona cada proximo a lista de abertos se puder. pega o proximo no, repete. */ AEstrelaNode inicio = new AEstrelaNode(null, pontoInicio, pontoInicio); AEstrelaNode posicaoAtual = inicio; while (!posicaoAtual.gridPosition.isEqual(pontoFim)) { vistaNode(posicaoAtual, pontoInicio, pontoFim); posicaoAtual = this.proximo(pontoFim); } Path saida = new Path(posicaoAtual.passosAteInicio); while (posicaoAtual != inicio) { saida.empilha(posicaoAtual.gridPosition); posicaoAtual = posicaoAtual.parent; } return saida; }
/** /* @name: isValid /* @version: 1.0 /* @Descrition: True caso o ponto esteja contido dentro do range de valores possiveis do wargrid. */ private bool isValid(ponto2D ponto) { return ponto.x >= 0 && ponto.x < this.mapSizeX && ponto.y >= 0 && ponto.y < this.mapSizeY; }
/** /* @name: isTileAtivado /* @version: 1.0 /* @Descrition: true caso um cubo já esteja subindo neste ponto. */ private bool isTileAtivado(ponto2D ponto) { if (warGrid[ponto.x][ponto.y] == null) { return false; } return warGrid[ponto.x][ponto.y].tileEstaAcima(); }
/** /* @name: generateActionArea /* @version: 1.0 /* @Descrition: Levanta Tiles no mapa de jogo para marcar a area de ação do jogador. */ private void generateActionArea(ponto2D centro, int walk, int maxRange, int minRange) { /** 1- começa no centro. 2- recursivamente chama os quadados do lados 3- cada quadrado válido levanta e chama os proximos dos lados */ recursiveActionArea( centro, new ponto2D(centro.x-1, centro.y), walk, maxRange + walk, minRange); recursiveActionArea( centro, new ponto2D(centro.x+1, centro.y), walk, maxRange + walk, minRange); recursiveActionArea( centro, new ponto2D(centro.x, centro.y+1), walk, maxRange + walk, minRange); recursiveActionArea( centro, new ponto2D(centro.x, centro.y-1), walk, maxRange + walk, minRange); }
/** /* @name: proximo /* @version: 2.0 /* @Descrition: recebe um ponto final para ser usado como desempate. retorna o proximo ponto a ser usado algoritmo de pathfinding. */ private AEstrelaNode proximo(ponto2D final) { AEstrelaNode saida = null; foreach (AEstrelaNode cadaNoAberto in this.abertos) // Loop through List with foreach. { if (saida == null) { saida = cadaNoAberto; } else { if (saida.euristicValue > cadaNoAberto.euristicValue) { saida = cadaNoAberto; } else if (saida.euristicValue == cadaNoAberto.euristicValue) { if (saida.gridPosition.distancia(final) > cadaNoAberto.gridPosition.distancia(final)) { saida = cadaNoAberto; } } } } this.abertos.Remove(saida); return saida; }
private Vector3 startPosition; // posição inicial do movimento do tile #endregion Fields #region Methods public void abaixar(ponto2D ponto, Vector3 position) { this.newPosition = position; this.estado = tileStates.descer; }
/** /* @name: wargridCoordDOWN /* @version: 2.0 /* @Descrition: calcula a posição espacial de um objeto dado sua posição no Wargrid, mas com altura abaixo do mapa, usado somente para abaixar o tile. */ private Vector3 wargridCoordDOWN(ponto2D wargridPoint) { return new Vector3(((this.tileSeparation * wargridPoint.x) + (groundOverlayTile.transform.localScale.x) * wargridPoint.x), -(groundOverlayTile.transform.localScale.y), -((this.tileSeparation * wargridPoint.y) + (groundOverlayTile.transform.localScale.z * (3 / 2)) * wargridPoint.y) ); }
/** /* @name: recursiveDeareaCall /* @version: 1.0 /* @Descrition: Chama as novas posições para recursiveDeactionArea dependendo da posição atual. */ private void recursiveDeareaCall(ponto2D centro, ponto2D position, int walk, int areaMaxRange, int areaMinRange) { if (position.x == centro.x) { if (position.y < centro.y) { recursiveDeactionArea(centro, new ponto2D(position.x, position.y - 1), (walk - 1), areaMaxRange, areaMinRange); } else { recursiveDeactionArea(centro, new ponto2D(position.x, position.y + 1), (walk - 1), areaMaxRange, areaMinRange); } } else if (position.x > centro.x) { if (position.y < centro.y) { recursiveDeactionArea(centro, new ponto2D(position.x, position.y - 1), (walk - 1), areaMaxRange, areaMinRange); recursiveDeactionArea(centro, new ponto2D(position.x + 1, position.y), (walk - 1), areaMaxRange, areaMinRange); } else if (position.y > centro.y) { recursiveDeactionArea(centro, new ponto2D(position.x, position.y + 1), (walk - 1), areaMaxRange, areaMinRange); recursiveDeactionArea(centro, new ponto2D(position.x + 1, position.y), (walk - 1), areaMaxRange, areaMinRange); } else { recursiveDeactionArea(centro, new ponto2D(position.x + 1, position.y), (walk - 1), areaMaxRange, areaMinRange); recursiveDeactionArea(centro, new ponto2D(position.x, position.y + 1), (walk - 1), areaMaxRange, areaMinRange); recursiveDeactionArea(centro, new ponto2D(position.x, position.y - 1), (walk - 1), areaMaxRange, areaMinRange); } } else { if (position.y < centro.y) { recursiveDeactionArea(centro, new ponto2D(position.x, position.y - 1), (walk - 1), areaMaxRange, areaMinRange); recursiveDeactionArea(centro, new ponto2D(position.x - 1, position.y), (walk - 1), areaMaxRange, areaMinRange); } else if (position.y > centro.y) { recursiveDeactionArea(centro, new ponto2D(position.x, position.y + 1), (walk - 1), areaMaxRange, areaMinRange); recursiveDeactionArea(centro, new ponto2D(position.x - 1, position.y), (walk - 1), areaMaxRange, areaMinRange); } else { recursiveDeactionArea(centro, new ponto2D(position.x - 1, position.y), (walk - 1), areaMaxRange, areaMinRange); recursiveDeactionArea(centro, new ponto2D(position.x, position.y + 1), (walk - 1), areaMaxRange, areaMinRange); recursiveDeactionArea(centro, new ponto2D(position.x, position.y - 1), (walk - 1), areaMaxRange, areaMinRange); } } }
public void setEuristicValue(ponto2D inicio, ponto2D fim, int multiplicador, int peso) { this.euristicValue = (inicio.distancia(this.gridPosition) * multiplicador) + (fim.distancia(this.gridPosition) * multiplicador) + peso; }
public int passosAteInicio; // Numero de passos até o inicio. usado para desempate em A*. #endregion Fields #region Constructors public AEstrelaNode(AEstrelaNode parente, ponto2D posicao, ponto2D inicio) { this.parent = parente; this.gridPosition = posicao; this.euristicValue = 0; this.passosAteInicio = contaPassosAteInicio(inicio, this, 0); }
/** /* @name: vistaNode /* @version: 0.1 /* @Descrition: recebe um no, atualiza seus vizinhos. retorna true se o ponto atual é o fim. falso caso contrário. */ private bool vistaNode(AEstrelaNode posicaoAtual, ponto2D inicio, ponto2D fim) { /** se posição atual == fim, return true testa se um vizinho já existe (tiles obstáculos são ignorados pelo algoritmo). (quatro lados) Se já existe, testa a quantidade de passos que este vizinho tem até chegar no inicio. Caso contrário cria um AEstrelaNode, calcula valor euristico e adiciona a lista de abertos. ao final, fecha o Node */ if (posicaoAtual.gridPosition.isEqual(fim)) { return true; } return false; }
/** /* @name: isEqual /* @version: 1.0 /* @Descrition: True caso as coordenadas sejam iguais */ public bool isEqual(ponto2D ponto) { return ((this.x == ponto.x) && (this.y == ponto.y)); }
/** /* @name: levantaTile /* @version: 1.0 /* @Descrition: Levanta um tile em um ponto especifico. */ private void levantaTile(ponto2D ponto) { if (this.warGrid[ponto.x][ponto.y] == null) { this.warGrid[ponto.x][ponto.y] = this.tilePool.withdraw(); //TODO: caso withdraw não seja possivel (fila vazia) instancia um novo tile. this.warGrid[ponto.x][ponto.y].levantar(ponto, this.wargridCoord(ponto), this.wargridCoordDOWN(ponto)); } else { this.warGrid[ponto.x][ponto.y].levantar(ponto, this.wargridCoord(ponto), this.wargridCoordDOWN(ponto)); } }
/** /* @name: recursiveDeactionArea /* @version: 1.0 /* @Descrition: Abaixa recursivamente tiles em uma area a partir de um centro de minRange até areaMaxRange */ private void recursiveDeactionArea(ponto2D centro, ponto2D position, int walk, int areaMaxRange, int areaMinRange) { if (isValid(centro) && isValid(position)) { if (isTileAtivado(position)) { if (position.distancia(centro) <= areaMinRange) { recursiveDeareaCall(centro, position, walk, areaMaxRange, areaMinRange); } else { if (position.distancia(centro) <= areaMaxRange) { abaixaTile(position); recursiveDeareaCall(centro, position, walk, areaMaxRange, areaMinRange); } } } } }
private int contaPassosAteInicio(ponto2D inicio, AEstrelaNode esteNode, int passosAnteriores) { if (esteNode.gridPosition.isEqual(inicio)) { return 0; } return 1 + contaPassosAteInicio(inicio, esteNode.parent, passosAnteriores); }
/** /* @name: spawUnity /* @version: 1.0 /* @Descrition: intancia uma unidade de um jogador em uma posição especifica do mapa */ private void spawUnity(ponto2D ponto, PlayersTags novoJogador) { GenericCharacter unidade = ((GameObject)Instantiate(playerUnity, // O que instanciar. wargridCoord(ponto), // Posição de instanciamento. Quaternion.Euler(new Vector3())) // Rotação inicial. ).GetComponent<GenericCharacter>(); unidade.gridPosition = ponto; unidade.jogador = novoJogador; }
public bool empilha(ponto2D ponto) { if ((head + 1) >= pilha.Length) { return false; } head++; pilha[head] = ponto; return true; }
/** /* @name: abaixaTile /* @version: 1.0 /* @Descrition: Abaixa um tile do mapa até abaixo dele, para que seja posteriormente reincluido no armazenamento de tiles */ private void abaixaTile(ponto2D ponto) { if (this.warGrid[ponto.x][ponto.y] != null) { this.warGrid[ponto.x][ponto.y].abaixar(ponto, this.wargridCoordDOWN(ponto)); this.tilePool.deposit(this.warGrid[ponto.x][ponto.y]); this.warGrid[ponto.x][ponto.y] = null; } }
/** /* @name: tilePoolCoord /* @version: 1.0 /* @Descrition: calcula a posição espacial de um objeto dado sua posição no Tilepool, mas com altura acima da camera, usado somente para abaixar o tile */ private Vector3 tilePoolCoord(ponto2D position) { return new Vector3(((this.transform.localScale.x) * position.x), -500, -((this.transform.localScale.z) * position.y) ); }