CURSO DE PROGRAMACION DE VIDEO JUEGOS:  TEXTO #10.
          ---------------------------------------------------

    Hola, ¨como han estado?. Como les habia prometido en este capitulo
    vamos a aprender a guardar imagenes en la memoria y moverlas
    por la pantalla asi que sin mas demora aqui vamos.

1.- Introduccion.

    Cuando nosotros almacenamos algo en la memoria con un programa
    ocupamos una variable, esta puede ser de distintos tipos (integer,
    char, boolean, etc...) cada uno indica un tipo de valor que
    se puede guardar, ya sea numero, letras, etc.. Para guardar
    imagenes en la memoria tambien debemos ocupar una variable
    que identifique a la imagen, pero ¨que tipo de variable?, no
    podemos almacenar una imagen en una variable de tipo char o
    boolean. Para este tipo de dato (una imagen) no existe un tipo
    de variable definida por el Pascal, por lo que debemos ocupar
    un tipo de variable llamada POINTER (puntero).

    Un puntero es una variable que contiene un valor numerico pero
    no cualquier valor, este corresponde a la "direccion de un bloque
    de memoria".

    Veran, cuando nosotros definimos una variable de tipo char, el
    Pascal sabe que va a guardar una letra en esta variable, y como
    todas las letras ocupan la misma cantidad de memoria cuando son
    almacenadas, el Pascal guarda el pedacito de memoria necesario
    para almacenar la letra y listo, ya podemos guardar en este
    espacio cualquier letra. Lo mismo pasa con los valores integer y
    los demas. Sin embargo, cuando queremos guardar una imagen, esta
    puede ser de cualquier tama¤o y el Pascal no sabe cuanta memoria
    va a ser necesaria para almacenarla. Por esto ocupamos un puntero,
    que nos permite definir el tama¤o que va a ocupar la variable que
    almacenemos.

    En el siguiente dibujo pueden ver un puntero apuntando a un bloque
    de la memoria de nuestro PC.


                           MEMORIA
                       ----------------
                       | Espacio      | (reservado para guardar una
     POINTER ------->  | asignado.    |  imagen)
                       |______________|
                       |              |
                       |              |
                       |              |
                       |              |
                       ----------------

    Para definir un variable de tipo puntero se hace algo asi:

    VAR  nombre: POINTER;

    Ejemplo:   VAR Nave: POINTER;

                                 -- o --

2.- Uso de IMAGESIZE y GETMEM.

    Una vez que tenemos definida nuestra variable de tipo puntero
    donde quedara guardada una imagen, es necesario asignarle la
    cantidad de memoria necesaria para almacenarla.

    Primero, debemos saber cuanta memoria sera necesaria. Para esto
    ocupamos la funcion IMAGESIZE:

    Nombre: IMAGESIZE.
    Descripcion: Devuelve la cantidad de memoria necesaria para
                 guardar una imagen en un puntero.
    Sintaxis: IMAGESIZE( x1, y1, x2, y2 ): word;
    Parametros: Los cuatros son valores enteros que corresponden a un
                rectangulo dentro del cual esta la imagen en la pantalla.

    Segundo, debemos asignarle al puntero la cantidad de memoria obtenida
    de la funcion IMAGESIZE, para ello ocupamos GETMEM.

    Nombre: GETMEM.
    Descripcion: Asigna cierta cantidad de memoria a un puntero.
    Sintaxis: GETMEM( puntero, memoria );
    Parametros: puntero es una variable de tipo POINTER y memoria es
                la cantidad de memoria que sera asignada.

    Nota: En el Turbo Pascal toda la memoria se trabaja en BYTES.

                                 -- o --

3.- Guardando la imagen.

    Ahora que ya tenemos listo nuestro sistema de almacenamiento, nos
    queda "capturar" la imagen. Para esto ocupamos el proc. GETIMAGE.

    Nombre: GETIMAGE.
    Descripcion: Guarda una imagen en un puntero.
    Sintaxis: GETIMAGE( x1, y1, x2, y2, puntero^ );
    Parametros: Los cuatro primeros son enteros que forman un rectangulo
                en torno a una imagen. El quinto es el puntero donde se
                va a almacenar.

    Es MUY IMPORTANTE que el rectangulo x1, y1, x2, y2 sea del mismo
    tama¤o del que se ocupo en la func. IMAGESIZE (generalmente los
    mismos valores).

    El simbolo ^ depues del nombre del parametro puntero es muy importante,
    ya que permite indicar que es una variable de tipo puntero la que se
    esta utilizando.

                                 -- o --

