1
\$\begingroup\$

UPDATE 2: I've tried to pass in GameTime to my Update method, just as I did for the bats, but I'm not seeing any change to the ball's speed. I've also changed my moveSpeed to:

*moveSpeed += (15f * elapsedTime);*

where previously it was simply moveSpeed += 15f; and it still hasn't yielded any results. What could I be doing wrong?

Class Ball
{ 

   public void UpdatePosition(GameTime gameTime)
    {
        elapsedTime = 50.0f * (float)gameTime.ElapsedGameTime.TotalSeconds;

        size.X = (int)position.X;
        size.Y = (int)position.Y;
        oldPos.X = position.X;
        oldPos.Y = position.Y;
        position.X += speed * ((float)Math.Cos(direction));
        position.Y += speed * ((float)Math.Sin(direction));
        bool collided = CheckWallHit();
        particleEngine.Update();

        previous = current;
        current = Keyboard.GetState();
        if (current.IsKeyDown(Keys.Z))
        {
            elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds * 5.0f;
        }       

        /// <summary>
    /// Check for the ball to return normal speed after the Powerup has expired
    /// </summary>
    public void NormalSpeed(GameTime gameTime)
    {
        moveSpeed += (15f * elapsedTime);
    }
 }

UPDATE:

I seem to have found a temporary solution, by using the follow method, however I am not sure of where I should place ElapsedTime so that it affects ALL of my classes and their updates (ex: the ball as well). As it stands, when I hit Z the bat will slow down because I am changing the ElapsedTime float, but I think I may have figured out a way to allow the ball to use it too. I may just have the Z key turn float down from 50 into 5 in all classes when pressed:

        /// <summary>
    /// Updates the position of the AI bat, in order to track the ball
    /// </summary>
    public virtual void UpdatePosition(Ball ball, GameTime gameTime)
    {
        size.X = (int)Position.X;
        size.Y = (int)Position.Y;

       elapsedTime =  50.0f * (float)gameTime.ElapsedGameTime.TotalSeconds;

       previous = current;
       current = Keyboard.GetState();
       if (current.IsKeyDown(Keys.Z))
       {
           elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds * 5.0f;
       }         
     }

        /// <summary>
    /// Controls the bat moving up the screen
    /// </summary>
    public void MoveUp()
    {
        SetPosition(Position + new Vector2(0, -moveSpeed * elapsedTime));

    }

I'm trying to create a slow-mo effect in my pong game so that when a player is a button the paddles and ball will suddenly move at a far slower speed. I believe my understanding of the concepts of adjusting the timing in XNA are done, but I'm not sure of how to incorporate it into my design exactly.

The updates for my bats (paddles) are done in my Bat.cs class:

        /// Controls the bat moving up the screen
    /// </summary>
    public void MoveUp()
    {
        SetPosition(Position + new Vector2(0, -moveSpeed));
    }

    /// <summary>
    /// Controls the bat moving down the screen
    /// </summary>
    public void MoveDown()
    {
        SetPosition(Position + new Vector2(0, moveSpeed));
    }

    /// <summary>
    /// Updates the position of the AI bat, in order to track the ball
    /// </summary>
    /// <param name="ball"></param>
    public virtual void UpdatePosition(Ball ball)
    {
        size.X = (int)Position.X;
        size.Y = (int)Position.Y;
    }

While the rest of my game updates are done in my GameplayScreen.cs class (I'm using the XNA game state management sample)

Class GameplayScreen
{
        ...........
        bool slow;
        ..........
      public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) 

  base.Update(gameTime, otherScreenHasFocus, false);

     if (IsActive)
            {
                // SlowMo Stuff
                Elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
                if (Slowmo) Elapsed *= .8f;

                MoveTimer += Elapsed;

                    double elapsedTime = gameTime.ElapsedGameTime.TotalMilliseconds;

                if (Keyboard.GetState().IsKeyDown(Keys.Up))
                    slow = true;
                else if (Keyboard.GetState().IsKeyDown(Keys.Down))
                    slow = false;

                    if (slow == true)
                    elapsedTime *= .1f;

                    // Updating bat position
                leftBat.UpdatePosition(ball);
                rightBat.UpdatePosition(ball);

                // Updating the ball position
                ball.UpdatePosition();

and finally my fixed time step is declared in the constructor of my Game1.cs Class:

    /// <summary>
/// The main game constructor.
/// </summary>
public Game1()
{
    IsFixedTimeStep = slow = false;

}

So my question is: Where do I place the MoveTimer or elapsedTime, so that my bat will slow down accordingly?

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for the assistance everyone. I seem to have found a suitable solution (for now) which I will update above. But I am left with one question. \$\endgroup\$ Commented Jun 25, 2012 at 11:00

4 Answers 4

1
\$\begingroup\$

I'm currently on my smartphone so can't provide a lengthy awnser right now.

Implementing slowmotion is as easy as this :

Leftbat.x += (leftbat.speedX * gametime.ElapsedSeconds) * 0.1; //0.1 is 10% of original speed

You don't have to modify the elapsedtime variable itself.

\$\endgroup\$
2
  • \$\begingroup\$ I applaud you for being able to do all of that on your phone! And thank you for answering my question. I guess my follow up to that answer is, where do I put this exactly? Is is it going within my UpdatePosition() method in my Bat.cs class, or somewhere within my Update() method in my GameplayScreen.cs class? \$\endgroup\$ Commented Jun 24, 2012 at 19:41
  • \$\begingroup\$ I would guess in your UpdatePosition function: position.X += (speed * ((float)Math.Cos(direction))) * elapsedTime) * 0.1f; \$\endgroup\$
    – omgnoseat
    Commented Jun 25, 2012 at 19:47
1
\$\begingroup\$

You only need to multiply your velocity vector by the time to know the offset, this way if time is smaller, then the offset applied to the position will be smaller too:

public void MoveUp()
{
    SetPosition(Position + new Vector2(0, -moveSpeed) * ElapsedTime);
}

public void MoveDown()
{
    SetPosition(Position + new Vector2(0, moveSpeed ) * ElapsedTime);
}

EDIT:

I'd pass the elapsedtime as a function argument, doing something like this

Vector2[] Directions = { Vector.UnitX, -Vector.UnitX, Vector.UnitY, -Vector.UnitY }
enum Direction { Right, Left, Down, Up };
public void Move(Direction dir, float ElapsedTime) {
   SetPosition(Position + Directions[(int)dir] * moveSpeed * ElapsedTime);
}

EDIT FOR UPDATE2:

I think you are a bit confused... :) ,

you are doing

 position.X += speed * ((float)Math.Cos(direction))

if speed is constant, the ball will move at constant speed. I can see:

public void NormalSpeed(GameTime gameTime)
{
    moveSpeed += (15f * elapsedTime);
}

but yor not using moveSpeed, you are using speed to modify position. :? and you are adding speed in method named normalspeed ... I can't understand what are you doing... :(

I'd do it this way:

public void UpdatePosition(GameTime gameTime)
{
    float newSpeed = default_speed;  
    float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

    // Update position
    size.X = (int)position.X;
    size.Y = (int)position.Y;
    oldPos.X = position.X;
    oldPos.Y = position.Y;

    if (ActivePowerUps.Contains(PowerUp.SlowDown))
    {
        newSpeed *= 0.5f; // 50% slowdown
    }

    position.X += newSpeed * ((float)Math.Cos(direction));
    position.Y += newspeed * ((float)Math.Sin(direction));
    bool collided = CheckWallHit();
    particleEngine.Update();
}

public void UpdatePowerUps()
{
    previous = current;
    current = Keyboard.GetState();

    if (!ActivePowerUps.Contains(PowerUp.SlowDown))
    {            
      if (current.IsKeyDown(Keys.Z)) ActivePowerUps.Add(PowerUp.SlowDown);           
    }
}

public void RemovePowerUp(PowerUp power)
{
    if (ActivePowerUps.Contains(power)) ActivePowerUps.remove(power);
}
\$\endgroup\$
4
  • \$\begingroup\$ Hmmmm I think I'm getting there. So declare ElapsedTime as "public float ElapsedTime();" in my GameplayScreen class, an then my MoveDown() method should actually read: "SetPosition(Position + new Vector2(0, moveSPeed * GameplayScreen.Instance.ElapsedTime));" Is that correct? \$\endgroup\$ Commented Jun 25, 2012 at 1:13
  • \$\begingroup\$ I prefer to pass it as a function argument, it will do things easier... you can call UpdatePosition with a reduction factor only for the ball... like ball.UpdatePosition(ElapsedSeconds*0.5f), and then only that ball is affected by the speed reduction \$\endgroup\$
    – Blau
    Commented Jun 25, 2012 at 6:32
  • \$\begingroup\$ I'll have to look further into how to do that. As it stands, I'm trying to pass in GameTime for the ball's update method, but am not seeing any results. I'm doing this very similar to what I did for the bats, which work fine however. I can't write code here, so I'll list it above. \$\endgroup\$ Commented Jun 25, 2012 at 16:47
  • \$\begingroup\$ You were correct. I was using MoveSpeed and speed for some reason. Not sure why I had two separate floats in there. I was briefly working on this with someone else at one point when they added the powerups and I guess that's why there are two variables for speed. The fix was EXTREMELY easy. I simply made "speed" my speed for the ball. I created a public void SlowMoSpeed() { speed = 2f; } and placed that inside Update. When I press Z, the ball comes to a crawl. It was the speed vs MoveSpeed that threw me off. Thanks guys! \$\endgroup\$ Commented Jun 25, 2012 at 21:25
0
\$\begingroup\$

you can do like above using a multiplication factor. However it should be noted, you do not want to change the elapsed time (you can't I don't think anyway) because it refers to the actual FPS of the game and that is the worst way to affect in game time.

\$\endgroup\$
0
\$\begingroup\$

I thought I had answered this the other day, but I guess it didn't go through for some reason.

Thank you all for taking the time to help me. My problem was that I had two floats for determining how quickly my ball was traveling, for some reason. I had speed and moveSPeed. I'm not sure why I ever had this, but it was casing issues. Therefore everything is just using speed now and it looks like this:

        ///<summary>
    ///Used for slowing down the ball when SlowMo is active
    ///</summary>
    public void SlowMoBall()
    {
        speed = 2f;
    }
\$\endgroup\$
1
  • \$\begingroup\$ I think you are not fair giving this as the right answer \$\endgroup\$
    – Blau
    Commented Jun 27, 2012 at 23:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .