¿Gimp cambia de nombre?

Es posible que muchos de vosotros os hayáis preguntado si después de un cambio tan brutal, como el que os anunciamos hace poco sobre el modo de ventana única o single mode en Gimp, sea necesario cambiarle el nombre para diferenciarlo claramente.

No se me ha ocurrido a mi, han sido los chicos de OMG Ubuntu los que han creado una encuesta para determinar si hacemos una propuesta común o no para el cambio de nombre de Gimp o a establecer un nuevo codename para esta versión.

¿Merece la pena todo esto? Vota aquí. Yo ya he votado. NO era mi respuesta, pero me gustaría además conocer vuestra opinión. read more

Leer más » 7 Comentarios

Curso programación de videojuegos con SDL – Incluyendo enemigos

¿Qué sería de un videojuego de este tipo sin enemigos? La verdad es que es difícil de imaginar por lo que aunque de una manera no demasiado cuidada vamos a incluirlos. Sabiendo ya incluir imágenes y moverlas, la operación es sencilla:

  1. Creamos una nueva estructura de datos para guardar la posición de los enemigos más cómodamente:
    struct posicion{
    int x;
    int y;
    };
  2. El correspondiente puntero para referencia el vector de posiciones:struct posicion *posicionesEnemigos;
  3. Un entero para el número de enemigos: int numeroEnemigos=10;
  4. Un doble puntero para referenciar un vector con los punteros a los enemigos: SDL_Surface **enemigos;
  5. Reservamos memoria para ambos:
    enemigos=(SDL_Surface**)malloc(sizeof(SDL_Surface*)*numeroEnemigos);
    posicionesEnemigos=(struct posicion*)malloc(sizeof(struct posicion)*numeroEnemigos);
  6. Cargamos los mapas de bits, con transparencia, para cada uno de los enemigos. Además inicializamos las posiciones de los enemigos de la siguiente manera:
  • Posición X: Un valor entre 0 y 590 para que quede dentro de la pantalla.
  • Posición Y: Un valor entre 20 y 100 para que no esten todos alineados.

     for(i=0;i<numeroEnemigos;i++)
     {
          enemigos[i]=SDL_LoadBMP(“enemigo.bmp”);
          SDL_SetColorKey (enemigos[i], SDL_SRCCOLORKEY,      SDL_MapRGB (enemigos[i]->format, MASK));
          posicionesEnemigos[i].x=rand()%590+1;
          posicionesEnemigos[i].y=60-rand()%40+1;
     }

  1. Modificamos el título de la ventana: SDL_WM_SetCaption( “Incluyendo enemigos”, “Incluyendo enemigos” );
  2. Dentro del bucle hacemos:
    1. Colocamos las superficies de los enemigos:
      for(i=0;i<numeroEnemigos;i++)
      {
      posicion.x=posicionesEnemigos[i].x;
      posicion.y=posicionesEnemigos[i].y;
      SDL_BlitSurface(enemigos[i], NULL, screen, &posicion);
      }
    2. Le damos velocidad a los enemigos:for(i=0;i<numeroEnemigos;i++){ posicionesEnemigos[i].y+=2;}

    Veamos en una imagen cómo queda:

    Y el código completo serían el siguiente:

    #include <stdio.h> #include <stdlib.h> #include <SDL/SDL.h> #include <time.h> #define MASK 255, 255, 255 struct posicion{ int x; int y; }; int main() { SDL_Surface *screen; SDL_Surface *fondo; SDL_Surface *jugador; SDL_Surface **enemigos; struct posicion *posicionesEnemigos; SDL_Event event; SDL_Rect posicion; int terminar=0; int numeroEnemigos=10; int i, j; int posicionJugadorX=290, posicionJugadorY=430; Uint8* teclas; srand(time(NULL)); if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("No se pudo inicializar SDL: %s\n", SDL_GetError()); exit(1); } /*creando vector para contener enemigos*/ enemigos=(SDL_Surface**)malloc(sizeof(SDL_Surface*)*numeroEnemigos); /*y vector para posiciones de los mismos*/ posicionesEnemigos=(struct posicion*)malloc(sizeof(struct posicion) *numeroEnemigos); fondo = SDL_LoadBMP("fondo.bmp"); jugador = SDL_LoadBMP("avion.bmp"); SDL_SetColorKey (jugador, SDL_SRCCOLORKEY, SDL_MapRGB (jugador->format, MASK)); /*cargando graficos para enemigos y generando posiciones iniciales para los enemigos*/ for(i=0;i<numeroEnemigos;i++) { enemigos[i]=SDL_LoadBMP("enemigo.bmp"); SDL_SetColorKey (enemigos[i], SDL_SRCCOLORKEY, SDL_MapRGB (enemigos[i]->format, MASK)); posicionesEnemigos[i].x=rand()%590+1; posicionesEnemigos[i].y=60-rand()%40+1; } screen = SDL_SetVideoMode( 640, 480, 16, SDL_HWSURFACE ); if( screen == NULL ) { printf( "Error al entrar a modo grafico: %s\n", SDL_GetError() ); SDL_Quit(); return -1; } SDL_WM_SetCaption( "Incluyendo enemigos", "Incluyendo enemigos" ); while(!terminar) { for (i=0; i<10; i++) for (j=0; j<10; j++) { posicion.x=64*i; posicion.y=48*j; SDL_BlitSurface(fondo, NULL, screen, &posicion); } posicion.x=posicionJugadorX; posicion.y=posicionJugadorY; SDL_BlitSurface(jugador, NULL, screen, &posicion); for(i=0;i<numeroEnemigos;i++) { posicion.x=posicionesEnemigos[i].x; posicion.y=posicionesEnemigos[i].y; SDL_BlitSurface(enemigos[i], NULL, screen, &posicion); } SDL_Flip(screen); while ( SDL_PollEvent(&event) ) { if (event.type == SDL_QUIT || event.key.keysym.sym == SDLK_ESCAPE) terminar = 1; } teclas = SDL_GetKeyState(NULL); if (teclas[SDLK_UP]) { posicionJugadorY -= 2; } if (teclas[SDLK_DOWN]) { posicionJugadorY += 2;} if (teclas[SDLK_LEFT]) { posicionJugadorX -= 2; } if (teclas[SDLK_RIGHT]) { posicionJugadorX += 2; } for(i=0;i<numeroEnemigos;i++) { posicionesEnemigos[i].y+=2; } } SDL_Quit(); return 0; } read more

