Página 12 de 20

Re: FASE (Fucking Awesome Spectrum Engine)

Publicado: Sab, 17 May 2014, 20:53
por antoniovillena
Por si te sirve de ayuda, he implementado inercia y gravedad en el personaje principal para la demo. Para simplificar el suelo es una línea recta y el salto no es acumulativo. Pongo aquí el código y más abajo el TAP para que lo probéis:

$this->bbcode_second_pass_code('', '
#include <stdlib.h>
#include "fase.h"

#define gconst 20
#define maxvx 600
#define maxvy 600

extern unsigned char *ending;
const unsigned char data[20]= {
0x00, 0x42, 0x11, 0,
0x08, 0x60, 0x60, 2,
0x09, 0x58, 0x48, 3,
0x0a, 0x22, 0x02, 1,
0x0b, 0x50, 0x6e, 2};

char i, j, killed, mapx, mapy, spacepressed, dirbul[4], num_bullets;
unsigned char tmpx, tmpy;
short x, vx, ax, y, vy, ay;
void remove_bullet( char k );
void update_screen();
void update_scoreboard();

main(){

start:
killed= mapx= mapy= spacepressed= num_bullets= *shadow= 0;
x= 0x3000;
y= 0x1000;
update_scoreboard();

// inicializar engine
INIT;

// pasar datos a sprites y balas
for ( i = 0; i < 5; i++ )
sprites[i].n= data[0 | i<<2],
sprites[i].x= data[1 | i<<2],
sprites[i].y= data[2 | i<<2],
sprites[i].f= data[3 | i<<2];
for ( i = 0; i < 4; i++ )
bullets[i].y= 255;

// mostrar la primera pantalla al comienzo y marcador
*screen= 0;

while(1){

// esto hace que el engine procese un frame generando el escenario
M_OUTP(0xfe, 0);
FRAME;
M_OUTP(0xfe, 2);

// movimiento de los enemigos
for ( i = 1; i < 5; i++ )
if( sprites[i].n<0x80 ){
for ( j= 0; j < num_bullets; j++ )
if( abs(bullets[j].x-sprites[i].x) + abs(bullets[j].y-sprites[i].y) < 10 ){
sprites[i].n-= 0x80;
remove_bullet( j );
tmpx= sprites[i].x>>4;
tmpy= sprites[i].y>>4;
tiles[tmpy*scrw+tmpx]= 68;
tilepaint(tmpx, tmpy, tmpx, tmpy);
killed++;
if( killed==10 ){
EXIT;
Dzx7b((unsigned int) (&ending-1), 0x5aff);
Pause(100);
goto start;
}
*drwout= (unsigned int)update_scoreboard;
}
if( sprites[i].f&1 )
if( sprites[i].y>0 )
sprites[i].y--;
else
sprites[i].f^= 1;
else
if( sprites[i].y<scrh*16 )
sprites[i].y++;
else
sprites[i].f^= 1;
if( sprites[i].f&2 )
if( sprites[i].x>0 )
sprites[i].x--;
else
sprites[i].f^= 2;
else
if( sprites[i].x<scrw*16 )
sprites[i].x++;
else
sprites[i].f^= 2;
}

// movimiento de las balas
for ( i = 0; i < num_bullets; i++ ){
if( dirbul[i]&3 ){
if( dirbul[i]&1 ){
if( bullets[i].x<scrw*16 )
bullets[i].x+= 2;
else
remove_bullet( i );
}
else{
if( bullets[i].x>2 )
bullets[i].x-= 2;
else
remove_bullet( i );
}
}
if( dirbul[i]&12 ){
if( dirbul[i]&4 ){
if( bullets[i].y<scrh*16 )
bullets[i].y+= 2;
else
remove_bullet( i );
}
else{
if( bullets[i].y>2 )
bullets[i].y-= 2;
else
remove_bullet( i );
}
}
}



vx+= ax;
x+= vx;
if( vx+8>>3 )
ax= -vx>>3;
else
ax= vx= 0;
if( (unsigned int)x > scrw<<12 )
if( vx>0 )
if( mapx < mapw-1 )
x= 0,
mapx++,
update_screen();
else
x= scrw<<12,
vx= 0;
else if( mapx )
x= scrw<<12,
mapx--,
update_screen();
else
vx= x= 0;
sprites[0].x= x>>8;

if( vy>maxvy )
vy= maxvy;
else
vy+= ay+gconst;
if( (unsigned int)y <= 15<<11 )
y+= vy;
else
vy= 0,
y= 15<<11;
sprites[0].y= y>>8;


// movimiento del protagonista
if( inKey(KeybYUIOP) & 0x01 ) // P
ax= vx<maxvx ? 40 : 0;
else if( inKey(KeybYUIOP) & 0x02 ) // O
ax= vx>-maxvx ? -40 : 0;
if( inKey(KeybGFDSA) & 0x01 ){ // A
/* if( sprites[0].y<scrh*16 )
sprites[0].y++;
else if( mapy < maph-1 )
sprites[0].y= 0,
mapy++,
update_screen();*/
}
else if( inKey(KeybTREWQ) & 0x01 ){ // Q
if( (unsigned int)y == 15<<11 )
vy= -800;
}
if( inKey(KeybBNMs_) & 0x01 && !spacepressed && num_bullets<4 ){ // Space
bullets[num_bullets].x= sprites[0].x;
bullets[num_bullets].y= sprites[0].y;
i= inKey(KeybTREWQ)<<3&8 | inKey(KeybGFDSA)<<2&4 | inKey(KeybYUIOP)&3;
dirbul[num_bullets]= i ? i : 1;
num_bullets++;
}
spacepressed= inKey(KeybBNMs_) & 0x01;
}
}

void remove_bullet( char k ){
if( num_bullets ){
num_bullets--;
while ( k<num_bullets )
dirbul[k]= dirbul[k+1],
bullets[k].x= bullets[k+1].x,
bullets[k].y= bullets[++k].y;
bullets[k].y= 255;
}
}

void update_screen(){
*screen= mapy*mapw + mapx;
for ( j= 1; j < 5; j++ )
if( sprites[j].n>0x7f )
sprites[j].n-= 0x80;
}

void update_scoreboard(){
unsigned int scr, dst;
char count;
scr= 0x3d80+killed*8;
dst= 0x50de|*shadow<<8;
for ( count= 0; count<8; count++ )
zxmem[dst]= zxmem[scr++]^0xff,
dst+= 0x100;
}

#asm
BINARY "ending.rcs.zx7b"
._ending
#endasm

')

Re: FASE (Fucking Awesome Spectrum Engine)

Publicado: Lun, 19 May 2014, 07:06
por Hark0
Me gusta la suavidad del movimiento... es genial!

(otra vez pon una pausa más larga en la pantalla de la chica... :mrgreen: que casi no da tiempo a verla ;) )

