Foros del Web » Programación para mayores de 30 ;) » C/C++ »

problemas con sdl y mouse

Estas en el tema de problemas con sdl y mouse en el foro de C/C++ en Foros del Web. hola tengo un problema y no encuentro la forma de solucionarlo estoy con las SDL ya que no tengo mucha experiencia tengo un juego buscaminas ...
  #1 (permalink)  
Antiguo 08/11/2008, 09:10
 
Fecha de Ingreso: mayo-2007
Ubicación: Buenos aires
Mensajes: 19
Antigüedad: 17 años
Puntos: 0
problemas con sdl y mouse

hola tengo un problema y no encuentro la forma de solucionarlo
estoy con las SDL ya que no tengo mucha experiencia
tengo un juego buscaminas no esta completamente terminado
weno mi problema es en la funcion destapar hice dos bucles para que recorra el tablero puse pollevent detecte evento si toque una tecla del mouse hice un if que verifique si la celda es correcta y se presiono la tecla del mouse izquierdo imprima por pantalla la celda weno solo
funciona mouse en la primera celda 0,0 si presiono en las demas no anda osea no mestra la img pense que el problema esta en la validacion de la posicicion de cada casillero pero no se yo la veo correcta luego pense en que poll va almacenado cada evento y como devo hacer muchos clicks estoy consultado mal el evento ocurrido por eso solo anda mouse en la primera celda, si cambio la posicion inicial del for que empiese de 4 por ejemplo el mouse funciona pero solo en la coordenada x4 y 4
que puede ser?solo anda mouse en una celda

struct Tcasilla {
int nmina;
int status;
};
Tcasilla matriz[10][10];

tamaño imagen celda 15

Código:
t=0 
while (t!=1) 
   { 

   t=buscaminas.destapar(cronometro,celda,monitor,evento); 
   }
funcion muesta la imagen de cada celda

Código:
void CBuscaminas::DibujaCasilla(ClsSprite &celda,ClsMonitor &monitor,int i,int j) 
{ 
if(matriz[i][j].status==1) 
{ 
    celda.cambiarElemento(matriz[i][j].nmina); 
    celda.copiarEn(i*15,j*15+35,monitor.ptr()); 


} 
else if(matriz[i][j].status==2) 
{ 
    celda.cambiarElemento(10); 
    celda.copiarEn(i*15,j*15+35,monitor.ptr()); 
} 

}
codigo donde esta todo el problema que tengo

Código:
int CBuscaminas::destapar(ClsTimer &cronometro,ClsSprite &celda,ClsMonitor &monitor,ClsEvento &evento) 
{ 
int h,z,estado; 

    for(int i=0;i<8;i++) 
    { 

        for(int j=0;j<8;j++) 
        { 
   // SDL_WarpMouse(i*15,j*15+35); 
    //pausa(); 
         if(evento.huboEvento()) 
          { 

            if(evento.tipo()==MOUSE_PRESIONADO) 
            { 
                 h=evento.mouseX(); 
                z=evento.mouseY(); 

          if(h>(i*15) && h<((i*15)+15) && z>((j*15)+35) && z<((j*15)+50) && evento.boton()==MOUSE_BOTON_IZQUIERDO) 
              { 
               matriz[i][j].status=1; 

                if(matriz[i][j].nmina==0) 
               { 
                AbrirCasillas(celda,monitor,i,j); 
               } 
                   if(matriz[i][j].nmina==9) 
                 { 
                    estado=1; 
                 } 
                 DibujaCasilla(celda,monitor,i,j); 
              }//if valida si esta en la celda correcta y aprete el boton izquierdo del mouse 

            }if valida si se presiono una tecla del mouse 
          }if valida si ocurrio un evento 
        }//for 


    }//for 
     monitor.refrescar(); 
        return estado; 
}
Para que entiendan mejor
Traduccion todas las funciones de SDL fueron guardadas en clases con funciones para que sea mas facil usar segun el Sensei

Funcion CambiarElemento
unsigned int ClsSprite::cambiarElemento(int elemento)
{
if (elemento >= imgTotal) return 702;
elementoActual = elemento;
return 0;
}
Funcion copiarEn
void ClsSprite::copiarEn(unsigned int X,
unsigned int Y,
SDL_Surface* sup
)
{
unsigned int ancho=sprite[elementoActual].imagen->w;
unsigned int alto=sprite[elementoActual].imagen->h;

SDL_Rect area = {X,Y,ancho,alto};
x=X;
y=Y;
SDL_BlitSurface(sprite[elementoActual].imagen, NULL, sup, &area);
}

