Foros - Stratos

Programadores => Programación gráfica => Mensaje iniciado por: J_F_NASH en 19 de Agosto de 2005, 10:23:02 PM

Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: J_F_NASH en 19 de Agosto de 2005, 10:23:02 PM
 Trato de hacer un Mario Bros o algo asi.
Tengo una pantalla que he llenado de "tiles" (un tablero) para facilitar el tema de las colisiones (no conozco otra manera mas eficaz).
Los pasos que sigo son:

while(true){
    dibujaTablero();
    dibujaPlayer();
    activaColisiones();
    activaTeclado();
}

El fondo, el tablero (una matriz llena de cuadrados 30x30), siempre se está re-dibujando. Primero pensé que esto sería algo lento o produciría parpadeos, pero me sorprendió ver que no -como ya me comentaron por aquí- de manera que seguiré con esta técnica a menos que me digais lo contrario.

Bueno, quiero probar hacer un simple scroll horizontal. Pero... ¿en que consiste?. ¿Se trata de mover TODOS los tiles en una dirección y ya está? ¿eso no repercute en el rendimiento?
¿Podeis indicarme información concreta que os haya servido sobre este tema?

S2.
Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: StraT en 19 de Agosto de 2005, 10:43:49 PM
 Veamos, pongamos que tienes un array de tiles, como sigue:

| 0 0 0 1 1 1 3 |
| 0 0 0 1 1 1 3 |
| 0 0 0 1 1 1 3 |
| 0 0 0 1 1 1 3 |
| 0 0 0 1 1 1 3 |
| 0 0 0 1 1 1 3 |

y en la primera pantalla te cabe lo siguiente:

| 0 0 0 1 |
| 0 0 0 1 |
| 0 0 0 1 |
| 0 0 0 1 |
| 0 0 0 1 |

si "scrolleas" hacia la derecha, la siguiente pantalla será:


| 0 0 1 1 |
| 0 0 1 1 |
| 0 0 1 1 |
| 0 0 1 1 |
| 0 0 1 1 |

la siguiente:


| 0 1 1 1 |
| 0 1 1 1 |
| 0 1 1 1 |
| 0 1 1 1 |
| 0 1 1 1 |

la próxima:


| 1 1 1 3 |
| 1 1 1 3 |
| 1 1 1 3 |
| 1 1 1 3 |
| 1 1 1 3 |

de forma que lo que se mueve es el array que contiene los tiles que has de dibujar. No consiste en mover el mapa, porque eso te obligaría a dibujar todos los tiles del mapa cada vez, sino de dibujar los tiles que salen en pantalla, actualizando según scrolleas.

Saludos
Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: Lord Trancos 2 en 19 de Agosto de 2005, 10:45:48 PM
 Lo único que tienes que hacer es dibujar la zona visible en pantalla.

Por ejemplo. Si el mapa se encuentra en la posicion X=1000 e Y=2000 (esquina superior izq.) y los tiles son de.... 32 x 32 pixels (por ejemplo). Ya sabes que tienes que dibujar el tile X=1000 div 32 e Y=2000 div 32 (div = division entera).

Como imagino que no querras que el mapa se mueva de tile en tile,... tendras que aplicar un "offset"; es decir no dibujar el tile en cuestion en la coordenada 0,0 de la pantalla. El offset lo obtienes facilmente al obtener el resto de la divisio. Offset X = 1000 mod 32, e Y = 2000 mod 32.

Asi pues el bucle pa dibujar seria algo asin:


 desdeY = (2000 div 32)
 offsetY = (2000 mod 32)
 desdeX = (1000 div 32)
 offsetX = (1000 mod 32)
 for y = 0 to TILES_EN_PANTALLA_A_LO_ANCHO  + 1
   for x = 0 to TILES_EN_PANTALLA_A_LO_ALTO + 1
      DibujarTile(desdeX + x - 1, desdeY + y - 1, - offsetX + (x*32), - offsetY + (y*32))
   next
 next


Los parametros de DibujarTile serian:
 - 1 - Coordenada X del tile a dibujar (en el mapa de tiles)
 - 2 - Coordenada Y del tile a dibujar (en el mapa de tiles)
 - 3 - Posicion X en pantalla
 - 4 - Posicion Y en pantalla.

Para evitar problemas en los bordes lo ideal es que dibujes un "marco" de tiles. Por eso los "+1" y los "-1"
Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: J_F_NASH en 20 de Agosto de 2005, 12:41:15 AM
 Lo unico que logro es moverme tile a tile.
No he entendido nada de lo que hay que hacer luego.

S2.
Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: _Grey en 20 de Agosto de 2005, 04:02:46 AM
 Creo que seria algo así:

int tileSizeX=30,tileSizeY=30; // Ancho/Alto de las tiles, en PIXELS!!

const int sizeX=50,sizeY=50; // Ancho/Alto del mapa de tiles
int mapa[sizeY][sizeX]; // Array bidimensional con el mapa de tiles