Re: FASE (Fucking Awesome Spectrum Engine)

Publicado: Lun, 19 May 2014, 14:48
por antoniovillena
Es suave porque son 50fps reales. El inconveniente es que tienes que ajustarte al tiempo que te sobra del frame para la lógica del juego, y si te pasas te saltas un frame. Si te saltas varios frames seguidos el juego iría ralentizado a la mitad de la velocidad real.

El secreto para no gastar muchos ciclos en la lógica es usar como mucho enteros de 16 bits, y no usar multiplicaciones ni cuadrados, ni potencias ni cualquier cosa que no pueda hacer el Z80 rápidamente.

En cuanto a la chica ahí está la gracia, quedarte con las ganas de verla más tiempo y obligarte a echar otra partida.

Re: FASE (Fucking Awesome Spectrum Engine)

Publicado: Mar, 20 May 2014, 18:14
por antoniovillena
He convertido la demo a HTML5 para facilitar la depuración. ¿Qué significa esto? Que si tienes instalado un apache en local puedes ejecutar directamente el código sin necesidad de compilación. Como el javascript es muy parecido al C luego no te va a costar mucho trabajo traducirlo, es un copy/paste con algún que otro ajuste.

Recomiendo usarlo con Chrome, que es el navegador que uso y por tanto con el que funciona seguro, además va bastante fluído.

Esto vale sólo para depurar, la versión HTML5 no está optimizada ni en velocidad ni en compatibilidad con otros navegadores. Si el objetivo es tener el juego bajo navegador también podría hacerse pero ya no sería tan cómodo para depurar (habría que tratar algunos archivos como map.tmx).

El enlace para probarlo está aquí:

http://antoniovillena.es/fase/game.html

Y el código fuente como siempre, en el repositorio, aunque también podéis extraerlo de aquí arriba, está sin ofuscar.

Re: FASE (Fucking Awesome Spectrum Engine)

Publicado: Mar, 20 May 2014, 18:35
por na_th_an
Qué chulo :O

Re: FASE (Fucking Awesome Spectrum Engine)

Publicado: Mié, 21 May 2014, 07:47
por Hark0
$this->bbcode_second_pass_quote('antoniovillena', 'H')e convertido la demo a HTML5 para facilitar la depuración. ¿Qué significa esto? Que si tienes instalado un apache en local puedes ejecutar directamente el código sin necesidad de compilación. Como el javascript es muy parecido al C luego no te va a costar mucho trabajo traducirlo, es un copy/paste con algún que otro ajuste.

Recomiendo usarlo con Chrome, que es el navegador que uso y por tanto con el que funciona seguro, además va bastante fluído.

Esto vale sólo para depurar, la versión HTML5 no está optimizada ni en velocidad ni en compatibilidad con otros navegadores. Si el objetivo es tener el juego bajo navegador también podría hacerse pero ya no sería tan cómodo para depurar (habría que tratar algunos archivos como map.tmx).

El enlace para probarlo está aquí:

http://antoniovillena.es/fase/game.html

Y el código fuente como siempre, en el repositorio, aunque también podéis extraerlo de aquí arriba, está sin ofuscar.


:o Que bien se mueve en mi aipad!

