11 octubre 2010

C#: Una imagen que se mueve con el teclado

Hemos visto lo básico de como mostrar imágenes en pantalla usando C# y SDL.

Un segundo ejemplo algo más detallado podría permitirnos mover el personaje con las flechas del teclado, a una velocidad de 50 fotogramas por segundo, así (tienes los comentarios tras el fuente):



/* Ejemplo de acceso a SDL
desde C# (2),
usando Tao.SDL

Por Nacho Cabanes
*/


using Tao.Sdl;
using System; // Para IntPtr (puntero: imágenes, etc)

public class Sdl02

{

private static void Main()
{


short anchoPantalla = 800;
short altoPantalla = 600;

int bitsColor = 24;
int flags = Sdl.SDL_HWSURFACE | Sdl.SDL_DOUBLEBUF | Sdl.SDL_ANYFORMAT
| Sdl.SDL_FULLSCREEN;

IntPtr pantallaOculta;

// Inicializamos SDL
Sdl.SDL_Init(Sdl.SDL_INIT_EVERYTHING);

pantallaOculta = Sdl.SDL_SetVideoMode(
anchoPantalla,
altoPantalla,
bitsColor,
flags);


// Indicamos que se recorte lo que salga de la pantalla oculta
Sdl.SDL_Rect rect2 =
new Sdl.SDL_Rect(0,0, (short) anchoPantalla, (short) altoPantalla);

Sdl.SDL_SetClipRect(pantallaOculta, ref rect2);

// Cargamos una imagen
IntPtr imagen;

imagen = Sdl.SDL_LoadBMP("personaje.bmp");
if (imagen == IntPtr.Zero) {

System.Console.WriteLine("Imagen inexistente!");
Environment.Exit(4);

}

// Parte repetitiva
bool terminado = false;
short x = 400;

short y = 300;
short anchoImagen = 50;

short altoImagen = 50;
Sdl.SDL_Event suceso;
int numkeys;

byte[] teclas;

do
{
// Comprobamos sucesos
Sdl.SDL_PollEvent(out suceso);
teclas = Sdl.SDL_GetKeyState(out numkeys);


// Miramos si se ha pulsado alguna flecha del cursor
if (teclas[Sdl.SDLK_UP] == 1)

y -= 2;
if (teclas[Sdl.SDLK_DOWN] == 1)

y += 2;
if (teclas[Sdl.SDLK_LEFT] == 1)

x -= 2;
if (teclas[Sdl.SDLK_RIGHT] == 1)

x += 2;
if (teclas[Sdl.SDLK_ESCAPE] == 1)

terminado = true;


// Borramos pantalla
Sdl.SDL_Rect origen = new Sdl.SDL_Rect(0,0,

anchoPantalla,altoPantalla);
Sdl.SDL_FillRect(pantallaOculta, ref origen, 0);

// Dibujamos en sus nuevas coordenadas
origen = new Sdl.SDL_Rect(0,0,anchoImagen,altoImagen);

Sdl.SDL_Rect dest = new Sdl.SDL_Rect(x,y,

anchoImagen,altoImagen);
Sdl.SDL_BlitSurface(imagen, ref origen,
pantallaOculta, ref dest);


// Mostramos la pantalla oculta
Sdl.SDL_Flip(pantallaOculta);

// Y esperamos 20 ms
System.Threading.Thread.Sleep( 20 );


} while (!terminado);

// Finalmente, cerramos SDL
Sdl.SDL_Quit();

}

}


Las diferencias de este fuente con el anterior son:

  • Al inicializar, añadimos una nueva opción, Sdl.SDL_FULLSCREEN, para que el "juego" se ejecute a pantalla completa, en vez de hacerlo en ventana.
  • Usamos un bucle "do...while" para repetir hasta que se pulse la tecla ESC.
  • SDL_Event es el tipo de datos que se usa para comprobar "sucesos", como pulsaciones de teclas, o de ratón, o el uso del joystick.
  • Con SDL_PollEvent forzamos a que se mire qué sucesos hay pendientes de analizar.
  • SDL_GetkeyState obtenemos un array que nos devuelve el estado actual de cada tecla. Luego podemos mirar cada una de esas teclas accediendo a ese array con el nombre de la tecla en inglés, así: teclas[Sdl.SDLK_RIGHT]
  • SDL_FillRect rellena un rectángulo con un cierto color. Es una forma sencilla de borrar la pantalla o parte de ésta.