Pong C++/SDL

Pong C++/SDL

Notapor Juanxo » Jue Jun 25, 2009 11:38 pm

Buenas a todos:

He hecho un pong en C++/ SDL para conocer un poco todo el tema de SDL en C++ y cosas así (yo hasta ahora solo conocía pygame), pero tengo un problemilla.
Todo funciona más o menos, excepto las colisiones stick-ball ( definidas en Ball.h y Ball.cpp) en las que he empleado la función de la siguiente página

Además, otro pequeño error es que cuando detecta una colisión con las paredes de la pantalla, he de modificar la posición de la bola un pixel, haciendo que deje de estar en contacto con la pared, porque si no se queda constantemente modificando la velocidad. Alguien sabe como subsanarlo.

El archivo lo podéis descargar de aquí

Un saludo y gracias a todos
Última edición por Juanxo el Mié Jul 01, 2009 3:42 am, editado 2 veces en total
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: Pong C++/SDL

Notapor endaramiz » Sab Jun 27, 2009 2:07 pm

Juanxo escribió:Además, otro pequeño error es que cuando detecta una colisión con las paredes de la pantalla, he de modificar la posición de la bola un pixel, haciendo que deje de estar en contacto con la pared, porque si no se queda constantemente modificando la velocidad. Alguien sabe como subsanarlo.

A ver si así te funciona:
Código: Seleccionar todo
if (rect.y + vy >= 0 and rect.y + rect.y + vy < SCREEN_H) rect.y += vy;
else vy = -vy;

De esta manera también se evita un efecto no deseado al hacer el blit, que modifica el rectángulo.
Faltaría mirar si sale por la izquierda o por la derecha, pero como eso incrementa los puntos, ya es otra cosa.

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

Notapor Juanxo » Sab Jun 27, 2009 3:27 pm

Código: Seleccionar todo
rect.y + rect.y + vy


uno de estos es rect,w no? esque si no no entiendo porque lo haces

Gracias de todas formas, lo voy a mirar
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor endaramiz » Sab Jun 27, 2009 8:41 pm

Si si, exacto. Lo había escrito con un poco de prisa.
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Notapor Juanxo » Mié Jul 01, 2009 3:52 pm

Buenas:

Gracias endaramiz por las soluciones. Ya he conseguido que todo funcione.

Ahora estoy tratando de hacer un marcador, pero me da error de segmentacion cuando intento hacer el render.

La verdad es que he probado bastantes cosas para ver si funcionaba char, char [] const char*, con sprintf, pero me sigue dando el mismo error.

Si me podéis guiar un poco os lo agradecería, porque he estado mirando ejemplos en internet, pero todos o casi todos son de texto, no de números

El código de la función es:

Código: Seleccionar todo
void Score::RenderText()
{

    //Create the text
    char msg[1];
    sprintf(msg, " %d" , N1);

    //Render to surface
    S1 = TTF_RenderText_Shaded(Font,msg,TColor,BColor);
    //Optimize the image, assigning the same format that the screen

    Rect1.w = S1 -> w;
    Rect1.h = S1 -> h;

    //Apply colorkey
    SDL_SetColorKey(S1,SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(S1->format,0,0,0));

}


N1, S1, Font, TColor, BColor y Rect son miembros de la clase

Gracias
Juanxo
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Geo » Mié Jul 01, 2009 5:10 pm

¿De qué tipo es N1? A primera vista, la variable msg no podrá contener lo que quieras copiarle con sprintf pues la has declarado de un solo caracter ¿?, por ejemplo, si N1 se trata de un entero, probablemente sea de 16 bits o, incluso de 32, eso definitivamente no cabrá en la variable msg, intenta darle más espacio:

Código: Seleccionar todo
char msg[ 16 ];

Ten en cuenta el número de dígitos que puede tener tu variable N1 (contando el signo, si es el caso), además del espacio que utilizas en la llamada a sprintf, como mínimo deberías tener esos caracteres + uno para el caracter de fin de cadena.
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Notapor Juanxo » Jue Jul 02, 2009 3:47 pm