Leer más » 8 Comentarios

Controlar teclas especiales con C (flechas, ENTER, TAB, ESC) en entornos Windows

Cuando programamos en C, nos enseñan desde primera hora a usar las funciones típicas de entrada/salida presentes en stdio.h: printf(), scanf(), getchar(), gets()… pero normalmente se obvia el uso de funciones algo más avanzadas para detectar pulsaciones de teclas o interactuar de forma más directa con la terminal.

Hoy os explicaré para qué sirven dos funciones: getch() y getche(), disponibles en conio.h (como ya advierto en el título de la entrada, este código funciona en entornos Windows, en entornos Linux ya explicaré en otra entrada cómo se puede hacer).

  • getch(): devuelve un char que representa el código ASCII de la tecla pulsada
  • getche(): ídem que el anterior, pero además lo imprime por pantalla

Veamos un ejemplo en el que detectamos la pulsación de las flechas del teclado, la tecla ENTER y el tabulador:

#include <stdio.h> #include <conio.h> int main() { char cTecla; printf("\r\nPresione un Tecla ..."); while(cTecla != 27) { cTecla = getch(); if(cTecla == 0) cTecla = getch(); else switch(cTecla) { case 13: printf("\r\n Presiono ENTER"); break; case 9: printf("\r\n Presiono TAB"); break; case 72: printf("\r\n Presiono Flecha Arriba"); break; case 80: printf("\r\n Presiono Flecha Abajo"); break; case 75: printf("\r\n Presiono Flecha izquierda"); break; case 77: printf("\r\n Presiono Flecha derecha"); break; } } return 0; } read more

Leer más » 7 Comentarios

Gimp 2.7.3 en Single window – Ventana única

Hablamos hace ya más de dos años (portal antiguo) de que en la versión 2.8 de Gimp aparecería el modo Single Window o ventana única. El cambio se ha hecho esperar, pero ya está disponible en la última actualización de la versión 2.7.

Simplemente, impresionante. Ya me acostumbré a lo anterior, pero no tardaré en hacerme con esto.

Vía Gimp Developer.

Leer más » 6 Comentarios

