Problema con RotoZoom

Tratamos sobre el manejo de APIs frecuentemente utilizadas en el desarrollo de videojuegos, como SDL, pygame o SFML.

Problema con RotoZoom

Notapor Metalero » Sab Oct 24, 2009 4:09 pm

Bueno, antes que anda me presento ante la comunidad (no encontre una seccion para presentarme), me llamo Juan, soy argentino, y hace varios años empece que esto del desarrollo de videojuegos (usando el Game Engine RPG Maker XP) y hace un tiempo me meti con SDL.

La cuestion es la siguiente, estoy intentando crear una serie de librerias multimedia (en base a un rejunte de cosas) para poder trabjar mas facil (metiendo todo lo relacionado a bajo nivel en las librerias)

La cuestion es que llegue a la parte que necesito poder rotar imagenes, hasta ahi bien, encontre la libreria RotoZoom, estuve viendo todas las funciones, y me puse a implementarla en mi libreria.

La idea es hacer una funcion asi:

Código: Seleccionar todo
nave.angle(int angulo,int smooth);


Donde nave es un SDL_Surface con un grafico cargado, angulo es el angulo de rotacion y smooth es un flag para activar y desctivar el antialias.

La funcion es asi:

Código: Seleccionar todo
void CSprite::angle(int angulo, int s){
  sprite[estado].img = rotozoomSurface(sprite_est[estado].img, angulo, 1, smooth){
  posx -= (sprite[estado].img->w - sprite_est[estado].img->w) / 2;
  posy -= (sprite[estado].img->h - sprite_est[estado].img->h) / 2;
}


sprite y sprite_est es uin array de surfaces con imagenes (img es el bitmap de la surface)

srpite es la imagen que se muestra en pantalla, mientras que espite_est, es la imagen cargada original, que no se altera en ningun momento.

El problema que tengo es que cuando roto la imagen, hace es movimiento de rebote (que deberia solucionarse con las correcciones:


Código: Seleccionar todo
posx -= (sprite[estado].img->w - sprite_est[estado].img->w) / 2;
posy -= (sprite[estado].img->h - sprite_est[estado].img->h) / 2;


Pero sigue sin funcionar.

Aca les dejo es codigo entero que esoty usando:

Código: Seleccionar todo
#include <stdio>
#include <stdlib>
#include <SDL>
#include <SDL>
#include "include/graphics.h"


SDL_Surface *screen;
CFrame fnave;
CFrame fmalo;
CSprite nave(1);
CSprite malo(1);
SDL_Rect rectangulo;
SDL_Joystick *joystick;
int joyx, joyy;
int done=0;
int player_rects [4][4] = {{48,0,13,33},
                           {39,33,31,111},
                           {0,78,40,46},
                           {70,78,40,46}
                          };
                         

Uint32 ini_milisegundos, fin_milisegundos, frametime;
int angulo = 0;

// estructura que contiene la información de la imagen
struct minave {
  int x,y;
} jugador;


// Dibuja los esprites en la pantalla
void DrawScene(SDL_Surface *screen) {
  // borramos en el frame anterior
  rectangulo.x=nave.getx();
  rectangulo.y=nave.gety();
  rectangulo.w=nave.getw();
  rectangulo.h=nave.geth();
  SDL_FillRect(screen,&rectangulo,SDL_MapRGB(screen->format,0,0,0));
   
   // dibuja avión
  nave.setx(jugador.x);
  nave.sety(jugador.y);
  nave.draw(screen);
  // Mostramos todo el frame
  SDL_Flip(screen);
}

// Inicializamos estados
void inicializa() {
  jugador.x=150;
  jugador.y=150;
 
  nave.set_rects(player_rects);

}

void finaliza() {
  // finalizamos los sprites
  nave.dispose();
  // cerramos el joystick
  if (SDL_JoystickOpened(0)) {
    SDL_JoystickClose(joystick);
  }
}

// Preparamos los esprites
int InitSprites() {
  fnave.load("Imagen.png");
  nave.addframe(fnave);
  return 0;
}

void ResetTimeBase() {
  ini_milisegundos=SDL_GetTicks();
}

int CurrentTime() {
  fin_milisegundos=SDL_GetTicks();
  return fin_milisegundos-ini_milisegundos;
}

int main(int argc, char *argv[]) {
  SDL_Event event;
  Uint8 *keys;
  if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK|SDL_INIT_AUDIO) < 0) {
    printf("No se pudo iniciar SDL: %s\n",SDL_GetError());
    return 1;
  }
  screen = SDL_SetVideoMode(640,480,24,SDL_HWSURFACE);
  if (screen == NULL) {
    printf("No se puede inicializar el modo gráfico: \n",SDL_GetError());
    return 1;
  }
  atexit(SDL_Quit);
 
  InitSprites();
  inicializa();
  while (done == 0) {
    ResetTimeBase();
    // dibujamos el frame
    DrawScene(screen);
    // consultamos el estado del teclado
    keys=SDL_GetKeyState(NULL);
    // consultamos el estado del joystick
    SDL_JoystickUpdate();
    joyx = SDL_JoystickGetAxis(joystick, 0);
    joyy = SDL_JoystickGetAxis(joystick, 1);
    if ((keys[SDLK_UP] || joyy <10> 0)) {
    }
    if ((keys[SDLK_DOWN] || joyy > 10) && (jugador.y < 460)) {
    }
    if ((keys[SDLK_LEFT] || joyx <10> 0)) {
        angulo += 2;
        nave.angle(angulo,1);
    }
    if ((keys[SDLK_RIGHT] || joyx > 10) && (jugador.x < 620)) {
      angulo -= 2;
      nave.angle(angulo,1);
    }
    while (SDL_PollEvent(&event)) {
      if (event.type == SDL_QUIT) {done=1;}
      if (event.type == SDL_KEYDOWN || event.type == SDL_JOYBUTTONDOWN) {
        if (event.key.keysym.sym == SDLK_ESCAPE) {
          done=1;
        }
      }
    }
    do {
      frametime=CurrentTime();
    } while (frametime<40>w - sprite_est[estado].img->w) / 2;
    dest.y=posy - (sprite[estado].img->h - sprite_est[estado].img->h) / 2;;
    SDL_BlitSurface(sprite[estado].img,NULL,superficie,&dest);
Metalero
 
Mensajes: 14
Registrado: Sab Oct 24, 2009 3:47 pm

Notapor endaramiz » Lun Oct 26, 2009 9:12 am

Bienvenido, en fuera de tópico hay un tema donde puedes hablar un poco sobre ti.

No sé el fallo concreto ya que no tengo todo el código. Pero diría que estás tratando posx y posy como la esquina superior izquierda de la imagen. Quizás se resuelva si tratas a posx y posy como centros y luego a la hora de hacer el blit, ya se calcula donde está la esquina superior izquierda.
Código: Seleccionar todo
SDL_Rect dst = {posx - ImagenRotada->w/2, posy - ImagenRotada->h/2};
SDL_BlitSurface(ImagenRotada, NULL, screen, &dst);


Saludos.
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona


Volver a Sobre las bibliotecas multimedia

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado