PDA

Ver la versión completa : 2xTron v0.1



cdrman
27/06/2006, 07:54
Pues bueno, acabo de realizar la primera versión de mi juego de Tron para gp2x. De momento la IA no es demasiado "inteligente", por lo que no resulta demasiado difícil ganarla. Es una versión preliminar pero que es totalmente jugable.

En futuras versiones se corregiran algunos bugs que tiene, se mejorará la interfície, se añadirá una nueva IA, y además intentaré hacer algun modo online, con el que podamos jugar entre nosotros.
Además al realitzarlo con SDL también pondré a disposición la versión pc con la que se puede jugar perfectamente, de esta forma podríamos probar la comunicación gp2x - pc.

PD: La versión PC requiere algunas dll's en el directorio donde se descomprima el juego.

cdrman
27/06/2006, 08:17
Aquí están las librerías.

cdrman
27/06/2006, 08:50
Hola, tengo problemas de velocidad. En el pc todo va ok pero en la gp2x va bastante lento. La rutina que hace que todo vaya lento es la de pintar los objetos por pantalla.

Si alguien puede decirme como optimizarla un poco aquí dejo el código:

void Game::ShowGame()
{
int xorig = 160;
int yorig = -150;
int auxx = 160;
int auxy = -150;


for(int i=Player1Act.X-31; i<Player1Act.X+31; i++)
{
for(int j=Player1Act.Y-31; j<Player1Act.Y+31; j++)
{
if ((i>=0)&&(i<MAXX)&&(j>=0)&&(j<MAXY))
{

if (i>MAXX || j>MAXY) break;

//if ((i==0)||(i==MAXX-1)||(j==0)||(j==MAXY-1))
DrawSprite(screen, isometric3 , 0, 0, xorig, yorig, 15, 16);

switch(board[i][j])
{
case PLAYER:
DrawSprite(screen, isometric1 , 0, 0, xorig, yorig, 15, 16);
break;

case CPU:
DrawSprite(screen, isometric2 , 0, 0, xorig, yorig, 15, 16);
break;

case PATH_CPU:
DrawSprite(screen, isometric2 , 0, 0, xorig, yorig, 15, 16);
break;

case PATH_PLAYER:
DrawSprite(screen, isometric1 , 0, 0, xorig, yorig, 15, 16);
break;
}
}
xorig-=7;
yorig+=4;
}
auxx+=7;
auxy+=4;
xorig=auxx;
yorig=auxy;
}
}

void DrawSprite(SDL_Surface * screen, SDL_Surface* imageSurface,int srcX, int srcY, int dstX, int dstY, int width, int height)
{
SDL_Rect srcRect;
srcRect.x = srcX;
srcRect.y = srcY;
srcRect.w = width;
srcRect.h = height;

SDL_Rect dstRect;
dstRect.x = dstX;
dstRect.y = dstY;
dstRect.w = width;
dstRect.h = height;

SDL_BlitSurface(imageSurface, &srcRect, screen, &dstRect);
}

Lo que hago es recorrer el array y mostrar el estado, nada más.

Logann
27/06/2006, 13:42
Ahora no puedo mirar como funciona el juego (ni windows ni gp2x), pero tal vez deberias pensar en pintar el fondo como un dibujo uniforme, todo directamente mapandolo desde una imagen de 340x280 por ejemplo en lugar de cada vez:

DrawSprite(screen, isometric3 , 0, 0, xorig, yorig, 15, 16);

ya que son muchos sprits ._.

cdrman
27/06/2006, 17:54
A ver si alguien tiene alguna idea maravillosa para que pueda obtener bastante más velocidad. He intentado no pintar el tierra para conseguir más velocidad, pero igualmente se realentiza cuando hay bastantes cuadros en pantalla. Alguna idea¿

Logann
27/06/2006, 18:46
Meterle frameskip 1 seria demasiado :?

cdrman
27/06/2006, 18:49
Tiene autoframeskip. Se adapta a la velocidad. El problema es el pintar tantos cuadros. No veo forma de que no se pinten tantos.

miq01
27/06/2006, 18:52
Sin haberlo probado, hay algo que sí puedes optimizar, aunque no estoy seguro de que mejore mucho el rendimiento (igual el compilador lo optimiza por ti).

En este bucle


for(int i=Player1Act.X-31; i<Player1Act.X+31; i++)
{
for(int j=Player1Act.Y-31; j<Player1Act.Y+31; j++)
{
...
}
}
no es necesario declarar la j dentro del bucle.

Podrías hacer


int j;
for(int i=Player1Act.X-31; i<Player1Act.X+31; i++)
{
for(j=Player1Act.Y-31; j<Player1Act.Y+31; j++)
{
...
}
}
y así evitas que se reserve (y después se libere) memoria para j tantas veces como vueltas da el bucle de la i (¿62 veces?). De esta manera solo se reserva y libera una vez.

ArChEr
27/06/2006, 21:17
Pues para que te valla mas rapido puedes utilizar punteros, en vez de tener un array[640][480] podrias tener un array[640*480] y hacer el bucle que dibuja con punteros, en isometrico no lo e probado pero es la misma tecnica que para dibujar un bitmap y con punteros va mucho mas rapido, un saludo y suerte con este juego te esta quedando muy bien :)

< - >
Tambien puedes hacer un array de bitmaps con los sprites por ejemplo isometric[3] y poner directamente solo un DrawSprite(screen, isometric[board[i][j]] , 0, 0, xorig, yorig, 15, 16);

Asi no haces tantos if en cada ciclo simplemente poniendo eso sin ningun if ya te dibujara el sprite correspondiente :)

