Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problema al crear juego de futbol en 2d

Iniciado por Dirfinyu, 29 de Noviembre de 2011, 08:41:49 PM

« anterior - próximo »

Dirfinyu

Saludos a todos!!
A ver si algun programador experto me puede ayudar, explico el problema a ver si se entiende bien.
Estoy creando un juego para wii(en C, aunque para esto el lenguaje no importa), es un juego de futbol en 2D. En él, el campo de futbol es un png que mide 1024x424(1024es el máximo permitido), y lo primero que hago es dibujarlo aumentando un 20% su tamaño, lo voy dibujando parte a parte:
DrawPart (0, 0, PosX-250, PosY-250, 640,480, tex_estadio, 0, 1.2, 1.2, WHITE);
PosX y PosY son las coordenadas que determinan que parte se muestra.

Despues dibujo los jugadores(3):
if (PtInRect(0,0,640,540,x[1],y[1])) GRRLIB_DrawTile(x[1], y[1], tex_mm, 0, 2, 2, WHITE, Jugadores.frame[1]);
if (PtInRect(0,0,640,480,x[2],y[2])) DrawTile(x[2], y[2], tex_bo, 0, 2, 2, WHITE, Jugadores.frame[2]);
if (PtInRect(0,0,640,480,x[3],y[3])) DrawTile(x[3], y[3], tex_go, 0, 2, 2, WHITE, Jugadores.frame[3]);

Como veis multiplico el tamaño del jugador x2 y las coordenadas x e y sale de un sencillo calculo hecho anteriormente:
for(i=1; i <4; i++) {
x[i]=Jugadores.bgx[i]+PosX; y[i]=Jugadores.bgy[i]+PosY;
}

bgx y bgy son las coordenadas de los jugadores.

Y finalmente dibujo el balón:
XBalon=bgx2+PosX; YBalon=bgy2+PosY;
if (PtInRect(0,0,640,480,XBalon,YBalon)) DrawImg(XBalon, YBalon, tex_balon, 0,1.5, 1.5, WHITE);

Como veis multiplico el tamaño por 1,5, y lo muestro solo si esta visible en la pantalla de juego(que en wii la resolucion es 640x480, al igual que los jugadores).

Como observais todo se centra en PosX y PosY que delimitan qué parte del campo se muestra. Pongo un ejemplo de lo que hago al mover el jugador a la derecha:

if(wpadheld & WPAD_BUTTON_DOWN) {
if (CapiBalon >0) {
if (PosX < XC2) {
Jugadores.bgx[JugadorSeleccionado] -=3;
bgx2 = Jugadores.bgx[JugadorSeleccionado];
PosX+=3;
}
}
else {
Jugadores.bgx[JugadorSeleccionado] +=3;
}
           Jugadores.direction_new[JugadorSeleccionado] = TILE_RIGHT;
}

WPAD_BUTTON_DOWN determina que el jugador va hacia la derecha. XC2 el maximo que puede avanzar. Lo que hago aquí es mover el jugador y no la pantalla si no tiene el balon, y si lo tiene es donde ejecuto esto:
Jugadores.bgx[JugadorSeleccionado] -=3;
bgx2 = Jugadores.bgx[JugadorSeleccionado];
PosX+=3;

Osea situo siempre el balón en el centro de la imagen.

