Estoy tratando de seguir este tutorial http://www.tonypa.pri.ee/tbw/tut05.html para implementar colisiones en tiempo real en un mundo basado en mosaicos.
Encuentro las coordenadas centrales de mis entidades gracias a estas propiedades:
public float CenterX
{
get { return X + Width / 2f; }
set { X = value - Width / 2f; }
}
public float CenterY
{
get { return Y + Height / 2f; }
set { Y = value - Height / 2f; }
}
Luego, en mi método de actualización, en la clase de jugador, que se llama cada cuadro, tengo este código:
public override void Update()
{
base.Update();
int downY = (int)Math.Floor((CenterY + Height / 2f - 1) / 16f);
int upY = (int)Math.Floor((CenterY - Height / 2f) / 16f);
int leftX = (int)Math.Floor((CenterX + Speed * NextX - Width / 2f) / 16f);
int rightX = (int)Math.Floor((CenterX + Speed * NextX + Width / 2f - 1) / 16f);
bool upleft = Game.CurrentMap[leftX, upY] != 1;
bool downleft = Game.CurrentMap[leftX, downY] != 1;
bool upright = Game.CurrentMap[rightX, upY] != 1;
bool downright = Game.CurrentMap[rightX, downY] != 1;
if(NextX == 1)
{
if (upright && downright)
CenterX += Speed;
else
CenterX = (Game.GetCellX(CenterX) + 1)*16 - Width / 2f;
}
}
downY, upY, leftX y rightX deben encontrar respectivamente la posición Y más baja, la posición Y más alta, la posición X más a la izquierda y la posición X más a la derecha. Agrego + Speed * NextX porque en el tutorial la función getMyCorners se llama con estos parámetros:
getMyCorners (ob.x+ob.speed*dirx, ob.y, ob);
Los métodos GetCellX y GetCellY:
public int GetCellX(float mX)
{
return (int)Math.Floor(mX / SGame.Camera.TileSize);
}
public int GetCellY(float mY)
{
return (int)Math.Floor(mY / SGame.Camera.TileSize);
}
El problema es que el jugador "parpadea" mientras golpea una pared, y la detección de esquinas ni siquiera funciona correctamente, ya que puede superponer paredes que solo golpean una de las esquinas. No entiendo lo que está mal. En el tutorial, los campos ob.x y ob.y deben ser iguales a mis propiedades CenterX y CenterY, y ob.width y ob.height deben ser iguales a Width / 2f y Height / 2f. Sin embargo, todavía no funciona.
Gracias por tu ayuda.
Respuestas:
Un par de sugerencias, aunque no estoy seguro de que solucionarán el problema, ya que no tengo el código completo para ejecutar y depurar.
En este código:
la instrucción else mueve el objeto aunque el objeto no debería moverse.
Supongo que está tratando de hacer que el objeto quede al ras contra la pared, pero tal vez el cálculo sea incorrecto.
Si comenta la declaración else, ¿el objeto todavía parpadea?
El cálculo parece un poco sospechoso ya que resta (Ancho / 2f) y luego el operador del conjunto CenterX hace la misma resta nuevamente.
Otra cosa que me gustaría señalar, solo para ayudar a la claridad del código, es que hizo que las propiedades de CenterX calculen el valor una y otra vez, pero el código todavía está lleno del mismo cálculo una y otra vez.
Esto bien podría ser parte del problema. De cualquier manera, sugeriría hacer algunas propiedades más y establecer un estándar para todas ellas. Por ejemplo, haga que el Centro sea la propiedad almacenada y calcule los demás a partir de él:
fuente