// Funcion que dibuja las tiles en pantalla
void dibujarMapa(int x,int y){

int coordX,coordY; // Coordenadas donde pintar la tile, EN PIXELS!!!
int actX,actY; // coordenada de la tile actual mapa[actX][actY]

coordX=-x
for (actX=0;actX<sizeX;actX++){
 coordsY=-y;
 for (actY=0;actY<sizeY;actY++){
  PintaTile(mapa[actY][actX],coordX,coordY); // mapa[actX][actY]->Tile a dibujar, (coordX,coordY) coordenadas donde dibujar la tile
  coordsY+=tileSizeY;
  }
 coordsX+=tileSizeX;
}

}


Espero que te sirva.
Por supuesto se puede optimizar, pero primero que funcione.

Saludos.
Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: J_F_NASH en 20 de Agosto de 2005, 09:36:40 AM
 Por el código que has puesto entiendo que DESPLAZAS (pixel a pixel) todos los tiles que veo en pantalla. ¿Entiendo bien?
Si entiendo bien... ¿esto no es mover todo el mapa de tiles en una dirección o en otra?


S2.
Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: Lord Trancos 2 en 20 de Agosto de 2005, 11:45:11 AM
 
Cita de: "J_F_NASH"Lo unico que logro es moverme tile a tile.
No he entendido nada de lo que hay que hacer luego.
Veamos. Vamos a simplificar el problema a 1 dimension.

Guardarte en una variable (desplazamientoX) la posicion X en pixels que quieres desplazar el mapa de tiles.

Asi, si el mapa es de 100 tiles de ancho, y los tiles son de 32 pixels de ancho... eso significa que tienes un mapa de 3200 pixels de ancho.

Si quiero que el primer pixel que aparezca en la izquierda del mapa (a esto le llamaremos desplazamientoX), sea el pixel 2312 (por ejemplo):


 desplazamientoX = 2312


Lo primero que tenemos que hacer antes de dibujar es calcular que tile sera el primero (tileX) que tenemos que dibujar (por la izquierda), y que "offset" tenemos que aplicarle a ese tile para que el movimiento sea pixel a pixel (offsetX).


 tileX = desplazamientoX div 32
 offsetX = desplazamientoX mod 32


tileX valdra 72 (resultado de la division entera) y offsetX valdra 8 (el resto de la division).

Eso quiere decir que el pixel 2312 corresponde al pixel 8 del tile numero 72. ¿Hasta aqui lo entiendes?

Asi pues, si sabemos que en la pantalla caben (por ejemplo) 40 tiles, para dibujar tenemos que hacer esto:


 For x = 0 to 41
   DibujarTile (tileX + x - 1, -offsetX + ((x-1) * 32))
 Next


Independientemente de que el mapa tenga 100 tiles, el For x = 0 to 41 lo que hace es dibujar 42 tiles (lo de dibujar 42 en lugar de 40 es pq resulta interesante dibujar un tile de mas en cada esquina de la pantalla para evitar problemas).

El (x-1)*32 lo que hace es que cada tile salga al lado del anterior. (el -1 que acompaña al X es para el tile ese de mas que interesa dibujar)

Y el -offsetX lo que hace es aplicar un desplazamiento para que el movimiento sea pixel a pixel.

Asi si haces:

desplazamientoX = desplazamientoX +1


El mapa se "scrolleara" 1 pixel. Finito, finito.

Si sigues sin aclararte, di que cosas en concreto no entiendes o postea tu codigo para que podamos ayudarte mejor.
Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: J_F_NASH en 20 de Agosto de 2005, 09:45:00 PM
 Ahora si.  :rolleyes: (Se agradece una explicación tan detallada)
El RESTO de una división... creí que eso nunca me iba ha servir para nada, y mira por donde :)

S2.
Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: Mars Attacks en 20 de Agosto de 2005, 10:27:19 PM
 La aritmética modular me ha salvado el culo muchas veces. Es un grave error no tenerla en cuenta.
Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: BeRSeRKeR en 21 de Agosto de 2005, 12:04:24 AM
Cita de: "J_F_NASH"El RESTO de una división... creí que eso nunca me iba ha servir para nada, y mira por donde :)
Se utiliza mucho para mantener una variable en un rango determinado (entre otras cosas). Por ejemplo, imagina que tienes una variable que se incrementa indefinidamente y que utilizas para saber en qué frame de una determinada animacion estás. Lo que harías sería:

frame = contador % numFrames

de esta forma, aunque "contador" sobrepase "numFrames", siempre se mantendrá entre 0 y "numFrames - 1".


Saludos.
Título: Scroll ¿en Que Consiste? (sdl)
Publicado por: ethernet en 21 de Agosto de 2005, 12:27:34 AM
 Es tan importante que muchos procesadores incorporan registros e instrucciones específicos para ejecutar operaciones de ese tipo sobre variables.

Un truquillo es usar el operador & cuando se pueda, por ejemplo:

int a[8] = {1,2,3,1....};
int i=0;
while(true) function(a[i++&7]);

pero solo se puede hacer con tamaños potencia de 2. :)