El problema que me estoy encontrando es que si te mueves hacia la derecha con el balon, el jugador que tiene la posesion cumple todo perfecto, pero el resto de jugadores no varian su bgx ni bgy pero siempre son visibles en la pantalla, se renderizan en la misma posicion del televisor. He probado a ajustar sus coordenadas al mover de esta manera:
if (CapiBalon >0) {
if (PosX < XC2) {
Jugadores.bgx[JugadorSeleccionado] -=3;
Jugadores.bgx[2] -=6;
Jugadores.bgx[3] -=6;
bgx2 = Jugadores.bgx[JugadorSeleccionado];
PosX+=3;
}

Pero no se quedan totalmente quietos, ni con -6,-5,-7 ni ninguno(el -6 es el que mas quietos los dejan, aunque te siguen un poco mas lento).

Otro problema grave que da esto es al disparar, que los ejes se vuelven locos y hay que estar recolocando y eso queda fatal. por ejemplo disparo a puerta, el balon entra y tengo que colocar despues el balon otra vez(queda en la linea de meta). Ademas da problemas en relacion a la PosX y el resto. Loslimites son xmin=0 xmax=800 ymin=0 ymax=410. Esos limites obviamente siempre se cumplen pero según la posicion de disparo PosY y PosX se mueven tan mal que si antes xmin, te situabas en la banda superior, al disparar muchas veces xmin se situa mucho mas arriba de la banda superior o mucho mas abajo.
En definitiva hay desajustes por todos lados y creo que es imposible ajustarlo al 100%, y eso que aun no me he metido en tema pases, paradas del portero, rechaces...

Espero que se entienda más o menos bien.

Mi pregunta es:
¿estoy enfocandolo bien?
¿como lo hariais vosotros?
¿Se puede conseguir esto?:
Crear un campo(vector) asi
0/0///////////////////////////////////////////////////////////////////////////////////1024/0
/                                                                                       /
/                          /////////////////////                                        /
/                          /  Camara  /                                        /
/                          /  Camara  /                                        /
/                         /////////////////////                                         /
/                                                                                       /
/                                                                                       /
/                                                                                       /
/                                                                                       /
0/424//////////////////////////////////////////////////////////////////////////////1024/424
Y que la camara que mide 640, 480 se fuera moviendo??una cosa importante seria que las coordenadas del balon no siempre estarian en el centro pero el balon siempre sería visible.
Si se puede como sería??

Muchisimas gracias a todos!

Gallo

Te recomendaria crear una serie de funciones y estructuras para controlar correctamente la escena (un sceneGraph), separado de la gestión del input del jugador. Todos los elementos deberían tener una posición en el mundo que actualizas con la lógica del juego y relativa al centro de coordenadas, entonces en cada frame tienes que enviarlos a pintar transformados según la vista del jugador (así es como se hacen las "camaras"), es la tipica modelView matrix (sin proyección por ser 2D), busca algo de información sobre el tema e inteta crear un modulo a parte solo para gestionar este tipo de cosas.

Si lo haces de la forma actual, que parece bastante rudimentaria, a parte de ser un lio realmente no estas entendiendo lo que pasa en al escena, se que lo de las matrices de transformacón puede sonar a chino o a "yo no necesito eso", pero es necesario emplearlo. Mi consejo seria que lo pasaras a C++ para aplicar los conceptos de "objetos de la escena" con mas facilidad, aunque tu veras.


shephiroth

Tu problema fundamentas es intentar crear una lógica partiendo de lo que se ve en pantalla. Esto es a largo plazo, imposible de sustentar.

Intenta crearte una lógica sin cámara, como si el juego corriera en segundo plano y solo te interesase el resultado. Una vez tengas la lógica, desarrolla una funcion donde se dibuje en pantalla la zona del campo donde se encuentra la pelota. Y por último, intenta añadir a la lógica (y siempre despues de la lógica del juego) para que la cámara siga la pelóta de una manera realista.

Tu ciclo de vida tendría q ser algo como:

logicaJuego();
logicaCamara();
dibujarCamara();

Dirfinyu

#3
Muchísimas gracias a los 2 por las respuestas!!!
Gallo, no puedo pasarlo a c++, la libreria que uso para wii no es compatible.
Voy a probar a hacer lo que decis, un modulo a parte y que lso sucesos del juego ocurran ahi, despues mirare como renderizarlo.
os voy contando a ver como queda

EDITO:
¿sabeis lo que me ha pasado?no se si os sonará. Te empeñas en programar de una manera y estas encabezonado que no hay otra solucion(aunque en realidad sabes que debe haberla). Buscas soluciones y no las encuentras.
Es tan sencillo como deciais, lo dejo aquí escrito por si alguien alguna vez se obceca tanto como yo.
En un modulo a parte (para verlo mas claro) :

int xmundo,ymundo,xmundomax=1229,ymundomax=508,xmundopos=0,ymundopos=0;
int balx,baly;
struct Jugador {

int frame[10], direction[10],direction_new[10];// = TILE_DOWN;
int bgx[10], bgy[10];

unsigned int wait[10];
};

struct Jugador Jugadores;


void Initgame(void) {
xmundopos=235,ymundopos=10;
balx=555,baly=180;
Jugadores.bgx[1]=460; Jugadores.bgy[1]=165;
Jugadores.bgx[2]=330; Jugadores.bgy[2]=340;
Jugadores.bgx[3]=405; Jugadores.bgy[3]=40;

}


void Setcamera(void) {
if ((baly<87) & (baly>0)) ymundopos= baly-76;
if ((baly>324) & (baly<405)) ymundopos= baly-314;
if ((baly<=324) & (baly>=87)) ymundopos= 10;
if ((balx<391) & (balx>=87)) xmundopos= balx-156;
if ((balx>=391) & (balx<=650)) xmundopos= 235;
if ((balx>=650) & (balx<=1220)) xmundopos=balx-415;
}


Tengo una matriz de 1229x508 y situo en ella jugadores y pelota. La funcion setcamera mueve la camara para que el balon siempre sea visible, pero este no debe permanecer en el centro.
Para renderizar?sencillisismo:
DrawPart (0, 0, xmundopos-50, ymundopos-40, 640,480, tex_estadio, 0, 1.2, 1.2, WHITE);
//if(RectOnRect(x[1], y[1], 40, 40, 0, 0, 640, 480)) DrawTile(x[1], y[1], tex_mm, 0, 2, 2, WHITE, Jugadores.frame[1]);
if (PtInRect(xmundopos-50,ymundopos-40,640,520,Jugadores.bgx[1],Jugadores.bgy[1])) DrawTile(Jugadores.bgx[1]-xmundopos, Jugadores.bgy[1]-ymundopos, tex_mm, 0, 2, 2, WHITE, Jugadores.frame[1]);
if (PtInRect(xmundopos-50,ymundopos-40,640,520,Jugadores.bgx[2],Jugadores.bgy[2])) DrawTile(Jugadores.bgx[2]-xmundopos, Jugadores.bgy[2]-ymundopos, tex_bo, 0, 2, 2, WHITE, Jugadores.frame[2]);
if (PtInRect(xmundopos-50,ymundopos-40,640,520,Jugadores.bgx[3],Jugadores.bgy[3])) DrawTile(Jugadores.bgx[2]-xmundopos, Jugadores.bgy[3]-ymundopos, tex_go, 0, 2, 2, WHITE, Jugadores.frame[3]);

Y lo mismo con el balón y otros elementos.
Al mover se hace mas sencillo:

     if(wpadheld & WPAD_BUTTON_DOWN) {
if (CapiBalon >0) {
if (PosX < XC2) {
Jugadores.bgx[JugadorSeleccionado] +=3;
balx = Jugadores.bgx[JugadorSeleccionado];
}
}
else {
Jugadores.bgx[JugadorSeleccionado] +=3;
}
            Jugadores.direction_new[JugadorSeleccionado] = TILE_RIGHT;
}


Muchas gracias a los 2 por que he logrado ver el error en seguida!!

Gallo

#4
No entiendo lo de que la librería no es compatible con C++, quizá no puedas pasarle objetos de C++ como parámetros a las funciones, pero podrías orientarla un poquito a objetos creando algunos wrappers con métodos a los que les pasas tus objetos per sustraes la información necesaria, para pasarla a las funciones de esa lib. En si el int, el float y el char* siempre estarán ahí para los datos, tanto en C como en C++.

Por ejemplo yo he utilizado LUA con Objective-C y C++, y lua es puro C.

Dirfinyu

Si, el principal problema es que no domino mucho c+. Y no tengo ejemplos para wii para verlos.
En principio con c es suficiente, mas tarde puedo optimizarlo con c+

[EX3]

#6
Cita de: Dirfinyu en 01 de Diciembre de 2011, 04:08:43 PM
En principio con c es suficiente, mas tarde puedo optimizarlo con c+
Mas que optimizar... seria reprogramar por completo el juego. Nada tiene que ver como lo estas programando ahora a como seria programarlo orientandolo a objetos.

Ejemplos de Wii no, mas bien deberias simplemente aprender C++ y orientacion a objetos ya que te seriviria para hacer lo que te comenta Gallo, encapsular muchas llamadas y logica de esa libreria en objetos faciles de manejar y gestionar. Ahi da igual que la libreria este o no orientada a objetos :)

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