Por Dios Antonio, métele soporte a un teclado que rule en una tableta!!! (yo no fui capaz por mucho que me mire lo que me pasaste/contaste... mis conocimientos son más limitados)

Re: FASE (Fucking Awesome Spectrum Engine)

Publicado: Jue, 22 May 2014, 21:25
por Metalbrain
La verdad es que el engine es alucinante. Un trabajo para quitarse el sombrero, Antonio.

Una micro optimización:

$this->bbcode_second_pass_code('', '
ld a, $18
jr z, do2
ld a, $17
')

se puede cambiar por:
$this->bbcode_second_pass_code('', '
ld a, $18
jr z, do2
dec a
')

Y también he visto que en las partes en las que se discrimina según la anchura (por ejemplo, al decidir entre del3, del4 o del5), la parte de código más corta (y por tanto más rápida) se beneficia de no tener que dar el salto hacia delante, lo cual acentúa las diferencias de velocidad respecto a las otras. Tal vez sea conveniente mover un poquito el código para que la parte más larga y lenta se beneficie de no tener que dar el salto.

Re: FASE (Fucking Awesome Spectrum Engine)

Publicado: Jue, 22 May 2014, 23:06
por antoniovillena
$this->bbcode_second_pass_quote('Hark0', '
') :o Que bien se mueve en mi aipad!

Por Dios Antonio, métele soporte a un teclado que rule en una tableta!!! (yo no fui capaz por mucho que me mire lo que me pasaste/contaste... mis conocimientos son más limitados)


Ahora mismo es que no se trata de portar el juego a HTML5, sino de tener un mecanismo rápido de depuración. Si te das cuenta no se necesita línea de comandos para nada, es editar y pulsar F5 en el navegador. La idea es hacer las pruebas en HTML5 y una vez estén los cambios definitivos trasladarlos a C.

Si más adelante tiene éxito podemos hablar de un port para HTML5, en este caso sí que sería interesante tener un teclado en pantalla.

$this->bbcode_second_pass_quote('Metalbrain', 'L')a verdad es que el engine es alucinante. Un trabajo para quitarse el sombrero, Antonio.

Una micro optimización:

$this->bbcode_second_pass_code('', '
ld a, $18
jr z, do2
ld a, $17
')

se puede cambiar por:
$this->bbcode_second_pass_code('', '
ld a, $18
jr z, do2
dec a
')

Y también he visto que en las partes en las que se discrimina según la anchura (por ejemplo, al decidir entre del3, del4 o del5), la parte de código más corta (y por tanto más rápida) se beneficia de no tener que dar el salto hacia delante, lo cual acentúa las diferencias de velocidad respecto a las otras. Tal vez sea conveniente mover un poquito el código para que la parte más larga y lenta se beneficie de no tener que dar el salto.


Gracias, ya he trasladado el cambio al repositorio. El engine lo tengo un poco abandonado, apenas lo he cambiado desde que lo hice, lo único que he hecho es soportar Z88DK y darle inercia y gravedad al protagonista de la demo. Yo no programo juegos, no tengo experiencia, mi idea era crear el germen de una Churrera mejorada sin las limitaciones actuales. Pero claro, se necesita programar el resto del juego en C.

Cuando lo acabé tenía unas ideas para ir mejorando el engine, pero claro esto depende del éxito que tenga:


Si te resulta interesante el proyecto, tanto para continuarlo como para hacer un juego con él, te doy acceso al repositorio. Y si no te manejas con GIT te lo muevo a otro sitio.

En cuanto al salto y la anchura en su momento le di el camino más corto a la anchura de 2 bytes, supongo que era la que más se repetía, al menos en los sprites de la demo. Tendría que analizar distintos sets de sprites para ver cual de los 3 anchos merece la pena acortar.

Re: FASE (Fucking Awesome Spectrum Engine)

Publicado: Jue, 29 May 2014, 11:58
por D_Skywalk
Muy wapo antonio el html5, una mini sugerencia:
$this->bbcode_second_pass_code('', 'canvas { image-rendering: -moz-crisp-edges; }')

Eso quita el suavizado en mozilla, pero en chrome no funciona su versión webkit (ya que el canvas lo generas con el js), si quieres revisarlo... https://code.google.com/p/chromium/issu ... ?id=134040

Por cierto, en Junio tengo un par de semanas libres y estoy preparando una pequeña JAM para hacer un pequeño juego/ejemplo con FASE. Ahora lo posteo por aquí también por si algún compa se anima también ;)

Re: FASE (Fucking Awesome Spectrum Engine)

Publicado: Vie, 30 May 2014, 03:49
por antoniovillena
Gracias por la sugerencia. El suavizado no molesta, incluso queda mejor. En Firefox se gana algo de rendimiento sin suavizado. El código que hay ahora es simple, no está optimizado en velocidad. En cada frame se sobreescribe el fondo completo, cuando lo más rápido sería restaurar sólo las porciones que quedan detrás de los sprites.

Genial, si quieres puedes publicarla (la demo) en el propio repositorio de FASE, en otra carpeta.