Gracias Geo, he hecho lo que me has comentado( al final los he hecho de 32) y ahora si han funcionado.
Lo único que esta manera me parece un poco rebuscada. Es la única o se puede hacer de una manera mejor?

Por cierto, alguien que este con linux y me diga como hacer el profile de un proyecto SDL en el gcc. Me da error ya dice que no encuentra las funciones de SDL, pero yo lo he probado con el codeblocks(ahi es donde programo) y lo ejecuta sin ningún problema.
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Geo » Vie Jul 03, 2009 3:39 am

Juanxo escribió:Gracias Geo, he hecho lo que me has comentado( al final los he hecho de 32) y ahora si han funcionado.
Lo único que esta manera me parece un poco rebuscada. Es la única o se puede hacer de una manera mejor?

¿Te refieres al tamaño con que declaras la variable? Claro, aprovecha que estás en C++ y usa la clase string :D. Otra forma, es hacer un estimado del número de dígitos que necesitarás de acuerdo al número de bytes de la variable. Un ejemplo muy malo:

Código: Seleccionar todo
char msg[ sizeof( int ) * 3 + 1 ];

Con sizeof se obtiene el número de bytes del tipo int, se multiplica por 3 considerando que por cada byte haremos uso de tres dígitos, se suma 1 para garantizar que tenemos espacio para el caracter de fin de cadena, es una aproximación que puede servir:

1 byte: 255 => 3 dígitos (se reservan 4 caracteres)
2 bytes: 65536 => 5 dígitos (7)
3 bytes: 16,777,216 => 8 dígitos (10)
4 bytes: 4,294,967,296 => 10 dígitos (13)

Ahora, cuidado con el caso de 1 byte para cuando sean variables con signo, podría usar un dígito más y no alcanzar. Debe haber una forma más efectiva ("elegante") de calcular cuántos dígitos se tienen para X bytes, pero ahorita no la recuerdo :P.

Juanxo escribió:Por cierto, alguien que este con linux y me diga como hacer el profile de un proyecto SDL en el gcc. Me da error ya dice que no encuentra las funciones de SDL, pero yo lo he probado con el codeblocks(ahi es donde programo) y lo ejecuta sin ningún problema.

¿Profile? ¿a qué te refieres?
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Notapor Juanxo » Vie Jul 03, 2009 11:29 am

¿Te refieres al tamaño con que declaras la variable? Claro, aprovecha que estás en C++ y usa la clase string


Si, me refería al tamaño de posiciones del array. Para que cupiesen dos numeros (enteros de 16bits, necesito 2 enteros = 32 bits).

En cuanto a lo de string, esque no sabía si funcionaría, porque el tipo que acepta SDL es const char* y no se si no habría problemas con los tipos.
Probaré haber.

En cuanto a lo de Profile, me refería a usar el profiler de gcc, que te muestra estadísticas del tiempo empleado en funciones y demás, para ver en que puntos puedo intentar atacar más la optimización

Gracias por todo Geo.
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Geo » Sab Jul 04, 2009 3:24 am

Juanxo escribió:
¿Te refieres al tamaño con que declaras la variable? Claro, aprovecha que estás en C++ y usa la clase string


Si, me refería al tamaño de posiciones del array. Para que cupiesen dos numeros (enteros de 16bits, necesito 2 enteros = 32 bits).

En cuanto a lo de string, esque no sabía si funcionaría, porque el tipo que acepta SDL es const char* y no se si no habría problemas con los tipos.
Probaré haber.

Recuerda que la clase string tiene el método c_string() que te devuelve un puntero a char para usar con funciones que esperan cadenas "tipo C".

Juanxo escribió:En cuanto a lo de Profile, me refería a usar el profiler de gcc, que te muestra estadísticas del tiempo empleado en funciones y demás, para ver en que puntos puedo intentar atacar más la optimización

