Función RotoZoomPolySprite

Previous topic - Next topic

msx

Últimamente estoy tratando de corregir mi costumbre de usar DRAWSPRITE y cambiarlo por POLYVECTOR que por lo que se comenta es más rápido y además mejora la compatibilidad entre plataformas. Lo malo es que no existe una función que rote y haga zoom, así que he creado una que espero que os sea útil.

Code (glbasic) Select
FUNCTION RotoZoomPolySprite: Sprite_ID,CenterX,CenterY,Angle,Zoom

LOCAL sx,sy // Dimensiones del Sprite
LOCAL p1x,p1y // Punto 1 rotado
LOCAL p2x,p2y // Punto 2 rotado
LOCAL p3x,p3y // Punto 3 rotado
LOCAL p4x,p4y // Punto 4 rotado
GETSPRITESIZE Sprite_ID,sx,sy

// Trasladamos centro de polígono a coordenadas 0,0 y rotamos
p1x=(-sx/2)*COS(Angle)-(-sy/2)*SIN(Angle)
p1y=(-sx/2)*SIN(Angle)+(-sy/2)*COS(Angle)

p2x=(-sx/2)*COS(Angle)-(sy/2)*SIN(Angle)
p2y=(-sx/2)*SIN(Angle)+(sy/2)*COS(Angle)

p3x=(sx/2)*COS(Angle)-(sy/2)*SIN(Angle)
p3y=(sx/2)*SIN(Angle)+(sy/2)*COS(Angle)

p4x=(sx/2)*COS(Angle)-(-sy/2)*SIN(Angle)
p4y=(sx/2)*SIN(Angle)+(-sy/2)*COS(Angle)

// Aplicamos Zoom
p1x=p1x*Zoom
p1y=p1y*Zoom

p2x=p2x*Zoom
p2y=p2y*Zoom

p3x=p3x*Zoom
p3y=p3y*Zoom

p4x=p4x*Zoom
p4y=p4y*Zoom


// Trasladamos centro de polígono a coordenadas dadas
p1x=p1x+CenterX
p1y=p1y+CenterY

p2x=p2x+CenterX
p2y=p2y+CenterY

p3x=p3x+CenterX
p3y=p3y+CenterY

p4x=p4x+CenterX
p4y=p4y+CenterY

// Dibujamos polígono
STARTPOLY Sprite_ID
        POLYVECTOR p1x,p1y,0,0,RGB(255,255,255)
        POLYVECTOR p2x,p2y,0,0+sy,RGB(255,255,255)
        POLYVECTOR p3x,p3y,0+sx,0+sy,RGB(255,255,255)
        POLYVECTOR p4x,p4y,0+sx,0,RGB(255,255,255)
ENDPOLY

ENDFUNCTION


Saludos.

ampos

Esa ya la tenía yo hecha en el PROYECTO Z  :good:

Ah, y el polysprite es realmente rápido si usas polynewstrip y un solo sprite/hoja de sprites; si no, me temo que es igual de rápido que el drawsprite.
check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE

msx

Z de Zumbao  =D

No me había percatado, en fín ya lo tenemos doble.  :S

msx

Quote from: ampos on 2011-Dec-28
Ah, y el polysprite es realmente rápido si usas polynewstrip y un solo sprite/hoja de sprites; si no, me temo que es igual de rápido que el drawsprite.

¿polynewstrip sirve para repetir la misma imagen múltiples veces?

Ruidesco

#4
POLYNEWSTRIP se puede usar sólo cuando haces un STARTPOLY en modo strip (2), y sirve para poder dibujar la misma u otra porción de gráficos que estén dentro del mismo sprite especificado en STARTPOLY sin tener que hacer ENDPOLY y STARTPOLY, lo que es mucho más rápido. Es una de las razones por las que se suele agrupar todo lo que se puede dentro de una única spritesheet.

msx

Comprendido, gracias  :nw:

mentalthink