Si a esto le sumas lo de los punteros que te comentado arriba pues ya tendras bastante mas velocidad y seguro que te va bien :)

una-i
28/06/2006, 05:18
Esta es la versio primera...


void Game::ShowGame()
{
int xorig = 160;
int yorig = -150;
int auxx = 160;
int auxy = -150;


int temps1 = SDL_GetTicks();
int i,j;

int renderXMin = MAX(Player1Act.X-31,0);
int renderXMax = MIN(Player1Act.X+31,MAXX);
int renderYMin = MAX(Player1Act.Y-31,0);
int renderYMax = MIN(Player1Act.Y+31,MAXY);

for(j=renderYMin; j<renderYMax; j++)
{
for(i=renderXMin; i<renderXMax; i++)
{
DrawSprite(screen, isometric[board[i][j]] , 0, 0, xorig, yorig, 15, 16);
xorig-=7;
yorig+=4;
}
auxx+=7;
auxy+=4;
xorig=auxx;
yorig=auxy;
}
int temps2 = SDL_GetTicks();
printf("Temps en pintar: %d\n", temps2-temps1);
}


Para hacer que recorrar el array "como debe"
cambiamos los for


for(i=renderXMin; i<renderXMax; i++)
{
for(j=renderYMin; j<renderYMax; j++)
{
}
}


Pero no vale solo eso como antes haciamos unos incrementos hay que hacer que lso incrementos vayan "como antes"

y el codigo podria set tal que asi...



// Mostramos tablero
void Game::ShowGame()
{
int xorig = 160; int yorig = -150; int auxx = 160; int auxy = -150;
int temps1 = SDL_GetTicks();
int i,j;

int renderXMin = MAX(Player1Act.X-31,0);
int renderXMax = MIN(Player1Act.X+31,MAXX);
int renderYMin = MAX(Player1Act.Y-31,0);
int renderYMax = MIN(Player1Act.Y+31,MAXY);

for(i=renderXMin; i<renderXMax; i++)
{
for(j=renderYMin; j<renderYMax; j++)
{
DrawSprite(screen, isometric[board[i][j]] , 0, 0, xorig, yorig, 15, 16);
xorig+=7;
yorig+=4;
}
auxx-=7;
auxy+=4;
xorig=auxx;
yorig=auxy;
}
int temps2 = SDL_GetTicks();
printf("Temps en pintar: %d\n", temps2-temps1);
}


Como optimizacion podriamos sacar un puntero a la "linea! que vamso a recorrer y no indexa doblemente en el array todo el tiempo.

Esto es un esquam he quitado todo lo que no "importa".


for(i=renderXMin; i<renderXMax; i++)
{
char* pDatos = &board[i][0]; // no se que tipo es board...
for(j=renderYMin; j<renderYMax; j++)
{
DrawSprite(screen, isometric[pDatos[j]] , 0, 0, xorig, yorig, 15, 16);
}
}



P.D: esto es todo lo que se me ocurre el unico otro factor de consumo de tiempo que se me ocurre, es qeu el tipo de "grafico" que estes usando con las sdl no se "bueno" es decir que tengas un modo de video inicializado a 32 bits cosa que es mala para la gp2x, que aunque tengas el modo de video de16bits, estes usando graficos de 32bits... y cosas que tengan que ver co conversiones de color en la funcion SDL_DrawSprite.

P.D: todo lo que he escrito esta sin probar... no he compilado el codig

Unai.

Estopero
28/06/2006, 05:31
***** madre mia que lujo y que m0orro, te ayuda unai >_< xD

Rivroner
28/06/2006, 07:20
***** madre mia que lujo y que m0orro, te ayuda unai >_< xD
Échale tú morro tb y pide por esa boquita para el BugaFactor [wei]

cdrman
28/06/2006, 10:56
HOla, gracias por contestar. Lo he probado. No he conseguido un augmento sustancial de velocidad, almenos yo no lo noto. Además de eso, no se ven las serpientes bien. Te adjunto el .gpe para que lo pruebes (si quieres). Veras que efecto más raro.

ArChEr
29/06/2006, 06:28
Vale ya se cual es tu problema... es bastante sencillo, estas dibujando de -31 a + 31 eso son 62 sprites por linea por 62 columnas eso te hace un total de 3844 Sprites en pantalla al mismo tiempo... es como una burrada de sprites teniendo en cuenta que los sprites son mas lentos de dibujar por el tema de la trasparencia... tendrias que solucionarlo dibujando menos sprites pero claro eso supondria hacerlos mas grandes y entonces perderias vision, una solucion puede ser que no dibujes el suelo, es decir como el suelo siempre es estatico y queda en la misma posicion lo que puedes hacer es dibujar el suelo con una imagen normal y luego encima dibujar las "serpientes" y asi solo tendrias que dibujar los sprites de las serpientes y ahorrarias bastante proceso

Un saludo y a ver si te sirve de algo la ayuda!

Logann
29/06/2006, 18:00
perderias vision, una solucion puede ser que no dibujes el suelo, es decir como el suelo siempre es estatico y queda en la misma posicion lo que puedes hacer es dibujar el suelo con una imagen normal y luego encima dibujar las "serpientes" y asi
:rolleyes: esto me suena xD

Buena va un solucion nueva:

Creas una imagen muy muy grande, con el suleo y todo, del tamaño de la pantalla con scroll (a ver si puede entrar en memoria) y solo vas modificado esta imagen de nose, (1500x1500?), en cada dibujo la modificas añadiendo solo el sprit nuevo de cada moto y copias la porcion que toque segun l'scroll en pantalla.

Venga suerte!