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...