Pido disculpas por el título algo genérico. Realmente no tengo mucha idea sobre cómo lograr lo que estoy tratando de hacer, lo que hace que sea más difícil incluso buscar una posible solución.
Estoy tratando de implementar una especie de marcador de ruta (tal vez hay un nombre más adecuado para ello, pero es lo mejor que se me ocurre).
Delante del jugador habrá un marcador de ruta, que determinará cómo se moverá el jugador una vez que termine de planificar su turno. El jugador puede hacer clic y arrastrar el marcador a la posición que elija, pero el marcador solo se puede mover dentro de un área de trabajo definida (el bit gris).
Así que ahora estoy atrapado con dos problemas:
En primer lugar, ¿cómo debo definir exactamente esa área viable? Me imagino quizás dos vectores que tienen al jugador como punto de partida para formar el ángulo viable, y tal vez esos dos arcos podrían provenir de círculos que tienen su centro donde está el jugador, pero definitivamente no sé cómo poner todo esto. juntos.
Y en segundo lugar, después de definir el área donde se puede colocar el marcador, ¿cómo puedo hacer que el marcador solo permanezca dentro de esa área? Por ejemplo, si el jugador hace clic y arrastra el marcador, puede moverse libremente dentro del área de trabajo, pero no debe abandonar los límites del área. Entonces, por ejemplo, si el jugador comienza a arrastrar el marcador hacia arriba, se moverá hacia arriba hasta que llegue al final del área de trabajo (primer diagrama a continuación), pero si después de eso el jugador comienza a arrastrar hacia los lados, el marcador debe seguir el arrastre mientras aún dentro del área (segundo diagrama a continuación).
Espero que esto no haya sido demasiado confuso. Gracias chicos.
Editar: en caso de que esto haga la diferencia, estoy usando C ++ con Marmalade SDK.
Respuestas:
Puede definir un área viable como la de su pregunta con tres valores:
Estos valores se basarán en un punto central que puede ser o no la posición del jugador. La forma del área viable depende de dónde coloque este punto.
En el ejemplo anterior, la posición central se encuentra a cierta distancia (digamos 50 unidades) detrás del jugador. Esto podría calcularse fácilmente como:
Para limitar la posición del marcador a esa área viable, primero mueva el marcador como lo haría normalmente. Luego, valide la distancia entre el punto central y el marcador:
Finalmente, valide el ángulo del marcador al rango especificado. Usaré pseudocódigo para este:
Mire a su alrededor sobre cómo rotar un punto alrededor de otro. Se puede hacer con trigonometría o con una matriz de transformación.
También es posible que desee tener en cuenta el tamaño del marcador y hacer que el radio y el ángulo sean un poco más pequeños para compensar.
Editar: Pensándolo bien, podría parecer más natural si primero valida el ángulo, luego la distancia, ¡así que pruebe ambas alternativas!
fuente
cos
y unasin
operación, por lo que no estoy seguro. Pero para calcular esos dos vectores también necesita rotarlos, aunque solo necesita hacerlo cuando cambia el vector hacia adelante. De todos modos, no debería importar mucho, elija el que prefiera implementar.Estaba pensando cómo se podría resolver el problema si la forma fuera irregular, y no se podría definir matemáticamente. Advertencia: esta es una solución sucia, no para los débiles de corazón.
1. Tome su área:
2. Y conviértalo a un mapa de bits monocromático:
y nómbralo scale_0
3. Clone el mapa de bits y reduzca su escala al 50%:
y nómbralo scale_1
4. Y así sucesivamente, hasta que haya un mapa de bits de menos de 4 píxeles de ancho / alto:
escala: 2, 3, 4, 5, 6
5. Ahora tenemos nuestra área como mapas de bits monocromáticos de diferentes resoluciones:
6. Tome la última imagen (aquí "scale_6") e itere a través de todos sus píxeles.
x = Math.pow ( 2, scale_level );
donde scale_level es el número que agregamos después de "scale_". También podríamos llamarlo un nivel de árbol cuádruple, aunque en realidad no estamos trabajando con un árbol cuádruple. Haz lo mismo con y.continue
pasar al siguiente paso del buclex *= 2; y*=2;
para traducirlas a coordenadas en la siguiente imagen (escala anterior)7. Tome la imagen anterior (aquí "scale_5"), pero no recorra todos los píxeles; comienza en x = salvado_x y termina con x = salvado_x + 2, lo mismo con y. Es decir, ¡ahora solo recorrerás 4 píxeles para cada nivel! El resto es como en la p. 6)
8. Tome la primera imagen (la más grande = la que tenga la mayor resolución), vuelva a recorrer 4 píxeles y finalmente tendrá el píxel más cercano al cursor del mouse:
9. Sin embargo, estoy tratando "M" como un punto aquí. Si desea que sea un círculo que se ajuste por completo,
circle.radius
primero debe contraer (reducir) la forma por píxeles.Pensé agregar que este algoritmo solo funcionará si usa imágenes no monocromáticas sino en escala de grises y trata un píxel como "lleno" si no es blanco, y como "vacío" si es exactamente blanco ... O si cambia el tamaño El algoritmo cambia cada grupo de 4 píxeles en 1 píxel negro cada vez que al menos uno de estos 4 píxeles no era blanco.
fuente
closest
, y verifica la distancia al punto más alejado en elclosest
- nombremos la distanciafurthest_dist
. Ahora debe eliminar de la lista todas las celdas que tienen su punto más cercano más allá delfurthest_dist
nivel más profundo. Entonces, en lugar de algo como esto: i.imgur.com/4UuFo.png Es algo como esto: i.imgur.com/dyTT3.png