Gracias MSX, esto es realmente útil, ademas lo bueno que tiene es el tema de cambiarle los colores a los sprites...
No sé si me va a dar tiempo a cambiarlo en mi proyecto, pero me voy a pensar en usar está técnica antes que los Sprites convencionales....

Gracias.... :nw: :nw: :nw:

mentalthink

Una consultilla  :-[ :-[ :-[

Para hacer una colision con el objeto como se haría?¿, he tratado de poner los segmentos entre los puntos horizontales y los verticales, y no me funciona correctamente, OJO!!! estoy seguro que algo hago mal...

El hecho es que me gustaria hacer un boxcoll, pero la cajas tuvieran angulo, ya que me gustaría poder añadir al Editor del Black Sun un modulo de cajas que se pudieran rotar y escalar.

Estoy probando la colision polygonal que hay en el foro inglés, pero cuando tengo más de 1 figura geometrica no me aclaro como hacer que todas las formas tengan colision...

Gracias de antemano  ...

msx

#8
Hola Iván, te he creado esta función, no la he probado pero debería funcionar.

La función comprueba si un punto está dentro de un polígono de cuatro punto (dos triángulos). Para comprobar la colisión entre dos formas tienes que pasarle los cuatro vértices de una de las formas, y un vértice de la otra forma, si te retorna 1 es que existe colisión, si te devuelve 0 tienes que volver a llamar a la función pasándole como parámetro otro vértice de la segunda forma, así hasta completar todos los vértices (aquí pueden ser más de cuatro).

Ya me cuentas.

Code (glbasic) Select
FUNCTION PuntoInterior: PX,PY,p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y // Comprueba colisión de rectángulo con polígono.
LOCAL Orientacion124,Orientacion234
LOCAL Orientacion_Punto

// Calculamos Orientación de los triángulos inscritos en el rectángulo
Orientacion124=ORIENTACION(p1x,p1y,p2x,p2y,p4x,p4y)
Orientacion234=ORIENTACION(p2x,p2y,p3x,p3y,p4x,p4y)

// Orientación con Punto 12P
Orientacion_Punto=ORIENTACION(p1x,p1y,p2x,p2y,PX,PY)
IF (Orientacion_Punto>0 AND Orientacion124<0) OR (Orientacion_Punto<0 AND Orientacion124>0) THEN GOTO P_Exterior1
// Orientación con Punto 24P
Orientacion_Punto=ORIENTACION(p2x,p2y,p4x,p4y,PX,PY)
IF (Orientacion_Punto>0 AND Orientacion124<0) OR (Orientacion_Punto<0 AND Orientacion124>0) THEN GOTO P_Exterior1
// Orientación con Punto 41P
Orientacion_Punto=ORIENTACION(p4x,p4y,p1x,p1y,PX,PY)
IF (Orientacion_Punto>0 AND Orientacion124<0) OR (Orientacion_Punto<0 AND Orientacion124>0) THEN GOTO P_Exterior1

RETURN 1

P_Exterior1:

// Orientación con Punto 23P
Orientacion_Punto=ORIENTACION(p2x,p2y,p3x,p3y,PX,PY)
IF (Orientacion_Punto>0 AND Orientacion234<0) OR (Orientacion_Punto<0 AND Orientacion124>0) THEN GOTO P_Exterior2
// Orientación con Punto 34P
Orientacion_Punto=ORIENTACION(p3x,p3y,p4x,p4y,PX,PY)
IF (Orientacion_Punto>0 AND Orientacion234<0) OR (Orientacion_Punto<0 AND Orientacion124>0) THEN GOTO P_Exterior2
// Orientación con Punto 42P
Orientacion_Punto=ORIENTACION(p4x,p4y,p2x,p2y,PX,PY)
IF (Orientacion_Punto>0 AND Orientacion234<0) OR (Orientacion_Punto<0 AND Orientacion124>0) THEN GOTO P_Exterior2

RETURN 1

P_Exterior2:

RETURN 0

ENDFUNCTION

FUNCTION ORIENTACION: x1,y1,x2,y2,x3,y3

RETURN (x1-x3)*(y2-y3)-(y1-y3)*(x2-x3)

ENDFUNCTION




P.D.: Este proceso tendrás que hacerlo dos veces, una por cada polígono, porque el que los vértices del polígono B no esté dentro del polígono A no quiere decir que los vértices del Polígono A no puedan estar dentro del Polígono B, no sé si me entiendes. En ambos casos se produciría una colisión.


mentalthink

Gracias MSX, mañana la pruebo y te comento... aunque he leído por ahí buscando temas de colisiones, que se ve que un rectangulo girado consume un mogollon de CPU,   O_O O_O, no sé hasta que punto eso es asi...

El tema es que está tarde he recordado un truquillo que comento Gernnot para el tema de los sprites muy grandes, y es digamos escalando la pantalla en otro sitio, con menos tamaño, para reducir los espacio del canal alpha de los PNG, pero luego me he vuelto a acordar que cuando se usa 3D, una simple collision con pixel perfect, para el juego, pero en seco, se ve que como mira el spritecoll el fondo, parece ser que "no se lleva muy bien con las open Gl en 3d"  :S

De nuevo gracias de antemano, y mañana te digo a ver si lo he conseguido hacer funcionar...

msx

Vaya lío que me has formado, no me enterao de ná  :S

Bueno algo sí y no estás exento de razón. Fíjate la de operaciones que hace la función anterior para comprobar si un punto está dentro de un polígono, pues en el peor de los casos para dos formas rectángulares, tendrías que llamar a la función 8 veces  :whistle: En tu caso (Black Sun) supongo que tendrás multitud de formas por ahí pululando y tendrás que estar continuamente comprobando posibles colisiones con cada una de ellas. Eso para el caso de polígonos de 4 vértices (2 triángulos), si son polígonos de N vértices (N-2 triángulos) el número de operaciones es aún mayor (requeriría modificar la función), total una burrada.  :'(

La función se podría modificar para pasarle dos Arrays que contenga cada uno los parámetros de cada vértice del polígono correspondiente y que la función se encargue de separar los triángulos y hacer las comprobaciones.

En cualquier caso creo que lo más rápido (y más inexacto) sería tomar los polígonos como circunferencias y comprobar la colisión de dos circunferencias que es muchísimo más elemental, aunque podría aparecer efectos raros.


mentalthink

Ok MSX, pérdona si te he armao un lio al escribir, demasiadas horas delante el PC y café en el cuerper.

Esto que te comentaba que consume mucha CPU, lo he leido por ahí, no es que lo diga yo, que no tengo ni "papa" de programación....

Esto que me comentas de las esferas lo he pensado, lo que pasa que las formas no son exactamente redondas, por lo que había pensado hacer en el Editor pues mezclas con cajas y esferas, basicamennte es para el tema de las collisiones con los backggrounds (los de primer plano, o los foregorunds), las collsiones con los  enemigos es bastante sencillo, con esferas o cajas o utilizando un par de cada se soluciona, y sobre los objectos 3D, aunque no he hecho una prueba a saco disparando, por colision con caja, no creo que haya mucho problema...

PS: Lo que a lo mejor te he liado, te lo intento explicar mejor, es :

Si tienes un mundo 2D y uno 3D mezclado, si utilizas el SPRCOLL, que hace la colision por pixel, cuando colisionas dos sprites con esta técnica, el juego se queda parado hasta que la colision desaparece... Esto me comento Gernnot que es porque el SprColl cuando funciona con un mundo 3D y 2D a la vez, mira tambien lo que sucede en el fondo, en esté caso al se 3D, y si las texturas són muy grandes se ve que intenta calcular algo... no sé más.... pero por si alguna vez hacés o alguien hace algo fusionado con 2D y 3D tened en cuenta estó, porque literalemte el juego se para hasta que ese SPRCOLL, se le elimina el disparo que lo provoca o se llava a otra posicion , o como elimineís los disparos...