2010-10-01 12 views
13

Estoy haciendo un motor de juego basado en lienzo y me pregunto si alguien tiene alguna buena información sobre cómo lograr una perspectiva de vista aérea. Lo que estoy buscando está en algún lugar a medio camino entre la vista de pájaro tradicional y la vieja vista de modo7 de SNES. Solo un pequeño ángulo para dar la ilusión de 3D.Transformada en perspectiva de modo 7 en lienzo?

Estoy tratando de averiguar cuál va a ser la mejor manera de lidiar con el sesgo de la perspectiva. No estoy haciendo rotaciones, así que las cosas de la matriz 3D irían por la borda, pero necesito poder procesar las capas del mapa en un ángulo constante y sería bueno si el ángulo fuera ajustable. También necesito lidiar con la disformidad de profundidad. Básicamente, la fila inferior de píxeles debe tener un ancho y una altura de 1: 1 píxeles, luego, para cada fila, por ejemplo, un 5% más pequeño o algo así. Lo que me gustaría es poder suministrar un lienzo grande como textura y luego proporcionar un ángulo de cámara entre 0 y 90, donde 0 es perfectamente horizontal y 90 es la vista de pájaro.

¿Alguien tiene algún tutorial relacionado o código de muestra? He buscado en línea un poco, pero todo lo que he encontrado parece no ser adecuado para su uso en esta aplicación en particular o demasiado complejo, haciendo todo tipo de locos giros y rotaciones en 3D. Todo lo que quiero es tomar la cuadrícula de mosaico normal e inclinarla hacia atrás un poco, sin rotaciones ni cosas complicadas como esa.

Aquí hay un ejemplo de lo que quiero; Here's an example. http://img801.imageshack.us/img801/2176/perspectivesample.jpg

La fila de píxeles inferior es de 1: 1 de proporción de píxeles, y cada fila de arriba se acorta progresivamente horizontal y verticalmente. La textura fuente de la región central superior es normalmente aproximadamente la mitad de la altura de la región central inferior, pero se ha reducido vertical y horizontalmente para adaptarse a la perspectiva.

Lo que estoy pensando que podría funcionar mejor es renderizar el estado de la ventana actual a otro lienzo plano, a vista de pájaro, con aproximadamente un 50% de espacio adicional en la parte superior y los lados, luego cortar una región triangular al revés de eso y dibuja eso al lienzo visible real.

El único problema es que me molestan las matemáticas cuando se trata de calcular ángulos y cosas así.

+1

¿Tiene un ejemplo gráfico en algún lugar en línea? Solo quiero obtener una idea más clara de lo que quiere. Gracias – Castrohenge

+0

Agregué una imagen, para representar lo que quiero. El mapa es en realidad un patrón de cuadrícula de 32x32, pero inclinado hacia atrás para agregar perspectiva. –

+3

Esto es interesante: http://acko.net/blog/projective-texturing-with- canvas –

Respuesta

3

Lo que está diciendo es algo que se puede hacer simplemente con cualquier api 3D. Sin embargo, como has decidido tratar de mantenerte en el lienzo en 2D, tienes que hacer todo lo posible en el mundo 2D, lo que significa trabajar con rectángulos, rotación, escala, sesgo, etc. También se conocen como transformaciones afines, como se mencionó en la otra respuesta.

Lo que quieres hacer es posible, pero como quieres usar 2D tienes que pensar en términos de funciones 2D.

  1. Genera tu imagen inicial.
  2. Agregue un corte desde la parte inferior de la imagen original a la parte inferior del lienzo, muy ligeramente hacia la izquierda para que el centro de la imagen coincida con el centro del lienzo actual.
  3. Aumente ligeramente la escala de la imagen completa
  4. Repita hasta llegar a la parte superior de la imagen.

El pseudo código se vería así ...

imgA = document.getElementById('source'); 

// grab image slices from bottom to top of image 
for (var ix=height-slice_height;ix>=0;ix-=slice_height) 
{ 

    // move a section of the source image to the target canvas 
    ctx.drawImage(imgA, 0,ix,width,slice_height, 
     0-half_slice_width_increase,width,slice_height); 
    // stretch the whole canvas 
    ctx.scale(scale_ratio, 1); 
} 

Esto tomará un montón de ajustes, pero eso es la solución general.

  • scale_ratio será un número ligeramente más grande, pero muy cerca de 1.
  • ctx es el contexto 2D lona estándar
  • half_slice_width_increase es el medio la cantidad que el lienzo crecer cuando se escala por la relación de escala. Esto mantiene centrada la imagen escalada.

Para que quede bien, querrá transformar los mosaicos de fondo antes de agregar las superposiciones de los iconos.

+0

Como dije en los comentarios, necesito que sea capaz de manejar imágenes que no están perfectamente centradas. Es bastante fácil para mí descubrir lo que has publicado, es compensar las imágenes que no están centradas con las que estoy teniendo problemas. –

+0

No estaba claro, supongo, pero la imagen inicial se generaría en un objeto canvas en 2D plano. Esa es la fuente. A continuación, toma rodajas de la imagen 2D terminada e inclínela agregando una línea al fondo, haciendo un ligero aumento y repitiendo a medida que sube. Luego agregue sprites en el mapa inclinado. Trataré de hacer una demostración en funcionamiento si tengo tiempo este fin de semana. –

6

si te entiendo bien, solo quieres una transformación de trapecio simple. si es así, tal vez this o this enlace lo ayude. para las imágenes que no están centradas, sería una transformación romboidal adicional, que es muy posible con el lienzo, hasta donde yo sé.

Cuestiones relacionadas