Aaah, ya entendí :P. No se, eso lo hago con Visual Studio :P. Espero que cuando le encuentres (o alguien más comente) lo compartas :).

Juanxo escribió:Gracias por todo Geo.

Por nada, recuerda que estamos para compartir :).
Aaah, y otra cosa, la mejor manera de agradecer es compartiendo, y cuando sea el turno, te toca echar la mano :D.
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Notapor Juanxo » Sab Jul 04, 2009 5:10 pm

gracias por lo del String. Lo miraré haber que tal.

Espero que cuando le encuentres (o alguien más comente) lo compartas


jajaja. Pues lo encontré. Haber, la manera de conseguir ejecutar el profiler en modo consola es el siguiente:

Código: Seleccionar todo
juanxo@Juanxo:~/Pruebas/pruebas$ g++ -o main -pg main.cpp
juanxo@Juanxo:~/Pruebas/pruebas$ ./main
juanxo@Juanxo:~/Pruebas/pruebas$ gprof main


la primera linea genera la salida del programa en el archivo que va a continuación del parámetro -o. -pg indica al compilador que ejecute el profiler cuando compile y finalmente ponemos el nombre del archivo a compilar.

en la segunda linea ejecutamos el archivo de salida y nos muestra la salida del programa.
y por último, ejecutamos el profiler en el archivo de salida y se nos mostrará las estadísticas.

Problemas: A pesar de tenerlo linkado en el proyecto del codeblocks, al compilar en la consola me da un error como que no reconoce las funciones de SDL.

Seguiré estudiandolo.

Aaah, y otra cosa, la mejor manera de agradecer es compartiendo, y cuando sea el turno, te toca echar la mano Very Happy.


Temer el día en que eso ocurra, porque para que yo os pueda ayudar en algo el mundo se tendría que haber vuelto loco xD (esperemos que no sea cierto) :P
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor endaramiz » Dom Jul 05, 2009 3:01 pm

Juanxo escribió:
Código: Seleccionar todo
juanxo@Juanxo:~/Pruebas/pruebas$ g++ -o main -pg main.cpp
juanxo@Juanxo:~/Pruebas/pruebas$ ./main
juanxo@Juanxo:~/Pruebas/pruebas$ gprof main


Problemas: A pesar de tenerlo linkado en el proyecto del codeblocks, al compilar en la consola me da un error como que no reconoce las funciones de SDL.

Si el código que has puesto utiliza SDL, no te olvides de poner el -lSDL:
Código: Seleccionar todo
g++ -o main -pg main.cpp -lSDL


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

Re: Pong C++/SDL

Notapor yasser_001200 » Jue Sep 03, 2009 6:16 pm

endaramiz escribió:
Juanxo escribió:Además, otro pequeño error es que cuando detecta una colisión con las paredes de la pantalla, he de modificar la posición de la bola un pixel, haciendo que deje de estar en contacto con la pared, porque si no se queda constantemente modificando la velocidad. Alguien sabe como subsanarlo.

A ver si así te funciona:
Código: Seleccionar todo
if (rect.y + vy >= 0 and rect.y + rect.y + vy < SCREEN_H) rect.y += vy;
else vy = -vy;

De esta manera también se evita un efecto no deseado al hacer el blit, que modifica el rectángulo.
Faltaría mirar si sale por la izquierda o por la derecha, pero como eso incrementa los puntos, ya es otra cosa.

Saludos.



NO sería mejor sumar la posición y con el alto y la posición x con el ancho, asi:
rect.y+rect.h+vy<SCREEN_H

Si se tratase de colisión con las paredes sería:

if rect.x<=0 then
vy=vy*-1
Asi la velocidad sería negativa y la bola iría al lado contrario.
En flash me sale así y me va bien. El problema es cuando aumenta la velocidad
Vienbeni2 a mi mundo....WAJAJAJAJAJA
yasser_001200
 
Mensajes: 46
Registrado: Lun May 19, 2008 3:28 pm


Volver a Videojuegos

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados

cron