Death Pit Remake
Un remake parcial de un juego... paso a paso
16.- Movimiento suave del personaje
El trabajo propuesto
Hacer que el movimiento del personaje sea más suave (en vez de saltar 70 píxeles a la izquierda, que salte 5, por ejemplo). Las colisiones con las paredes deben ser correctas.
Forma de conseguirlo
En el Personaje, cambiaremos el incremento, para que ahora se mueva de 5 en 5 píxeles. Y como ahora ya no iremos del centro de una casilla al centro de otra casilla, una forma sencilla de comprobar colisiones puede ser mirar qué casilla habrá en cada una de las 4 esquinas del personaje después del movimiento. Si alguna de esas casillas no es un espacio ni una escalera, no podremos movernos a esta posición, porque chocamos con algo. Las coordenadas de las 4 esquinas son (x,y) , (x+ancho,y) , (x,y+alto) y (x+ancho,y+alto), de modo que podríamos hacer algo así:
public class Personaje : ElemGrafico { ... public Personaje(Partida p) { miPartida = p; vidas = 5; x = 1; y = 1; incrX = 5; incrY = 5; ... } public void MoverDerecha() { direccion = DERECHA; if (x >= miPartida.GetMapa().GetMaxX()-5) { x = 0; miPartida.GetMapa().IrAHabitacionDerecha(); miPartida.RecolocarEnemigo(); } else if (x < miPartida.GetMapa().GetMaxX()) if (miPartida.GetMapa().EsPosibleMover((short) (x+incrX),y, (short) (x+ancho +incrX),(short) (y+alto))) x += incrX; } ...
Y en el Mapa ampliaremos ese "PosibleMover" para que mire realmente las cuatro esquinas:
public class Mapa { public const byte CASILLA_ESPACIO = 0; public const byte CASILLA_HORIZ = 1; public const byte CASILLA_HORIZ2 = 2; public const byte CASILLA_VERT = 3; public const byte CASILLA_ESCALERA = 4; ... public bool EsPosibleMover(short x, short y, short xMax, short yMax) { short posX = (short) (x/ANCHOCASILLA); short posY = (short) (y/ALTOCASILLA); short posXmax = (short) ((xMax-1)/ANCHOCASILLA); short posYmax = (short) ((yMax-1)/ALTOCASILLA); //Para que no se salga por los bordes de la pantalla if ((posX < 0) || (posY < 0) || (posX >= MAXCOLS) || (posY >= MAXFILAS)) return false; //Controlar colision con otros bloques if ( ((GetPosicion(posX,posY) != CASILLA_ESPACIO) && (GetPosicion(posX,posY) != CASILLA_ESCALERA) ) || ((GetPosicion(posX,posYmax) != CASILLA_ESPACIO) && (GetPosicion(posX,posYmax) != CASILLA_ESCALERA) ) || ((GetPosicion(posXmax,posY) != CASILLA_ESPACIO) && (GetPosicion(posXmax,posY) != CASILLA_ESCALERA) ) || ((GetPosicion(posXmax,posYmax) != CASILLA_ESPACIO) && (GetPosicion(posXmax,posYmax) != CASILLA_ESCALERA) ) ) return false; // Si no hay obstaculos, se puede mover a esa posicion return true; } ...
De forma similar, podemos hacer que el enemigo también se mueva de forma más suave.
De paso, podemos hacer que el movimiento del enemigo sea un poco más real, avanzando en una dirección totalmente hasta que encuentra un obstáculo, y cambiando de dirección en ese momento:
public class EnemigoMortal : ElemGrafico { ... Random numAleatorio; // Para que se mueva al azar public new void Mover() { // Si puede seguir en la dirección actual, lo hace if (miPartida.GetMapa().EsPosibleMover((short) (x+incrX), (short) (y+incrY), (short) (x+ancho +incrX),(short) (y+alto +incrY)) && (x+incrX < miPartida.GetMapa().GetMaxX()) && (y+incrY < miPartida.GetMapa().GetMaxY()) ) { x += incrX; y += incrY; return; } // Si no... // Para la siguiente posición, escojo al azar y miro si realmente se puede mover bool posibleMover = false; do { int numeroAzar = (int) numAleatorio.Next(0,100); if (numeroAzar < 25) // Intento derecha { ...
Puedes descargar todo el paquete de la versión 0.16, con todos los fuentes, el ejecutable (en la carpeta BIN/DEBUG), las imágenes, y el proyecto de SharpDevelop, en un fichero ZIP de tamaño cercano a 1 Mb.
Siguiente entrega...Acceso rápido
- 00.- Motivo
- 01.- Esqueleto vacío
- 02.- Un personaje que se mueve solo
- 03.- Personaje que se mueve con teclado. Enemigo simultáneo
- 04.- Presentación. Dos enemigos con distinto comportamiento
- 05.- Varios enemigos iguales
- 06.- Un fondo formado por "casillas" repetitivas (tiles)
- 07.- El personaje se mueve por el laberinto
- 08.- Un fuente más modular
- 09.- Varias pantallas conectadas
- 10.- Un enemigo que se mueve por el laberinto
- 11.- Varias vidas
- 12.- Distintas imágenes según la dirección. Matar enemigos y obtener puntos.
- 13.- Volver a empezar una partida.
- 14.- Rediseño usando objetos
- 15.- Pantalla de créditos
- 16.- Movimiento suave del personaje
- 17.- Personaje "animado"
- 18.- Leyendo el mapa desde fichero
- 19.- Animación al morir un enemigo (Aún no)
- 20.- Varios tipos de enemigos (Aún no)
- 21.- Un mapa más grande (Aún no)
- 22.- Tabla de records (Aún no)
- 23.- Recoger "premios" (Aún no)
- 24.- Gastar aire y "energía" (Aún no)
- Orig.- Algunos datos sobre el juego original