Peço desculpas pelo título um tanto genérico. Na verdade, não tenho muita ideia de como realizar o que estou tentando fazer, o que torna ainda mais difícil pesquisar uma possível solução.
Estou tentando implementar um tipo de marcador de caminho (talvez exista um nome mais adequado para ele, mas esse é o melhor que eu poderia criar).
Na frente do jogador, haverá um marcador de caminho, que determinará como o jogador se moverá quando ele terminar de planejar seu turno. O jogador pode clicar e arrastar o marcador para a posição que escolher, mas o marcador só pode ser movido dentro de uma área de trabalho definida (o bit cinza).
Então, agora estou com dois problemas:
Primeiro de tudo, como exatamente devo definir essa área viável? Eu posso imaginar talvez dois vetores que tenham o jogador como ponto de partida para formar o ângulo viável, e talvez esses dois arcos possam vir de círculos que tenham seu centro onde o jogador está, mas eu definitivamente não sei como colocar tudo isso juntos.
Em segundo lugar, depois de definir a área em que o marcador pode ser colocado, como posso garantir que o marcador permaneça apenas nessa área? Por exemplo, se o jogador clicar e arrastar o marcador, ele poderá se mover livremente dentro da área de trabalho, mas não deve deixar os limites da área. Por exemplo, se o jogador começar a arrastar o marcador para cima, ele se moverá para cima até atingir o final da área de trabalho (primeiro diagrama abaixo), mas se depois disso o jogador começar a arrastar para o lado, o marcador deverá seguir o arrasto enquanto ainda estiver dentro da área (segundo diagrama abaixo).
Espero que isso não tenha sido muito confuso. Obrigado rapazes.
Edit: Caso isso faça alguma diferença, estou usando C ++ com o Marmalade SDK.
Respostas:
Você pode definir uma área viável como a da sua pergunta com três valores:
Esses valores serão baseados em um ponto central que pode ou não ser a posição do jogador. A forma da área viável depende de onde você coloca esse ponto.
No exemplo acima, a posição central fica a uma certa distância (digamos, 50 unidades) atrás do jogador. Isso pode ser facilmente calculado como:
Para limitar a posição do marcador a essa área viável, mova-o primeiro como faria normalmente. Em seguida, validar a distância entre o ponto central e o marcador:
Por fim, valide o ângulo do marcador para o intervalo especificado. Vou usar o pseudocódigo para este:
Veja como girar um ponto em torno de outro. Isso pode ser feito com trigonometria ou com uma matriz de transformação.
Você também pode levar em consideração o tamanho do marcador e diminuir o raio e o ângulo para compensar.
Edit: Pensando bem, pode parecer mais natural se você validar o ângulo primeiro, depois a distância, então tente as duas alternativas!
fonte
cos
e umasin
operação, então não tenho certeza. Mas para calcular esses dois vetores, você também precisa rotacioná-los, embora seja necessário fazê-lo apenas quando o vetor para frente for alterado. De qualquer forma, não deve importar muito, escolha o que você prefere implementar.Eu estava pensando em como o problema poderia ser resolvido se a forma fosse irregular e não se pudesse defini-la matematicamente. Aviso: esta é uma solução suja, não para os fracos de coração.
1. Leve sua área:
2. E converta-o em um bitmap monocromático:
e chame-o de scale_0
3. Clone o bitmap e reduza-o para 50%:
e chame-o de scale_1
4. E assim por diante, até que haja um bitmap com menos de 4 pixels de largura / altura:
escala: 2, 3, 4, 5, 6
5. Agora, temos nossa área como bitmaps monocromáticos de diferentes resoluções:
6. Pegue a última imagem (aqui "scale_6") e repita todos os seus pixels.
x = Math.pow ( 2, scale_level );
converta as coordenadas de cada pixel em coordenadas da tela: onde scale_level é o número que adicionamos após "scale_". Também podemos chamá-lo de nível de quad-tree, embora não trabalhemos realmente com um quad-tree. Faça o mesmo com y.continue
próximo passo do loopx *= 2; y*=2;
para convertê-las em coordenadas na próxima imagem (escala anterior)7. Tire uma foto anterior (aqui "scale_5"), mas não passe por todos os pixels; comece em x = saved_x e termine com x = saved_x + 2, o mesmo com y. Ou seja, já que agora você passará apenas por 4 pixels para cada nível! O resto é como na p. 6
8. Tire a primeira imagem (a maior = a de maior resolução), passe novamente por 4 pixels e, finalmente, você terá o pixel mais próximo do cursor do mouse:
9. No entanto, estou tratando "M" como um ponto aqui. Se você deseja que ele seja um círculo que se encaixa completamente, contrate (reduz) a forma por
circle.radius
pixels primeiro.Pensei em acrescentar que esse algoritmo só funcionará se você não usar imagens monocromáticas, mas em escala de cinza e tratar um pixel como "cheio" se não for branco e como "vazio" se for exatamente branco ... OU se você estiver redimensionando O algoritmo altera todos os grupos de 4 pixels em 1 pixel preto toda vez que pelo menos um desses 4 pixels não era branco.
fonte
closest
e verificar a distância até o ponto mais distante doclosest
- vamos nomear a distânciafurthest_dist
. Agora você precisa remover da lista todas as células que têm seu ponto mais próximo além dofurthest_dist
nível e vão mais fundo. Então, ao invés de algo como isto: i.imgur.com/4UuFo.png do É algo como isto: i.imgur.com/dyTT3.png