El efecto Linus Torvals

El pasado 26 de julio, hace casi un mes, Linus Torvals anunció en Google+ que se pasaría definitivamente a XFCE por su poca afinidad con la versión 3 de Gnome. Pues bien, el efecto se ha hecho notar:

Incluso en Google se ha notado la creciente búsqueda de “XFCE” tras las declaraciones. La marca A cuando se lanzó la última versión, la 4.8. La marca B cuando Linus habló.

Afortunada o desgraciadamente, la influencia de estas declaraciones pueden marcar la desvinculación de este escritorio para muchos usuarios. En mi caso, tengo dos opciones, me quedo con las actualizaciones sobre la versión dos o vuelvo al que fue mi primer escritorio, XFCE. read more

Leer más » 8 Comentarios

Lo mejor de mi RSS del 15 al 21 de agosto

Leer más » 1 Comentario

Reservar memoria dinámica para una matriz en C

Acabamos de hablar hace nada de cómo reservar memoria para un vector unidimensional de forma dinámica con C. Hoy le toca el turno a las matrices o arrays bidimensionales. Los vectores se organizan de forma lineal, secuencial y con todos los elementos en posiciones correlativas en la memoria. Las matrices se almacenan en forma de vector de vectores.

Dimensiones fijas

Si es de dimensiones fijas (declarándolas como matriz[filas][columnas]), el vector de vectores se guardará también uno al lado del otro.

Por lo tanto, en una matriz del tipo:

a00 a01 a02
a10 a11 a12
a20 a21 a22

En memoria (en la que los elementos los direccionamos en una sola dirección) los tendríamos de la siguiente forma (en cada lenguaje este criterio cambia, en Fotran se almacena en forma de vector de columnas):

a00 a01 a02 a10 a11 a12 a20 a21 a22

Dimensiones variables

Sin embargo, en el caso de la memoria dinámica, las cosas cambian. El mecanismo será el siguiente:

  • Declararemos un doble puntero “matriz” sobre el que reservaremos memoria para tantas filas tengamos.
  • Recorreremos el vector recién creado para reservar memoria para las columnas de cada fila.

Hay dos detalles a tener en cuenta:

  • La variable “matriz” será del tipo doble puntero ya que hará referencia a un vector de punteros.
  • Cada fila sí estará almacenada de forma consecutiva en memoria, pero éstas a su vez no estarán de forma obligada juntas, aunque podremos seguir accediendo de la misma forma.

Veamos un ejemplo con código real (no hace comprobaciones de que el malloc se ejecute correctamente):

#include <stdlib.h> #include <stdio.h> int main(void) { int filas = 2; int columnas = 3; int **x; int i; // Recorre filas int j; // Recorre columnas // Reserva de Memoria x = (int **)malloc(filas*sizeof(int*)); for (i=0;i<filas;i++) x[i] = (int*)malloc(columnas*sizeof(int)); // Damos Valores a la Matriz x[0][0] = 1; x[0][1] = 2; x[0][2] = 3; x[1][0] = 4; x[1][1] = 5; x[1][2] = 6; // Dibujamos la Matriz en pantalla for (i=0; i<filas; i++) { printf("\n"); for (j=0; j<columnas; j++) printf("\t%d", x[i][j] ); } return 0; } read more

Leer más » 16 Comentarios

[Tips] Google compra Motorola

La noticia (Mashable) me sorprende de dos formas, la primera es que desconozco qué mercado espera cubrir Google con esta compra, no lo tengo demasiado claro.

La segunda la barbaridad que han pagado por esta adquisión, sólo 12.5 billones de dólares, lo que serían en lengua española 12500 millones de dólares. Recordad que un billón anglosajón no equivale a un billón español, ya que aquí (España) se considera que un billón es un millón de millones y en este caso hablamos de miles de millones. read more

Leer más » 5 Comentarios

Reservar memoria dinámica para un vector en C

Puesto que estamos hablando bastante de C en el curso de programación de videojuegos con SDL, voy a publicar una serie de pequeños apuntes sobre programación en C que seguro que os son de utilidad. No van a constituir un curso como tal pero serán una serie de entradas relacionadas sobre este tema. read more

Leer más » 8 Comentarios

Lo mejor de mi RSS del 8 a 14 de agosto

Leer más » 1 Comentario