Funcion huboEvento
bool ClsEvento::huboEvento()
{
if (SDL_PollEvent(&evento))
{
return true;
}
return false;
}
Funcion tipo
Uint8 ClsEvento::tipo()
{
return evento.type;
}
Funcion mouseX
Uint16 ClsEvento::mouseX()
{
return evento.button.x;
}
Funcion mouseY
Uint16 ClsEvento::mouseY()
{
return evento.button.y;
}
Funcion boton
Uint8 ClsEvento::boton()
{
return evento.button.button;
}
Funcion refrescar
void ClsMonitor::refrescar(){SDL_Flip(imagen);}
  #2 (permalink)  
Antiguo 08/11/2008, 10:22
Avatar de Xinef  
Fecha de Ingreso: marzo-2007
Mensajes: 202
Antigüedad: 17 años, 1 mes
Puntos: 7
Busqueda Respuesta: problemas con sdl y mouse

Lo siento, pero he sido incapaz de entender demasiado por el código que has puesto.

De todas formas, no entiendo por qué has metido el control de eventos dentro del método: destapar.

Te pongo por encima como lo haría yo... no tiene por qué ser la mejor forma, pero igual te sirve de algo:

Código PHP:
class Tablero {

    
Casillas **tablero;

public:

    
Tablero();
    ~
Tablero();
        
void setCasilla(Uint16 xUint16 yUint16 valor);
    
bool getValorCasilla(Uint16 xUint16 y);
    
bool quedanCasillasOcultas();

};


class 
Casilla {
    
//Constantes del tamaño de una casilla. Nos servirán para completar la
    //estructura "posicion".
    
const Uint16 TAMX;
    const 
Uint16 TAMY;
    
Sint8 valor;
    
//Puede ser interesante guardar la posición de la casilla para
    //comprobar si unas coordenadas de pulsación están dentro de la casilla.
    
SDL_Rect posicion;

        
SDL_Surface *imagenCasillaOculta;
        
SDL_Surface *imagenCasillaVisible;

        
//Está la casilla oculta o visible?
        
bool oculta;

public:
    
Casilla(Uint16 xUint16 yUint16 valor);
    
Uint16 getValor(void);
    
SDL_RECT getPosicion(void);
        
bool estaOculta(void);
};


