Falla en los coliders *colliders y como se soluciona temporalmente


Entrada importante al devlog 




Falla en los coliders *colliders y como se soluciona temporalmente :

causa 

- al cambiar el movimiento de mover todos el sprites 16 pixeles a la vez (tamaño del tileset) y la animación de una que usa delay() por el movimiento de un pixel a la vez y una animación más fluido usando en su lugar sys_time surge el feo problema de los coliders


Explicación falla de resolución 

```

al cambio realizado surge una falta de resolución en cuanto al movimiento y la colision de 16:16 que es 1:1 a 16:1 que causa que los coliders no sean exactos y en tiempo real no se pueden verificar

```

soluciones

```

1 limitar la actualización del input en 16 ciclos (inviable - lag)

2 permitir cualquier tipo de movimiento mientras la posición no sea exacta (%16==0) (implementado *pero puede causar otros problemas)

3 realizar cambios en la matriz de coliders para que se ajuste mejor (incrementando su tamaño) (posiblemente inviable por que la matriz de collider es la misma que usa para dibujar el tileset, además usar una matriz adicional puede consumir bastante memoria)

```


Explicación input cruzado :

```

caso particular

0=vacío X=sólido P=personaje

input =J_RIGHT


000

0P0

00X

```

analisis

```

La función de gravedad indica que P debe moverse hacia abajo por que el tile de abajo es 0

el input de usuario le indica que debe moverse hacia la derecha y como el tile de la derecha no es 0 se lo permite

como el colider tiene una falta de resolución no va a detectar ningún cambio hasta que las posiciones no sean exactas (%16)

P va directo a X en diagonal


```

solución implementada (temporalmente hasta mejorarse) :

```

no permitir el movimiento <- - > si hay un tile vacío debajo

```

contras

```

1 no se puede saltar y subir de la forma

^ ->

| P X

X X X

es decir no se puede subir gradas o subir a las plataformas

2 no se puede mover en el aire (aun con inercia inicial) , la gravedad siempre tiene prioridad al movimiento

```

soluciónes que no solucionan pero podría o tal vez no :


herramienta

```

termine inplementando un super colisionador de 8 puntos nine_col que devuelve un byte con todas las colisiónes al rededor de un personaje ver coliders.c

/*--------
[UL][U ][UR]
[ L][  ][ R]
[DL][D ][DR]
COL_UL B10000000 bit8
COL_U  B01000000 bit7
COL_UR B00100000 bit6
COL_L  B00010000 bit5
COL_R  B00001000 bit4
COL_DL B00000100 bit3
COL_D  B00000010 bit2
COL_DR B00000001 bit1
-----------*/
#define COL_UL  0x80
#define COL_U   0x40
#define COL_UR  0x20
#define COL_L   0x10
#define COL_R   0x08
#define COL_DL  0x04
#define COL_D   0x02
#define COL_DR  0x01
#define MAP_WHITH 10
#define TILE_SOLID 0x01
UBYTE COL =0x00;
#define CPOS (c_y_pos*MAP_WHITH+c_x_pos)
UBYTE nine_col(UBYTE c_x_pos,UBYTE c_y_pos,UBYTE mapa[]){
COL =0x00;
if(mapa[CPOS-MAP_WHITH-1]==TILE_SOLID){COL=COL|COL_UL;}
if(mapa[CPOS-MAP_WHITH  ]==TILE_SOLID){COL=COL|COL_U; }
if(mapa[CPOS-MAP_WHITH+1]==TILE_SOLID){COL=COL|COL_UR;}
if(mapa[CPOS-1]          ==TILE_SOLID){COL=COL|COL_L; }
if(mapa[CPOS+1]          ==TILE_SOLID){COL=COL|COL_R; }
if(mapa[CPOS+MAP_WHITH-1]==TILE_SOLID){COL=COL|COL_DL;}
if(mapa[CPOS+MAP_WHITH  ]==TILE_SOLID){COL=COL|COL_D; }
if(mapa[CPOS+MAP_WHITH+1]==TILE_SOLID){COL=COL|COL_DR;}
return COL;
}
//end of colider.c





Gracias a mi super colisionador puedo saber teóricamente si hay casos particulares como el mencionado anteriormente en la cual X esta en una posición diagonal a P y directamente le asigna un valor de 8bits

propuesta :

```