[EX3]

José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Gallo

Despues de las respuestas y tal creo que te faltaria asimilar algunos conceptos sobre programación. Para empezar este nivel que muestras ya indica que mucho sobre sistemas embebidos no debes saber y hay cosas importantes en la wii como lag estión de memoria y esas cosas, que realmente son aplicables a cualquier sistema (otras consolas, mobiles, tablets, etc..) pero que en un PC pues no se suelen tener en cuenta a la hora de aprender por que el PC se lo traga todo.

Mi consejo es que amplíes tus conocimientos, está bien irlo haciendo con un juego, pero creo que la base ha de ser mas amplia y sobretodo no hacerlo tal como sabes ahora por que lo consideres suficiente, siempre lo puedes mejorar. C++ no es una versión mejorada u optimizada de C, casi todo lo contrario, simplemente añade funcionalidad para la orientación a objetos, super útil cuando hablamos de un juego y super útil también en un game engine.

Si lo prefieres sigue con C pero no descuides el tema de la gestión de memoria y el uso correcto de la API gráfica. Saludos!

Dirfinyu

Muchas gracias por los comentarios EX3.

Y muchas gracias por los consejos Gallo. Que no conozca c++, solo implica que no se c++. La gestion de la memoria en wii y el uso de su Api grafica las domino perfectamente. Simplemente que no se c++, aunque es cierto que tengo que aprenderlo y que me va a ser util y necesario.

