• Create Account

2D Platformer fps/Independent- time based movement

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

6 replies to this topic

#1EusKoder  Members   -  Reputation: 127

Like
0Likes
Like

Posted 08 August 2012 - 02:44 AM

Hello, I am developing a 2d platform game with XNA and the starter kit plataformer of msdn.
The fact is that I could use the method of physics that brings the starter kit, (thought they were independent of fps) but to start porting the game to linux by monoGame and lowered fps (windows 63, Ubuntu / Kubuntu 57-59) I then checked that the player did not move properly.

The funny part is that the enemies are moving properly, it have only movement in the x axis.

Now being tested in windows disabling Vertical Sync by:

[source lang="csharp"] graphics.SynchronizeWithVerticalRetrace = false; IsFixedTimeStep = false;[/source]

I leave the pieces of code relevant to them a look.
I believe that these method would be involved:

ApplyPhysics

[source lang="csharp"] public void ApplyPhysics(GameTime gameTime) { float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; Vector2 previousPosition = Position; // Base velocity is a combination of horizontal movement control and // acceleration downward due to gravity. velocity.X += movement * MoveAcceleration * elapsed; velocity.Y = MathHelper.Clamp(velocity.Y + GravityAcceleration * elapsed, -MaxFallSpeed, MaxFallSpeed); velocity.Y = DoJump(velocity.Y, gameTime); // Apply pseudo-drag horizontally. if (IsOnGround) velocity.X *= GroundDragFactor; else velocity.X *= GroundDragFactor; //velocity.X *= AirDragFactor; // Prevent the player from running faster than his top speed. velocity.X = MathHelper.Clamp(velocity.X, -MaxMoveSpeed, MaxMoveSpeed); // Apply velocity. Position += velocity *elapsed; Position = new Vector2((float)Math.Round(Position.X), (float)Math.Round(Position.Y)); // If the player is now colliding with the level, separate them. HandleCollisions(gameTime); // If the collision stopped us from moving, reset the velocity to zero. if (Position.X == previousPosition.X) velocity.X = 0; if (Position.Y == previousPosition.Y) { velocity.Y = 0; jumpTime = 0.0f; } }[/source]

I'm trying to simplify character movement putting it as the enemy,

[source lang="csharp"] Vector2 velocity = new Vector2((int)direction * MoveSpeed * elapsed, 0.0f); position = position + velocity;[/source]

but then come the problems of collisions of the character in both axes (X, Y) ...

Attached to the post player and enemy classes of my project.

I would appreciate a little help from someone who is put in the subject, thanks in advance for your time and sorry for my bad English ;).

Attached Files

Edited by EusKoder, 08 August 2012 - 04:00 AM.

#2Jebbs  Members   -  Reputation: 280

Like
1Likes
Like

Posted 08 August 2012 - 06:28 PM

Now, I could be wrong, but I am pretty sure that everything the GameTime class returns is going to be an int. To get the correct elapsed time, I would instead get the milliseconds and divide by 1000.

Edit:

I was mistaken! gameTime.ElapsedGameTime.TotalSeconds; does indeed return a floating point number. Will continue to look at the code to see if I can see anything!

Edited by Jebbles, 08 August 2012 - 11:04 PM.

#3yewbie  Members   -  Reputation: 677

Like
1Likes
Like

Posted 10 August 2012 - 10:41 AM

Do you ApplyPhysics() every frame?

Also how are movement and MoveAcceleration defined?

#4EusKoder  Members   -  Reputation: 127

Like
1Likes
Like

Posted 12 August 2012 - 09:57 AM

ApplyPhysics () is executed in each Update() of Player.cs class which in turn runs on each Update() of Level.cs which in turn runs on each Update () of Game1.cs.
Yes, ApplyPhysics () is executed for every frame of the game.

movement keeps the direction in which the character moves (later is multiplied by moveAcceleration) -1 (left), 0 (not moving), 1 (right).
moveAcceleration keeps the acceleration, which later is multiplied by the number of seconds since the last frame.

[source lang="csharp"] /// <summary> /// Current user movement input. /// </summary> private float movement; public float Movement { set { movement = value; } } // For controling horizontal movement private float MoveAcceleration = 15000.0f; public float Move_Acceleration { get { return MoveAcceleration; } }[/source]

You can download the two classes (Player, Enemy) from the link I put in the post (Attached Files) to see all the code.

Edited by EusKoder, 12 August 2012 - 10:01 AM.

#5yewbie  Members   -  Reputation: 677

Like
-1Likes
Like

Posted 13 August 2012 - 04:36 PM

I looked through your code and the only thing I am a little unsure of is:

float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

Does this return milliseconds as well or a just seconds?
IE: 0.0033 seconds or just 1 second, IE whats the resolution of this timer?

I would check the value of TotalSeconds on runtime on both platforms and see if you get similar results.

Also (correct me if I am wrong) gameTime.ElapsedGameTime.TotalSeconds is a XNA thing when you ported it over what did you change it to?

#6EusKoder  Members   -  Reputation: 127

Like
0Likes
Like

Posted 16 September 2012 - 09:25 AM

Note, the GameTime object stores the elapsed and total time as a TimeSpan:
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.gametime_members.aspx
TimeSpan object store the units broken up in integer values:
http://msdn.microsoft.com/en-us/library/system.timespan.aspx
So the seconds property is a WHOLE number. It represents the current seconds as a part of the timespan. So a Timespan representing 2 mins, 30 secs, 123 milliseconds, would return 30 for seconds from the Seconds property... not 150.123.
If you want ALL the seconds as a fracitonal value you access the TimeSpan.TotalSeconds property, which is a double. There are also TotalMilliseconds, Minutes, Hours, and Days...
So the TotalSeconds property on the other hand would return 150.123 for the previously mentioned TimeSpan.

Edited by EusKoder, 16 September 2012 - 09:26 AM.

#7yewbie  Members   -  Reputation: 677

Like
0Likes
Like

Posted 17 September 2012 - 04:05 PM

If you want ALL the seconds as a fracitonal value you access the TimeSpan.TotalSeconds property, which is a double. There are also TotalMilliseconds, Minutes, Hours, and Days...
So the TotalSeconds property on the other hand would return 150.123 for the previously mentioned TimeSpan.

I wasn't being authoritative with my response but thanks for the downvotes anyway. =)

You solved your problem by comparing the timing between two hardware platforms and determined that gameTime.ElapsedGameTime.TotalSeconds was running at a different speed because of the monitors refresh rate. (In case anyone else looks at this in the future)

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS