Ir para conteúdo

[TUTORIAL] Como fazer uma entidade olhar para um bloco (tipo uma bússola)


abidux

Posts Recomendados

Esse tópico vai ser dividido em 2 áreas, "básica" e "matemática", para quem quiser entender melhor

 

BÁSICA

 

primeiramente, temos que escrever umas variáveis.

public static final int NORTE = 180, SUL = 0, LESTE = 270, OESTE = 90, NORDESTE = 225, NOROESTE = 135, SUDESTE = -45, SUDOESTE = 45;

esses são alguns ângulos importantes para isso.
primeiro, precisamos determinar a distâncias pelas direções.

  private static int[] getDirections(Location l) {
        final int[] location = new int[] {l.getBlockX(), l.getBlockZ()};
        final int[] target = new int[] {track[0], track[1]};
        
        int east = 0, west = 0, south = 0, north = 0;
        
        if (location[0] > target[0]) {
            west += location[0] - target[0];
        } else if (location[0] != target[0]) {
            east += target[0] - location[0];
        }
        
        if (location[1] > target[1]) {
            north += location[1] - target[1];
        } else if (location[1] != target[1]) {
            south += target[1] - location[1];
        }
        
        return new int[] {north, south, east, west};
    }

isso vai retornar os blocos que temos que andar para cada direção, mas ainda não é preciso o suficiente, agora vamos pegar o ângulo certo.

	private static double distance(int[] a, int[] b) {
		int m1 = a[0] - b[0];
		int m2 = a[1] - b[1];
		return Math.sqrt(m1*m1 + m2*m2);
	}
	
	public static void lookAtTarget(Entity entity) {
		if (track != null) {
			final int[] d = getDirections(entity.getLocation());
			double angle = 0;
			if (d[0] > 0) {
				angle = NORTE;
				if (d[2] > 0) {
					angle = NORDESTE;
					int[] u = {d[2], d[0]};
					int[] v = {0, d[0]};
					angle = (180 - angle(u, v)) * -1;
				} else if (d[3] > 0) {
					angle = NOROESTE;
					int[] u = {d[3], d[0]};
					int[] v = {0, d[0]};
					angle = 180 - angle(u, v);
				}
			} else if (d[1] > 0) {
				angle = SUL;
				if (d[2] > 0) {
					angle = SUDESTE;
					int[] u = {d[2], d[1]};
					int[] v = {0, d[1]};
					angle = angle(u, v) * -1;
				} else if (d[3] > 0) {
					angle = SUDOESTE;
					int[] u = {d[3], d[1]};
					int[] v = {0, d[1]};
					angle = angle(u, v);
				}
			} else if (d[2] > 0) {
				angle = LESTE;
			} else if (d[3] > 0) {
				angle = OESTE;
			}
			
			Location location = entity.getLocation();
			location.setYaw((float) angle);
			entity.teleport(location);
		}
	}
	
	private static double angle(int[] u, int[] v) {
		int[] base = {0, 0};
		double cosO = (u[0] * v[0] + u[1] * v[1]) / (distance(u, base) * distance(v, base));
		return Math.toDegrees(Math.acos(cosO));
	}

esses métodos entram na matemática, então não vou explicar muito, mas para usar é só executar lookAtTarget(entity);
track é uma variável int[] com as coordenadas X e Z do bloco que você quer mirar.

Como criar a track:

int[] track = {x, z};
track = new int[] {x, z};

 

MATEMÁTICA

a distância é basicamente um plano cartesiano, então a fórmula é:
(a1 - b1)^2 + (a2 - b2)^2

a distância é usada com base em 2 pontos, que são calculados a partir da matemática com vetores...
o primeiro ponto é baseado em uma array com as seguintes condições
int[] u = {east||west, north||south};
int[] v = {0, north||south};

o ângulo é calculado por a1*b1 + a2*b2 sobre o módulo de a vezes o módulo de b




desculpa se o tópico não ficou bom ou didático, comente se tiver alguma dica para melhorar.

Link para o comentário
Compartilhar em outros sites

Participe da Conversa

Você pode postar agora e se cadastrar mais tarde. Se você tiver uma conta, a class='ipsType_brandedLink' href='https://gamersboard.com.br/login/' data-ipsDialog data-ipsDialog-size='medium' data-ipsDialog-title='Sign In Now'>acesse agora para postar com sua conta.
Observação: sua postagem exigirá aprovação do moderador antes de ficar visível.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.

Processando...
×
×
  • Criar Novo...