verificar el caso particular y permitir o no el movimiento

```

prueba 1:

```

en la función input al verificar si hay un tile vacío hacia la dirección del movimiento también verificar el caso particular de un tile vacío y uno sólido en diagonal

```

resultado

```

lo mismo casi que solo verificar el tile inferior, igual no se puede subir gradas

```

prueba 2:

```

en la función de gravedad

```

resultado

```

suele bloquear la gravedad casi constantemente, se puede quedar suspendido contra una pared y gracias a que el juego sigue roto simplemente saltar y romperlo aún mas

```

tal vez haya que tomar un enfoque más amplio y tomar en cuenta también el salto, tomar en cuenta más casos específicos también con tiles superiores, agregar más físicas fricción aceleracion así al enfocarlo por el lado de la gravedad no bloquearla solo porque si sino considerar otras alternativas


```

disclaimer :


todo lo anterior fue solo para una posible rotación del jugador que sería la de plataforma normal izq der y gravedad abajo, para los otros casos se extrapola cambiando la dirección del movimiento por los establecimientos

```

observacion:

la función rotar también hace que los coliders fallen porque al rotar la posición tiende a cambiar y no sincroniza los offsets correctamente ejemplo a nivel pixeles

```

|0123456789ABCDEF|


               P


|FEDCBA9876543210|

```

*la posición pasa de ser B a ser 5 y viceversa(puede de que según tu dispositivo y el tamaño de letra no sea xD pero ese es el punto) 

solucion implementada

```

solo permitir la rotación cuando la posición sea (%16==0) es decir tomando el centro 8 en el ejemplo

```

contras

```

no siempre se puede rotar , hay que alinear al personaje 

```


código del player en cuestión 


/h>. Parte importante ver comentario hasta abajo 

Files

webGB.zip 102 kB
Jul 03, 2023
KEYCHAN-DEMO-052C.gb 256 kB
Jul 03, 2023

Get keychan

Download NowName your own price

Comments

Log in with itch.io to leave a comment.

https://github.com/djarky/Keychan/blob/main/src/089K/player_control.c

void player_inputt(UBYTE joy,UBYTE mapa[]){   player_calcule_xy(); player_col=nine_col(player_pos_x,player_pos_y,mapa);   if(joy & J_A){ if(jump_height==0){play_sound_C1(0x62, 0x87, 0x8D, 0x32 ,0xC1);} player_jump();   player_calcule_xy(); player_col=nine_col(player_pos_x,player_pos_y,mapa); } else{if(jump_height>0){jump_height--;}}   if(joy & J_B){player_power_up();}  switch(player_rot){  case J_UP   :      if( (joy & J_RIGHT) && (!(player_col & COL_R)&&(player_col & COL_D)||player_pos_x_abs%16 !=0) ){player_move_front();    }      if( (joy & J_LEFT)  && (!(player_col & COL_L)&&(player_col & COL_D)||player_pos_x_abs%16 !=0) ){player_move_back();     }  break;  case J_DOWN :      if( (joy & J_RIGHT) && (!(player_col & COL_R)&&(player_col & COL_U)||player_pos_x_abs%16 !=0) ){player_move_front();    }      if( (joy & J_LEFT)  && (!(player_col & COL_L)&&(player_col & COL_U)||player_pos_x_abs%16 !=0) ){player_move_back();     }  break;  case J_LEFT :     if( (joy & J_UP)   && (!(player_col & COL_U)&&(player_col & COL_R)||player_pos_y_abs%16 !=0) ){player_move_front_side();}     if( (joy & J_DOWN) && (!(player_col & COL_D)&&(player_col & COL_R)||player_pos_y_abs%16 !=0) ){player_move_back_side(); }  break;  case J_RIGHT:     if( (joy & J_UP)   && (!(player_col & COL_U)&&(player_col & COL_L)||player_pos_y_abs%16 !=0) ){player_move_front_side();}     if( (joy & J_DOWN) && (!(player_col & COL_D)&&(player_col & COL_L)||player_pos_y_abs%16 !=0) ){player_move_back_side(); }  break;  }    //recalcule new x y and collision player_calcule_xy(); player_col=nine_col(player_pos_x,player_pos_y,mapa); player_gravity();    }