4.- Desplegar la imagen.

    Luego para poder dibujar una imagen almacenada a la pantalla
    ocupamos el proc. PUTIMAGE.

    Nombre: PUTIMAGE.
    Descripcion: Copia una imagen almacenada en un puntero a la pantalla.
    Sintaxis: PUTIMAGE( x, y, puntero^, sistema );
    Parametros: x, y son el punto en la pantalla donde se va a colocar la
                imagen y puntero es la variable donde esta almacenada la
                imagen. sistema es como sera desplegada la imagen.

    El sistema con que se va a desplegar la imagen es un valor entre
    0 y 4 que nos permite escoger entre otras cosas si la imagen va
    a borrar lo que hay atras luego de colocarla, si se var a
    traslucir los colores o mezclar, etc...

                                 -- o --

5.- Liberar la memoria.

    Una vez que termina nuestro programa, es importante liberar la
    memoria que teniamos asignada para nuestro puntero, para esto
    ocupamos el proc. FREEMEM.

    Nombre: FREEMEM.
    Descripcion: Libera la memoria almacenada para un puntero.
    Sintaxis: FREEMEM( puntero, tama¤o );
    Parametros: Igual que con GETMEM.


    Veamos un programa de ejemplo:

------------------------------------------------------------------------------
uses crt, graph;

var Bola: pointer;     { Aqui se almacena la imagen }
    tamano: word;      { Aqui se guarda el tama¤o de la imagen
                         (la memoria necesaria) }

{ Verifica que no se presion ESC }
function Salir: boolean;
begin
  Salir:=false;
  if keypressed then
    if Ord(readkey)=27 then Salir:=true;
end;

{ Carga el modo de video }
procedure SetModo;
var modo, drv: integer;
begin
  drv:=3;
  modo:=2;
  initgraph( drv, modo, '' );
end;

{ Dibuja la imagen en la pantalla }
procedure DibujaImagen;
begin
  setcolor( 10 );
  circle( 320, 240, 20 );
  setfillstyle( 1, 14 );
  floodfill( 320, 240, 10 );
  setfillstyle( 7, 11 );
  bar( 300, 230, 340, 250 );
end;

{ Guarda la imagen en la memoria }
procedure GuardaImg;
begin
  { Calcula la memoria necesaria }
  tamano := ImageSize( 299, 220, 341, 260 );
  { Asigna la memoria necesaria al puntero }
  GetMem( Bola, tamano );
  { Captura la imagen de la pantalla }
  GetImage( 299, 220, 341, 260, Bola^ );
end;

{ Comienza la animacion }
procedure Animar;
var x, y, dx, dy: integer;
begin
  x:=320; y:=240;
  dx:=10; dy:=10;
  while not(Salir) do
  begin
    cleardevice;
    { Coloca la imagen la posicion x, y }
    PutImage( x, y, Bola^, 0 );

    inc(x, dx);
    inc(y, dy);
    if (x>580) or (x<2) then dx:=-dx;
    if (y>420) or (y<2) then dy:=-dy;
    delay( 100 );
  end;
end;

begin
  SetModo;
  DibujaImagen;
  GuardaImg;
  setcolor( 15 );
  outtextxy( 30, 10, 'Imagen almacenada. Presiona ENTER para comenzar la animacion.' );
  readln;
  Animar;
  { Libera la memoria asignada la puntero }
  FreeMem( Bola, tamano );

  closegraph;
end.
------------------------------------------------------------------------------

                                 -- o --

    Bien, ¨que les parece?. Solo hay algunas consideraciones que deben
    tener en mente:

­­­­ IMPORTANTE !!!­­­ IMPORTANTE !!!­­­ IMPORTANTE !!!!­­­­ IMPORTANTE !!!!

     LAS SIGUIENTES SITUACIONES PUEDEN DESTRUIR TU COMPUTADOR:

     - SI TRATAS DE ALMACENAR UNA IMAGEN EN UN PUNTERO SIN HABER ASIGNADO
       LA MEMORIA NECESARIA.

     - SI ALMACENAS EN UN PUNTERO UNA IMAGEN MAS GRANDE QUE LA MEMORIA
       ASIGNADA.

     - SI NO LIBERAS LA MEMORIA DE UN PUNTERO CON EL PROC. FREEMEM ANTES
       DE SALIR DEL PROGRAMA.

SI TIENES ESTO EN MENTE SIEMPRE TODO DEBERIA ESTAR OK.

                                 -- o --

    Bueno, lo dejamos hasta aqui por ahora. Salio corto pero les deje
    un lote con que practicar. Prueben los distintos sistemas para
    colocar imagenes con el PUTIMAGE, en el otro capitulo les ense¤o un
    par de metodos para conservar el fondo de la pantalla cuando movemos
    las imagenes.

    CHAO.

    ¨quien hizo esto?:   JPLL
    ¨dudas?:             pc-jlopez@entelchile.net
    ¨otras cosas?:       http://www.geocities.com/SiliconValley/Bridge/1910

    No olviden subscribirse a la lista de avisos de actualizacion del
    sitio (mas info. en mi sito web).

                                 -- o --

    Source: geocities.com/siliconvalley/bridge/1910

               ( geocities.com/siliconvalley/bridge)                   ( geocities.com/siliconvalley)