2011-12-01 12 views
5

Estoy trabajando en mi primer juego XNA 2D y tengo un pequeño problema. Si salto, mi sprite salta pero no se cae. Y también tengo otro problema, el usuario puede contener barra espaciadora para saltar tan alto como quiera y no sé cómo evitar que lo haga. Aquí está mi código: El Salto:Salto vs. Gravedad

if (FaKeyboard.IsKeyDown(Keys.Space)) 
     { 
      Jumping = true; 
      xPosition -= new Vector2(0, 5); 
     } 

     if (xPosition.Y >= 10) 
     { 
      Jumping = false; 
      Grounded = false; 
     } 

El muy simple gravedad básica:

if (!Grounded && !Jumping) 
     { 
      xPosition += new Vector2(1, 3) * speed; 
     } 

Aquí es donde está la tierra se establece en Verdadero o Falso con una colisión

Rectangle MegamanRectangle = new Rectangle((int)xPosition.X, (int)xPosition.Y, FrameSizeDraw.X, FrameSizeDraw.Y); 
     Rectangle Block1Rectangle = new Rectangle((int)0, (int)73, Block1.Width, Block1.Height); 
     Rectangle Block2Rectangle = new Rectangle((int)500, (int)73, Block2.Width, Block2.Height); 

     if ((MegamanRectangle.Intersects(Block1Rectangle) || (MegamanRectangle.Intersects(Block2Rectangle)))) 
     { 
      Grounded = true; 
     } 
     else 
     { 
      Grounded = false; 
     } 

La conexión a tierra bool y La gravedad han sido probados y están funcionando. ¿Alguna idea de por qué? Gracias de antemano y no dude en preguntar si necesita otra parte del código.

Respuesta

5

Una forma relativamente simple de manejar el salto es implementar la gravedad como un vector y saltar/moverse como un impulso.

Por ejemplo:

foreach (Object obj in GameWorld) 
{ 
    obj.Velocity *= 0.5; // Slow it down slightly 
    obj.Velocity += GravityPerSecond * FrameTime; // Gravity adjusted for time 
    obj.Move(obj.Velocity); // Handle collision and movement here 
} 

La velocidad debería ser un vector con las mismas dimensiones que el mundo, y Mover un método que se mueve el objeto en la medida de lo posible en el vector dado.

código de salto:

OnKeyDown(Key k) 
{ 
    if (k == Key.Space) 
    { 
     obj.Velocity += Vector2(0, 10); // Add an upward impulse 
    } 
} 

Esto hará que el objeto se mueva para un poco, y luego comience a caer. Puede usar impulsos similares para otros efectos (movimiento, explosiones, colisión). Deberá tener colisión para modificar la velocidad cuando dos objetos colisionen, para rebotar.

Este es un sistema de física extremadamente simple que hará que los cambios futuros sean mucho más simples, y podría permitir algún diseño de nivel interesante (cambiar la gravedad y demás). Simplifica el manejo del salto abstrayéndolo del complejo código IsJumping a una sola mecánica.

Para evitar saltar sin pararse sobre un objeto, tendría que hacer una prueba de colisión, o seguir cuando los objetos colisionan/dejan de colisionar hacia abajo. También podría ser posible verificar si la velocidad vertical del objeto es cero y permitir saltar solo en ese momento (evitaría saltar al caer o al moverse hacia arriba).

+0

Me gusta mucho este enfoque! Pero soy nuevo en esto y no puedo imaginarme qué poner en lugar de "GameWorld" – phadaphunk

+1

Lo que sea que guardes los objetos del juego, ya sea el mundo, el administrador de escena, etc. Es posible que desee mantener una colección de objetos de física (solo objetos móviles, omita el nivel estático) y usar eso. – ssube

+1

+1; Buena sugerencia. Mis dos centavos: Dependiendo de su juego, a veces la física más falsa puede darle mejores resultados. Ala los juegos de Mario, o casi cualquier juego de plataforma de la era NES o SNES. Tendrás cálculos más fáciles/menos experimentación al diseñar tus niveles, y no será tan difícil de resolver som Las cosas, como "tunelización", o hacer que tu física funcione de manera diferente en diferentes máquinas. No será tan general tho. Si opta por un enfoque de velocidad/aceleración más generalizado, como sugiere esta respuesta, también podría considerar la velocidad del terminal de modelado. –

2

Creo que esto podría ser la respuesta:

cambio de su

if (FaKeyboard.IsKeyDown(Keys.Space)) 
    { 
     Jumping = true; 
     xPosition -= new Vector2(0, 5); 
    } 

    if (xPosition.Y >= 10) 
    { 
     Jumping = false; 
     Grounded = false; 
    } 

a

if (!Jumping && FaKeyboard.IsKeyDown(Keys.Space)) 
    { 
     Jumping = true; 
     Grounded = false; 
    } 

    if (Jumping) 
    { 
     xPosition -= new Vector2(0, 5); 
    } 

    if (xPosition.Y >= 10) 
    { 
     Jumping = false; 
    } 

Las otras respuestas dadas con velocidad son realmente mejores enfoques, pero esto podría ser lo suficientemente cerca para que comiences de nuevo.

+0

También podría utilizar! Saltar en lugar de poner a tierra en la declaración condicional de la solución si se ajusta mejor a su modelo de gravedad. –

+0

Lo probé pero no funciona .. El sprite no salta en absoluto. Y si cambio xPosition - = new Vector (0, 5) a Vector nuevo (0, 20) o superior, el sprite salta un poco pero aún no cae. :( Estoy atascado :( – phadaphunk

+0

Probé el ! Saltando también pero parece que tampoco puedo hacer que funcione ... – phadaphunk

1

Aquí es una solución muy rústico a hacer un salto subir y bajar:

const float SCALE = 20.0f; //SPEED!!! 
if (jump <= 15 && jump != 0) 
      { 
       humanPosition.Y -= SCALE * speed; 
       jump++; 
      } 
      else if (jump > 15) 
      { 
       humanPosition.Y += SCALE * speed; 
       jump++; 
       if (jump == 32) 
       { 
        jump = 0; 
        humanPosition.Y = 307; 
       } 
      } 

Y es activado por

  else if (keyboard.IsKeyDown(Keys.Up)) 
     { 
      jump = 1; 
      humanPosition.Y -= SCALE * speed; 
     } 

Lo que esto hace es puesto en movimiento el salto al establecer su 1 Además, si desea restringir el salto solo cuando el personaje está en el suelo, puede agregar una condición similar a esta

if (humanPosition.Y != GROUNDLEVEL){} 
0

El salto no debe ser un booleano a menos que lo necesite para algo así como una animación o una habilidad que solo se puede utilizar al saltar.

En su lugar, debe utilizar el movimiento del vector y cuando el jugador esté tocando el suelo y presione su botón de salto, agregue un vector de salto ascendente a su movimiento.

Entonces, la gravedad tiene que ser un vector descendente que actúa contra el jugador y se manejará solo.