Muchas gracias de nuevo!

josepzin


Mars Attacks

Me parece aún más interesante saber por qué hacer algo para la Wii hoy en día :)

Dirfinyu

Cita de: Mars Attacks en 03 de Diciembre de 2011, 12:03:14 AM
Me parece aún más interesante saber por qué hacer algo para la Wii hoy en día :)
Jejej, hombre hecho para wii, es facil pasarlo a pc, ps3,xbox...es que yo solo tengo la wii. Y es paea una idea que hace tiempo llevo pensando.

Gallo

#13
Cita de: Mars Attacks en 03 de Diciembre de 2011, 12:03:14 AM
Me parece aún más interesante saber por qué hacer algo para la Wii hoy en día :)

Tu sabes el currículum que da que hayas hecho un juego para Wii (o cualquier consola) por tu cuenta? tiene mas valor que muchos que los estudios o experiencia en programación de videojuegos en PC. Eso si, siempre y cuando lo que hayas hecho funcione como es debido.

Por cierto, si que igual tengo en un orden diferente los conocimientos que hay que ir teniendo para programar en consola. También ocurre que yo tiro mucho de templates para crear memory allocators y para prácticamente todas las marcianadas que se me ocurran, de ahí que tenga muy interrelacionado que C++ es tan necesario, a veces es un peligro llevar mucho tiempo usando la OO casi exclusivamente, hoy en dia se me haría imposible diseñar una lib  o un framework o lo que sea, solo con C stubs, vamos acabaria haciendo structs con punteros a funciones continuamente para simular objetos, jeje.

Mars Attacks

Cita de: Gallo en 03 de Diciembre de 2011, 11:35:05 AM
Cita de: Mars Attacks en 03 de Diciembre de 2011, 12:03:14 AM
Me parece aún más interesante saber por qué hacer algo para la Wii hoy en día :)

Tu sabes el currículum que da que hayas hecho un juego para Wii (o cualquier consola) por tu cuenta?

Precisamente la pregunta era "¿y por qué no para cualquier otra consola o dispositivo móvil?" La Wii está bastante enterrada ya (Nintendo se autocubrió de gloria en el acceso a las third parties). Hoy en día veía mucho más asequible programar para XBLIG o Android, de ahí mi pregunta.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.