int main(int nargchar **argv) {

    
SDL_Event evento;
    
bool terminar false;
    
    
Tablero tablero;

    
//[iniciamos tablero con las casillas... aleatoriamente.

    
while (SDL_PoolEvent(&evento) && !terminar) {
        switch(
evento.type) {
            case 
SDL_MOUSEBUTTONDOWN:
                
//Si hay una bomba en la casilla, terminar.
                
terminar tablero.getValorCasilla(evento.xevento.y);
                break;
        }

        
terminar tablero.quedanCasillasOcultas();
    }

    return 
0;


Es una especie de pseudocódigo con código. Es posible que tenga algún error, pero es una aproximación.

En la implementación luego puedes hacer lo que quieras, mostrar imágenes, etc, etc.

Por último, para ver si una coordenada colisiona con una casilla, sólo tienes que recorrer las casillas del tablero y preguntándole a cada una si esa coordenada la "mata".
  #3 (permalink)  
Antiguo 08/11/2008, 10:46
 
Fecha de Ingreso: mayo-2007
Ubicación: Buenos aires
Mensajes: 19
Antigüedad: 17 años
Puntos: 0
Respuesta: problemas con sdl y mouse

gracias Xinef por responder necesitaba alquien que conosca bien sdl
si no entiene el codigo aca lo dejo completo.
ya se que manejando bien las clases se puede hacer de otra forma mas facil el juego pero solo necesito saber porque solo funciona el mouse cuando hago click en la primer casilla 0,0 y en las demas no es un tema de que esta mal la funcion para validar la posicion del la casilla o porque el pollevent se satura de eventos o porque el for al volver hace que pollevent verifique eventos desde el principio y por funciona solo la primer casilla?

Código:
#include <iostream>
#include <conio.c>
#include "DMCS++.h" // Sistema DMCS++.
#include "random.h"

void pausa();

Uint8 mouse_b;
int h;
int z;

class CBuscaminas {
	public:
		CBuscaminas();
		~CBuscaminas();
		void CBuscaminas::AbrirCasillas(ClsSprite &,ClsMonitor &,int ,int);
		void ColocarMinas();
		int destapar(ClsTimer &,ClsSprite &,ClsMonitor &,ClsEvento &);
		void RecuentoMinas();
		void ContarMinas (int ,int);
		void DibujaTabla(ClsSprite &,ClsMonitor &);
		void DibujaCasilla(ClsSprite &,ClsMonitor &,int,int);

	public:

		struct Tcasilla {
			int nmina;
			int status;
		};
		typedef Tcasilla Tmatriz[11][11];

		Tmatriz matriz ;
};

CBuscaminas::CBuscaminas() {
	for (int i = 0; i < 8; i++) { // poner agua
		for (int k = 0; k < 8; k++) {
			matriz[i][k].nmina = 0;
			matriz[i][k].status =2;
		}
	}

	ColocarMinas();
	RecuentoMinas();
}

//Destructor
CBuscaminas::~CBuscaminas() {};

void CBuscaminas::AbrirCasillas(ClsSprite &celda,ClsMonitor &monitor,int posx,int posy){
    int i,j;
   	for (i=-1; i<=1; i++) {
		for (j=-1; j<=1; j++) {
		    //COMPRUEBA DE QUE NO SE SALE DE LA MATRIZ E INVADE ESPACIOS DE MEMORIA NO RESERVADOR
			if (posx+i>=0 && posx+i<=8-1 && posy+j>=0 && posy+j<=8-1 && matriz[posx+i][posy+j].status==2 ) {
			   //COMPRUEBA QUE LA CASILLA ESTE SIN LEVANTAR, QUE TENGA 0 MINAS Y QUE NO SEA ELLA MISMA
			   if(matriz[posx+i][posy+j].nmina == 0 && (i!=0 || j!=0)){
			         AbrirCasillas(celda,monitor,posx+i,posy+j);
			   }
               matriz[posx+i][posy+j].status=1;
			   DibujaCasilla(celda,monitor,posx+i,posy+j);
            }
		}
	}
}

void CBuscaminas::DibujaCasilla(ClsSprite &celda,ClsMonitor &monitor,int i,int j)
{
if(matriz[i][j].status==1)
{
    celda.cambiarElemento(matriz[i][j].nmina);
    celda.copiarEn(i*15,j*15+35,monitor.ptr());


}
else if(matriz[i][j].status==2)
{
    celda.cambiarElemento(10);
    celda.copiarEn(i*15,j*15+35,monitor.ptr());
}

}
void CBuscaminas::ContarMinas (int posx,int posy){
    int i,j;
   	for (i=-1; i<=1; i++) {
		for (j=-1; j<=1; j++) {
			if (matriz[posx+i][posy+j].nmina == 9 && (posx+i>=0 && posx+i<=8-1 && posy+j>=0 && posy+j<=8-1)) {
				matriz[posx][posy].nmina++;
			}
		}
	}

}
void CBuscaminas::ColocarMinas() {

  randomize();
	int i, k;
	int aux_mines = 10;    //colocar minas

	while (aux_mines != 0) {
		i = random(8);
		k = random(8);
		if (matriz[i][k].nmina != 9) {
			matriz[i][k].nmina = 9; //Number 9 means mine
			aux_mines--;
		}
	}
}

void CBuscaminas::RecuentoMinas() { //contar contactos
int i,j;
    for(i=0;i<9;i++){
        for(j=0;j<9;j++){
            if(matriz[i][j].nmina!=9){
                ContarMinas(i,j);
            }
        }
    }
}

void CBuscaminas::DibujaTabla(ClsSprite &celda,ClsMonitor &monitor)
{
for(int i=0; i<8; i++)
	 {
		for(int j=0; j<8; j++)
		{
		  DibujaCasilla(celda,monitor,i,j);
		}
	 }
}

int CBuscaminas::destapar(ClsTimer &cronometro,ClsSprite &celda,ClsMonitor &monitor,ClsEvento &evento)
{
int estado;

    for(int i=0;i<8;i++)
    {

        for(int j=0;j<8;j++)
        {
   // SDL_WarpMouse(i*15,j*15+35);
    //pausa();
         if(evento.huboEvento())
          {

            if(evento.tipo()==MOUSE_PRESIONADO)
            {
                 h=evento.mouseX();
                z=evento.mouseY();

              if(h>(i*15) && h<((i*15)+15) && z>((j*15)+35) && z<((j*15)+50) && evento.boton()==MOUSE_BOTON_IZQUIERDO)
              {
               matriz[i][j].status=1;

                if(matriz[i][j].nmina==0)
               {
                AbrirCasillas(celda,monitor,i,j);
               }
                   if(matriz[i][j].nmina==9)
                 {
                    estado=1;
                 }
                 DibujaCasilla(celda,monitor,i,j);
              }
              }
        }
        }//for


    }//for
     monitor.refrescar();
        return estado;
}
using namespace std;

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

   ClsDirectMedia modo;
  ClsDirectMediaError errorMSJ;
  ClsMonitor monitor;
  ClsEvento evento;
    ClsTimer cronometro;
  ClsSprite celda(12);

  int errorID;
  atexit(SDL_Quit);

  int estado=0,t=0;

  errorID=modo.iniciarVideo();
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }

    errorID=monitor.inicializar(640,480,16,HABILITADA,REDIMENSIONABLE);
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }

  celda.cambiarElemento(0);			//vetanja sdl no uso vectores
  errorID=celda.cargarImagen("casilla0.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
  celda.cambiarElemento(1);
  errorID=celda.cargarImagen("casilla1.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
  celda.cambiarElemento(2);
  errorID=celda.cargarImagen("casilla2.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
  celda.cambiarElemento(3);
  errorID=celda.cargarImagen("casilla3.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
  celda.cambiarElemento(4);
  errorID=celda.cargarImagen("casilla4.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
  celda.cambiarElemento(5);
  errorID=celda.cargarImagen("casilla5.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
  celda.cambiarElemento(6);
  errorID=celda.cargarImagen("casilla6.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
  celda.cambiarElemento(7);
  errorID=celda.cargarImagen("casilla7.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
  celda.cambiarElemento(8);
  errorID=celda.cargarImagen("casilla8.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
  celda.cambiarElemento(9);
  errorID=celda.cargarImagen("mina.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
  celda.cambiarElemento(10);
  errorID=celda.cargarImagen("casilla.pcx");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }
    celda.cambiarElemento(11);
  errorID=celda.cargarImagen("firma.jpg");
  if(errorID)
  {
    errorMSJ.mensaje(errorID);
    exit(errorID);
  }

  estado=0;              // Inicializa el estado del cronometro.
  cronometro.arrancar(); // Pone en marcha el cronometro.
 monitor.limpiar(NEGRO);

	CBuscaminas buscaminas; //

	buscaminas.DibujaTabla(celda,monitor);
	monitor.refrescar();



	while (t!=1)
	{

		t=buscaminas.destapar(cronometro,celda,monitor,evento);
	}


  errorID=0;
errorMSJ.mensaje(errorID);
  return errorID;
}


void pausa()
{
  bool fin=false;
  ClsEvento evento;
  while(!fin)
  {
    while(evento.huboEvento())
    {
       if(evento.tipo()==TECLA_PRESIONADA)fin=true;
    }
  }
}
  #4 (permalink)  
Antiguo 08/11/2008, 11:43
Avatar de Xinef  
Fecha de Ingreso: marzo-2007
Mensajes: 202
Antigüedad: 17 años, 1 mes
Puntos: 7
Respuesta: problemas con sdl y mouse

A ver.

Vamos a hacer pruebas porque es complicado seguir el código.

Antes de nada, saca el control de evento de los dos bucles. Quedaría más o menos así:

Código PHP:
int CBuscaminas::destapar(ClsTimer &cronometro,ClsSprite &celda,ClsMonitor &monitor,ClsEvento &evento)
{
int estado;

if(
evento.huboEvento())
          {

            if(
evento.tipo()==MOUSE_PRESIONADO)
            {
                 
h=evento.mouseX();
                
z=evento.mouseY();

 for(
int i=0;i<8;i++)
    {

        for(
int j=0;j<8;j++)
        {

              
//[...resto del código...]
    
}

Estabas haciendo una lectura de evento por cada redibujado.

Además, crea cuatro variables de control que muestren:
  • X ratón
  • Y ratón
  • (i*15)
  • ((i*15)+15)
  • ((j*15)+35)
  • ((j*15)+50)

Puede hacerlo con un simple std::cout.

Una vez que tengas la traza, comprueba que se están tomando bien las coordenadas de cada pulsación y que se cumple la condición del if (lo siento, pero con tanto número mágico me es imposible hacer la traza visualmente).


Si la clase Evento usa SDL_PollEvent, esta función de SDL ya hace el borrado del evento, si no usa esa función, tienes que sacar tú el evento que has leído de la cola.

Por cierto, presupongo que el método huboEvento hace la lectura de la cola de eventos... pero eso ya depende de esa clase... no es cosa de SDL.
  #5 (permalink)  
Antiguo 08/11/2008, 12:12
 
Fecha de Ingreso: mayo-2007
Ubicación: Buenos aires
Mensajes: 19
Antigüedad: 17 años
Puntos: 0
De acuerdo Respuesta: problemas con sdl y mouse

gracias Xinef ahora toma los clicks del mouse.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:42.