Saltar al contenido
56K

56K

Slow IT Notes – Just 4 Fun

Menú
Menú

SDL en C bajo GNU/Linux – 005 – Moviendo con el teclado un objeto

Publicada el 24/10/202106/02/2023 por fanta

En este nuevo post vamos a ver como controlar eventos. En este caso cerrar la ventana, la pulsación de algunas teclas y con ello mover en pantalla algo.

Para ello he recurrido al típico ejemplo de una nave que movemos en el eje x e y.

Aquí se puede bajar todo el tinglado para seguir el tutorial: teclado.zip

 

Está vez en este quinto post no voy a repetir el rollo de como compilarlo ni como crear el makefile ya que presupongo que si lees esto es que te interesa y lo mismo ya has visto los anteriores.

Antes de mostrar el código hemos de saber que para usar el tipo bool en C hemos de añadir stdbool.h . Hemos de saber también que vamos a precisar de 2 mapas de bits (uno de una nave y otro del fondo):

 

5

 

 

Pongo el código y tras ello intentaré explicarlo:

 

#include <SDL.h>
#include <stdbool.h>

int main(int argc, char ** argv) {

	SDL_Window * ventana;
	SDL_Renderer * render;
	SDL_Event evento;
	
	
	SDL_Surface * imagenNave;       			// Nave
	SDL_Texture * texturaNave;      			// Nave
	SDL_Surface * imagenFondo;       			// Fondo Mar
	SDL_Texture * texturaFondo;      			// Fondo Mar
    imagenNave = SDL_LoadBMP("res/nave.bmp");	// Cargamos el mapa de bits de la nave
	imagenFondo = SDL_LoadBMP("res/mar.bmp");	// Cargamos el bmp del fondo.

	int anchoNave = 128;			// Definimos el ancho de la nave
	int altoNave = 113;				// Definimos el alto de la nave
	int x = (640/2)-(anchoNave/2);		// Eje x - Posición inicial de la nave
	int y = (480/2)-(altoNave/2);					// Eje y - Posición inicial de la nave	

	bool quit = false;

	SDL_Init(SDL_INIT_VIDEO);
	ventana = SDL_CreateWindow("Controlando el teclado",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,640,480,SDL_WINDOW_OPENGL);

	if (ventana == NULL) {
		printf("No se pudo crear la ventana: %s\n", SDL_GetError());
		return 1;
	}

	render = SDL_CreateRenderer(ventana, -1, 0);
	
	texturaFondo = SDL_CreateTextureFromSurface(render, imagenFondo);
	SDL_RenderCopy(render, texturaFondo, NULL, NULL);
	SDL_RenderPresent(render);
	
	texturaNave = SDL_CreateTextureFromSurface(render, imagenNave);
	SDL_Rect dstrect = { x, y, altoNave, anchoNave };
	SDL_RenderCopy(render, texturaNave, NULL, &dstrect);
	SDL_RenderPresent(render);


	while (!quit) {
		SDL_WaitEvent(&evento);
		
		switch (evento.type) {
			case SDL_QUIT:
				quit = true;
				break;
			case SDL_KEYDOWN:
				switch (evento.key.keysym.sym) {
					case SDLK_LEFT:  x--; break;
					case SDLK_RIGHT: x++; break;
					case SDLK_UP:    y--; break;
					case SDLK_DOWN:  y++; break;
				}
				break;
			
		}
	
		SDL_RenderCopy(render, texturaFondo, NULL, NULL);
		SDL_RenderPresent(render);
	
		SDL_Rect dstrect = { x, y, altoNave, anchoNave };
		SDL_RenderCopy(render, texturaNave, NULL, &dstrect);
		SDL_RenderPresent(render);	
		
	}


}

 

Usando las teclas cursor (arriba, abajo, izquierda, derecha) se moverá la nave, aunque muy lento.
Se puede hacer que en vez de pixel a pixel se mueva de 5 en 5 así:

 

					case SDLK_LEFT:  x=x-5; break;
					case SDLK_RIGHT: x=x+5; break;
					case SDLK_UP:    y=y-5; break;
					case SDLK_DOWN:  y=y+5; break;

 

SDL_QUIT es el evento cuando el usuario solicita salir (pulsando en la x de la ventana).
Hemos declarado una variable booleana (true/false) llamada quit con el valor false.

Durante todo el tiempo que la ventana esté abierta estará comprobando si eso cambia, en el caso de que solicitemos cerrar la ventana en el evento SDL_QUIT indicaremos que el valor de la variable quit es true y eso servirá para que se salga del bucle while.

En anteriores posts no metíamos ningún bucle, básicamente dejábamos unos segundos lo que queríamos y el programa llegaba a su fin cerrándose la ventana. Ahora que ya sabemos como controlar eventos (al menos algunos) ya no vamos a trabajar así.

 

La posición de la nave.

La posición de la nave se puede realizar con las variables que hemos declarado: x e y.

int x = (640/2)-(anchoNave/2);		// Eje x - Posición inicial de la nave
int y = (480/2)-(altoNave/2);		// Eje y - Posición inicial de la nave	

 

En vez de poner de valor a «x» el entero 0 y a «y» también 0 podemos realizar algunas restas y divisiones para centrar la nave.

 

Si analizamos eso simplemente estamos dividiendo el ancho y alto de la ventana y luego a eso restándole la mitad del ancho y alto de la nave.

Aquí SDL_Keycode se puede ver que en vez de los cursores podríamos usar también otras teclas.

 

No tiene mucho más misterio. En futuras entradas iremos controlando esto un poco más e incluso realizar algunos ejemplos de control de un joystick o el ratón.

 

Saludos cordiales.


fanta

Escrito por Fanta

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

fanta de naranja
Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors
💾 QEMU
💾 SOLARIS
💾 ESXi
💾 FREEBSD
💾 DEBIAN
💾 AMIGA
💾 SYSADMIN
💾 JUNOS
💾 IMPRIMIR
💾 MSDOS
💾 WINDOWS
💾 FAIRPHONE
💾 GAMING
💾 STREAMING
💾 REDHAT
💾 GRÁFICOS
💾 CACHARROS
💾 SONIDO
💾 NETWORKING
💾 ROCKY
💾 SUSE
💾 TMP
©2025 56K | Construido utilizando WordPress y Responsive Blogily tema por Superb