Why won't my sprite move back down?

Discussion in 'Programmer's Corner' started by magnet18, Oct 16, 2011.

  1. magnet18

    Thread Starter Senior Member

    Dec 22, 2010
    1,232
    124
    Alright, I'm learning C# and am trying to get the basics down by making a simple 2D game similar to mario. I got the moving don, and am currently trying to get it to jump smoothly, so I came up with the following code- But when I press the jump button, the sprite just moves up, and keeps moving up, and I cant figure out why :(
    Code ( (Unknown Language)):
    1. namespace mario_clone
    2. {   public class Game1 : Microsoft.Xna.Framework.Game
    3.     {
    4.         GraphicsDeviceManager graphics;
    5.         KeyboardState oldState;
    6.         SpriteBatch spriteBatch;
    7.         Boolean jumping;
    8.  
    9.         public Game1()
    10.         {
    11.             graphics = new GraphicsDeviceManager(this);
    12.             graphics.IsFullScreen = true;
    13.             Content.RootDirectory = "Content";
    14.         }
    15.         protected override void Initialize()
    16.         {
    17.            base.Initialize();
    18.            oldState = Keyboard.GetState();
    19.            jumping = false;
    20.            // TODO: Add your initialization logic here
    21.  
    22.            base.Initialize();
    23.         }
    24.  
    25.         Texture2D myTexture;
    26.  
    27.         Vector2 spritePosition = new Vector2(1.0f, 1.0f);
    28.  
    29.         protected override void LoadContent()
    30.         {
    31.             spriteBatch = new SpriteBatch(GraphicsDevice);
    32.             myTexture = Content.Load<Texture2D>("mario sprite");
    33.            
    34.         }
    35.  
    36.      protected override void UnloadContent()
    37.         {
    38.         }
    39.  
    40.         protected override void Update(GameTime gameTime)
    41.         {
    42.             int MaxX =
    43.                 graphics.GraphicsDevice.Viewport.Width - myTexture.Width;
    44.             int MinX = 0;
    45.             int MaxY =
    46.                 graphics.GraphicsDevice.Viewport.Height - myTexture.Height;
    47.             int MinY = 0;
    48.             int gravity = 5;
    49.             var velocity = 15;
    50.  
    51.            
    52.             // keyboard logic
    53.             KeyboardState newState = Keyboard.GetState();
    54.  
    55.             if (newState.IsKeyDown(Keys.Escape))
    56.             {
    57.                 if (!oldState.IsKeyDown(Keys.Escape))
    58.                 {
    59.                     this.Exit();
    60.                 }
    61.             }
    62.  
    63.             if (newState.IsKeyDown(Keys.Left))
    64.             {
    65.                 if (spritePosition.X > MinX)
    66.                 {
    67.                     spritePosition.X = spritePosition.X - 2.0f;
    68.                 }                
    69.             }
    70.  
    71.             if (newState.IsKeyDown(Keys.Right))
    72.             {
    73.                 if (spritePosition.X < MaxX)
    74.                 {
    75.                     spritePosition.X = spritePosition.X + 2.0f;
    76.                 }
    77.             }
    78.            
    79.             if (newState.IsKeyDown(Keys.Up) && spritePosition.Y >= MaxY && jumping == false)
    80.             {
    81.                 jumping = true;
    82.                 velocity = 15;
    83.             }
    84.  
    85.             if (jumping == true)
    86.             {
    87.                
    88.                 spritePosition.Y = spritePosition.Y - velocity;
    89.                 velocity = velocity - gravity;
    90.             }
    91.  
    92.  
    93.             if (spritePosition.Y == MaxY && jumping == true)
    94.             {
    95.                 jumping = false;
    96.                 velocity = 0;
    97.             }
    98.  
    99.             if (spritePosition.Y < MaxY && jumping == false)
    100.             {
    101.                 spritePosition.Y = spritePosition.Y + gravity;
    102.             }
    103.  
    104.             if (spritePosition.Y >= MaxY)
    105.             {
    106.                 spritePosition.Y = MaxY;
    107.             }
    108.        
    109.             base.Update(gameTime);
    110.             oldState = newState;
    111.         }
    112.  
    113.         protected override void Draw(GameTime gameTime)
    114.         {
    115.             graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
    116.  
    117.             spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
    118.             spriteBatch.Draw(myTexture, spritePosition, Color.White);
    119.             spriteBatch.End();
    120.  
    121.             base.Draw(gameTime);
    122.         }
    123.     }
    124. }
     
  2. Filox

    New Member

    Oct 11, 2011
    7
    4
    Hello magnet18,

    The fact that the texture continued to move upwards ,was because you didn't have any limiting factor that could actually stop the ascending(examples: when texture reached the top border of the window, based on a timer etc).

    I added a TimeSpan variable in the declarations to count the time between the moment you pressed UP and the duration of ascdendance. When the timer passes that time the texture will start falling based on the gravity.

    Let's go to the actual code:
    Code (Text):
    1.  TimeSpan jumpTimer = TimeSpan.Zero;
    And change the if ( jumping == true ) condition's content to:
    Code (Text):
    1.  
    2. jumpTimer += gameTime.ElapsedGameTime;
    3. if (jumpTimer.CompareTo(new TimeSpan(0,0,0,0,500)) == 1)
    4. {
    5.      jumping = false;
    6.      jumpTimer = TimeSpan.Zero;
    7. }
    8. spritePosition.Y -= gravity;
    9.  
    I didn't want to change your code, just add the functionality you had problem with.Don't hesitate to ask if you want more clarifications on the above.
     
    Last edited: Oct 16, 2011
    magnet18 likes this.
  3. magnet18

    Thread Starter Senior Member

    Dec 22, 2010
    1,232
    124
    Thanks!, it kinda works, but I had to modify your code from if (jumpTimer.CompareTo(new TimeSpan(0,0,0,0,500)) == 1) to if (jumpTimer.CompareTo(new TimeSpan(0,0,0,0,500)) <= 1) to get it to come back down, which doesn't make sense to me, since it shouldn't go above 1 in the first place....

    also, now whenever I hit the jump button it moves up the initial velocity in one frame, then falls back down, rather than moving up the velocity, then the velocity - gravity, then the velocity - 2 gravity...

    I also am wondering why my initial code didn't work, because it should have moved up by less and less each time, until eventually moving back down by more and more, and triggering the end of the jump when it reached MaxY (bottom of screen)

    here's my current code-
    Code ( (Unknown Language)):
    1. namespace mario_clone
    2. {
    3.     /// <summary>
    4.     /// This is the main type for your game
    5.     /// </summary>
    6.     public class Game1 : Microsoft.Xna.Framework.Game
    7.     {
    8.         GraphicsDeviceManager graphics;
    9.         KeyboardState oldState;
    10.         SpriteBatch spriteBatch;
    11.         Boolean jumping;
    12.         const int move_up = -1;
    13.         const int move_down = 1;
    14.         const int move_left = -1;
    15.         const int move_right = 1;
    16.  
    17.  
    18.         public Game1()
    19.         {
    20.             graphics = new GraphicsDeviceManager(this);
    21.             graphics.IsFullScreen = true;
    22.             Content.RootDirectory = "Content";
    23.         }
    24.  
    25.         /// <summary>
    26.         /// Allows the game to perform any initialization it needs to before starting to run.
    27.         /// This is where it can query for any required services and load any non-graphic
    28.         /// related content.  Calling base.Initialize will enumerate through any components
    29.         /// and initialize them as well.
    30.         /// </summary>
    31.         protected override void Initialize()
    32.         {
    33.            base.Initialize();
    34.            oldState = Keyboard.GetState();
    35.            jumping = false;
    36.            // TODO: Add your initialization logic here
    37.  
    38.            base.Initialize();
    39.         }
    40.  
    41.         /// <summary>
    42.         /// LoadContent will be called once per game and is the place to load
    43.         /// all of your content.
    44.         /// </summary>
    45.         ///
    46.  
    47.         Texture2D myTexture;
    48.  
    49.         Vector2 spritePosition = new Vector2(1,1);
    50.  
    51.         protected override void LoadContent()
    52.         {
    53.             // Create a new SpriteBatch, which can be used to draw textures.
    54.             spriteBatch = new SpriteBatch(GraphicsDevice);
    55.             myTexture = Content.Load<Texture2D>("mario sprite");
    56.            
    57.         }
    58.  
    59.         /// <summary>
    60.         /// UnloadContent will be called once per game and is the place to unload
    61.         /// all content.
    62.         /// </summary>
    63.         protected override void UnloadContent()
    64.         {
    65.             // TODO: Unload any non ContentManager content here
    66.         }
    67.  
    68.         /// <summary>
    69.         /// Allows the game to run logic such as updating the world,
    70.         /// checking for collisions, gathering input, and playing audio.
    71.         /// </summary>
    72.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
    73.         protected override void Update(GameTime gameTime)
    74.         {
    75.             int MaxX =
    76.                 graphics.GraphicsDevice.Viewport.Width - myTexture.Width;
    77.             int MinX = 0;
    78.             int MaxY =
    79.                 graphics.GraphicsDevice.Viewport.Height - myTexture.Height;
    80.             int MinY = 0;
    81.             int gravity = 5;
    82.             var velocity = 0;
    83.  
    84.             UpdateJump();
    85.             // keyboard logic
    86.             KeyboardState newState = Keyboard.GetState();
    87.             TimeSpan jumpTimer = TimeSpan.Zero;
    88.  
    89.             if (newState.IsKeyDown(Keys.Escape))
    90.             {
    91.                 if (!oldState.IsKeyDown(Keys.Escape))
    92.                 {
    93.                     this.Exit();
    94.                 }
    95.             }
    96.  
    97.             if (newState.IsKeyDown(Keys.Left))
    98.             {
    99.                 if (spritePosition.X > MinX)
    100.                 {
    101.                     spritePosition.X = spritePosition.X - 2;
    102.                 }                
    103.             }
    104.  
    105.             if (newState.IsKeyDown(Keys.Right))
    106.             {
    107.                 if (spritePosition.X < MaxX)
    108.                 {
    109.                     spritePosition.X = spritePosition.X + 2;
    110.                 }
    111.             }
    112.            
    113.             if (newState.IsKeyDown(Keys.Up) && oldState.IsKeyDown(Keys.Up) == false && spritePosition.Y >= MaxY && jumping == false)
    114.             {
    115.                 jumping = true;
    116.                 velocity = 500;
    117.             }
    118.  
    119.             jumpTimer += gameTime.ElapsedGameTime;
    120.             if (jumpTimer.CompareTo(new TimeSpan(0,0,0,1,500)) == 1 && jumping == true)
    121.             {
    122.                
    123.                     jumping = false;
    124.                     jumpTimer = TimeSpan.Zero;
    125.                
    126.             }
    127.  
    128.             if (spritePosition.Y < MaxY && jumping == false)
    129.             {
    130.                 spritePosition.Y +=  gravity;
    131.             }
    132.  
    133.             if (velocity > 0)
    134.             {
    135.                 spritePosition.Y -= velocity;
    136.                 velocity -= gravity;
    137.             }
    138.  
    139.             if (spritePosition.Y >= MaxY)
    140.             {
    141.                 spritePosition.Y = MaxY;
    142.             }
    143.  
    144.             if (spritePosition.Y <= MinY)
    145.             {
    146.                 spritePosition.Y = MinY;
    147.             }
    148.        
    149.             // Move the sprite by speed, scaled by elapsed time.
    150.            
    151.            
    152.  
    153.            
    154.  
    155.             base.Update(gameTime);
    156.             oldState = newState;
    157.         }
    158.  
    159.         private void UpdateJump()
    160.         {
    161.         }
    162.      
    163.  
    164.        
    165.         /// <summary>
    166.         /// This is called when the game should draw itself.
    167.         /// </summary>
    168.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
    169.         protected override void Draw(GameTime gameTime)
    170.         {
    171.             graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
    172.  
    173.             spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
    174.             spriteBatch.Draw(myTexture, spritePosition, Color.White);
    175.             spriteBatch.End();
    176.  
    177.             base.Draw(gameTime);
    178.         }
    179.     }
    180. }
    181.  
    [EDIT]
    Could the jumpTimer not be "starting" properly, or be running the whole time and being to big, or something?
     
    Last edited: Oct 16, 2011
  4. Filox

    New Member

    Oct 11, 2011
    7
    4
    I believe that there was a misunderstanding there. When I said :
    I meant that you should keep that condition and replace the code between the braces with the code given. You should keep the initial code that you posted and replace this condition:
    Code ( (Unknown Language)):
    1.  
    2. if (jumping == true)
    3. {          
    4.      spritePosition.Y = spritePosition.Y - velocity;
    5.      velocity = velocity - gravity;
    6. }
    with:
    Code ( (Unknown Language)):
    1.  
    2. if (jumping == true)
    3. {
    4.      jumpTimer += gameTime.ElapsedGameTime;
    5.      if (jumpTimer.CompareTo(new TimeSpan(0,0,0,0,500)) == 1)
    6.      {
    7.            jumping = false;
    8.            jumpTimer = TimeSpan.Zero;
    9.       }
    10.       spritePosition.Y -= gravity;
    11. }
    The jumpTimer should count ONLY after the UP button has been pressed and not always as you had in the second code that you posted, which had as a result , our timer not doing what he was supposed to do.

    CompareTo method works like this: Let's say that we have:
    Code ( (Unknown Language)):
    1. timer.CompareTo(value)
    This method call returns:
    -> (-1) if the value is bigger than timer
    -> (0) if the value is equal to the timer
    -> (1) if the value is smaller than the timer

    This means that :
    Code ( (Unknown Language)):
    1. jumpTimer.CompareTo(new TimeSpan(0,0,0,0,500)) <= 1
    will be always true and draw at the most 1 frame.

    (Source: http://msdn.microsoft.com/en-us/library/3she1h3z.aspx)
     
    magnet18 likes this.
  5. magnet18

    Thread Starter Senior Member

    Dec 22, 2010
    1,232
    124
    OK, thankyou, that makes sense now.

    I made the modifications, and the sprite moves up smoothly now, but now it won't come back down. :/

    Code ( (Unknown Language)):
    1.  
    2.         protected override void Update(GameTime gameTime)
    3.         {
    4.             int MaxX =
    5.                 graphics.GraphicsDevice.Viewport.Width - myTexture.Width;
    6.             int MinX = 0;
    7.             int MaxY =
    8.                 graphics.GraphicsDevice.Viewport.Height - myTexture.Height;
    9.             int MinY = 0;
    10.             int gravity = 5;
    11.             var velocity = 0;
    12.  
    13.             UpdateJump();
    14.             // keyboard logic
    15.             KeyboardState newState = Keyboard.GetState();
    16.             TimeSpan jumpTimer = TimeSpan.Zero;
    17.  
    18.             if (newState.IsKeyDown(Keys.Escape))
    19.             {
    20.                 if (!oldState.IsKeyDown(Keys.Escape))
    21.                 {
    22.                     this.Exit();
    23.                 }
    24.             }
    25.  
    26.             if (newState.IsKeyDown(Keys.Left))
    27.             {
    28.                 if (spritePosition.X > MinX)
    29.                 {
    30.                     spritePosition.X = spritePosition.X - 2;
    31.                 }
    32.             }
    33.  
    34.             if (newState.IsKeyDown(Keys.Right))
    35.             {
    36.                 if (spritePosition.X < MaxX)
    37.                 {
    38.                     spritePosition.X = spritePosition.X + 2;
    39.                 }
    40.             }
    41.  
    42.             if (newState.IsKeyDown(Keys.Up) && oldState.IsKeyDown(Keys.Up) == false && spritePosition.Y >= MaxY && jumping == false)
    43.             {
    44.                 jumping = true;
    45.                 velocity = 30;
    46.             }
    47.  
    48.             if (jumping == true)
    49.             {
    50.                 jumpTimer += gameTime.ElapsedGameTime;
    51.                 if (jumpTimer.CompareTo(new TimeSpan(0, 0, 0, 0, 500)) == 1)
    52.                 {
    53.                     jumping = false;
    54.                     jumpTimer = TimeSpan.Zero;
    55.                 }
    56.                 spritePosition.Y -= gravity;
    57.             }
    58.  
    59.             if (spritePosition.Y < MaxY && jumping == false)
    60.             {
    61.                 spritePosition.Y += gravity;
    62.             }
    63.  
    64.             if (velocity > 0)
    65.             {
    66.                 velocity -= gravity;
    67.             }
    68.  
    69.             if (spritePosition.Y >= MaxY)
    70.             {
    71.                 spritePosition.Y = MaxY;
    72.             }
    73.  
    74.             if (spritePosition.Y <= MinY)
    75.             {
    76.                 spritePosition.Y = MinY;
    77.             }
    78.  
    79.             // Move the sprite by speed, scaled by elapsed time.
    80.  
    81.  
    82.  
    83.  
    84.  
    85.             base.Update(gameTime);
    86.             oldState = newState;
    87.         }
    88.  
    any idea why?
     
  6. Filox

    New Member

    Oct 11, 2011
    7
    4
    Because in the Update method you reset the counter to zero which means that your bool variable jumping is true and the jumpTimer never reaches 500 miliseconds to stop the jumping. Declare it in the start of your class and not in the Update method.
     
    magnet18 likes this.
  7. magnet18

    Thread Starter Senior Member

    Dec 22, 2010
    1,232
    124
    *Facepalm*
    Thankyou!!!
     
Loading...