I am building a news ticker that needs to be implemented on Blackberry 5. When transitioning from one element to the next, I am looking at a fade out/fade in transition. Mostly because I am having trouble finding resources on creating animations in the Blackberry 5 reference.
the basic flow I am looking at is:
public void updateUI() {
//fade out
//set values
//fade in
}
So far I have all the UI elements contained inside a HorizontalFieldManager. I have tried digging through the Field and Graphics documents, but did not find what I was looking for.
Keep in mind, supporting Blackberry 5 is the client's requirement, not mine.
You need to handle animations explicitly, using a timer for transitions.
My typical solution is something like this (inside the paint() method):
final long time = System.currentTimeMillis();
final int alpha;
if (startFadeIn != 0) {
alpha = (int) Math.min((time - startFadeIn) / SPEED, 255);
if (alpha < 255) {
invalidate();
}
} else if (startFadeOut != 0) {
alpha = (int) Math.max(255 + (startFadeOut - time) / SPEED, 0);
if (alpha > 0) {
invalidate();
}
} else {
alpha = 255;
}
graphics.setGlobalAlpha(alpha);
It burns some CPU cycles (for a short time), but it works.
Related
I posted this question three days ago, but I received the feedback that the question was not clear so I would like to ask again. Also, the scope of the problem has changed as I researched it further (no Unity issue!)
I'm making a game for iOS where you rotate an object left and right by touching the left or right side of the screen. The Object rotates as long as the display is touched and stops rotating when the touch ends. When I run the game on an actual iPad/iPhone for a while every few touches the Rotation of the Objects stutters for about 2 seconds. This happends in about 5% of the touches. All other touches work perfectly smooth.
All other Game Actions work fine at the set frame rate of 60 fps. The only thing that doesn't move smoothly is the rotated object, while the rest of the game is all running perfectly smooth. I tried to visualize the problem on the attached image. See here
It visually looks like the Touch Refresh Rate is freezed for two seconds.
What may be the cause for this and how do I fix this?
I created the game with the game engine Unity. I use these versions:
- Unity: 2019.3.15f1
- Xcode: 11
- Device: iPhone x
- iOS Version: 13.5.1
After a lot of research I found out, that this is not an issue related to Unity. Also, there is no issue when building the game on an Android device.
Steps to reproduce:
int rotation
private void FixedUpdate(){
for (int i = 0; i < Input.touchCount; i++)
{
Vector3 touchPos = Camera.main.ScreenToWorldPoint(Input.touches[i].position);
if (touchPos.x < 0)
{
rotation += 10;
}
else if (touchPos.x > 0)
{
rotation -= 10;
}
}
transform.Rotate(0, 0, rotation);
rotation = 0;
}
Coding the Touch Input via c# in Unity (see above)
Building the Project on iOS Platform (creating an xcodeproject)
Open the Project in XCode and running it on the iPhone
Does anybody have a solution for this?
Any "Input" class should be called in Update(), instead of FixedUpdate().
The Input data loss is expected if you are trying to get them in FixedUpdate().
Just for example, FixedUpdate can be execute twice in one frame, or skipped in one frame. That's how it causes data lost or inaccurate.
The proper solution will be sth like below.
int rotation
private void Update()
{
for (int i = 0; i < Input.touchCount; i++)
{
Vector3 touchPos = Camera.main.ScreenToWorldPoint(Input.touches[i].position);
if (touchPos.x < 0)
{
rotation += 10 * time.deltaTime;
}
else if (touchPos.x > 0)
{
rotation -= 10 * time.deltaTime;
}
}
transform.Rotate(0, 0, rotation);
rotation = 0;
}
and please be noted that your current rotation direction is determined by a ray casting from camera.
If you want to rotate left/right by screen space, this should work better.
private void Update()
{
int rotation = 0;
for (int i = 0; i < Input.touchCount; i++)
{
if (Input.touches[i].position.x < Screen.width/2)
{
rotation += 10 * time.deltaTime;
}
else
{
rotation -= 10 * time.deltaTime;
}
}
transform.Rotate(0, 0, rotation);
}
In general, I prefer a simple rotation script by checking last touch.
private void Update()
{
if(Input.touchCount > 0)
{
if (Input.touches[Input.touchCount-1].position.x < Screen.width/2)
{
transform.Rotate(0, 0, 10f * time.deltaTime);
}
else
{
transform.Rotate(0, 0, -10f * time.deltaTime);
}
}
}
Or, if you really want to sync the input with FixedUpdate(), you can do sth like below.
bool HasTouch = false;
float SpeedRot = 0;
private void Update()
{
if(Input.touchCount > 0)
{
HasTouch = true;
if (Input.touches[Input.touchCount-1].position.x < Screen.width/2)
{
SpeedRot = 10f;
}
else
{
SpeedRot = -10f;
}
}
else
{
HasTouch = false;
}
}
private void FixedUpdate()
{
if(HasTouch) transform.Rotate(0, 0, SpeedRot * Time.fixedDeltaTime);
}
The task at hand is to add a band selection tool to a Dart WebGL application.
The tool will be used to draw a rectangle over multiple objects by dragging the mouse.
Thus multiple objects can be selected/picked in a single user action.
I'm currently using gl.readPixels() to read colors from an off-screen renderbuffer.
Problem is, when a large area is band-selected, gl.readPixels() issues millions of pixels.
Scanning such a big amount of colors wastes precious seconds just to locate few objects.
Please anyone point possibly faster methods for band-selecting multiple objects with Dart+WebGL.
For reference, I show below the current main portion of the band selection tool.
Uint8List _color = new Uint8List(4);
void bandSelection(int x, y, width, height, PickerShader picker, RenderingContext gl, bool shift) {
if (picker == null) {
err("bandSelection: picker not available");
return;
}
int size = 4 * width * height;
if (size > _color.length) {
_color = new Uint8List(size);
}
gl.bindFramebuffer(RenderingContext.FRAMEBUFFER, picker.framebuffer);
gl.readPixels(x, y, width, height, RenderingContext.RGBA, RenderingContext.UNSIGNED_BYTE, _color);
if (!shift) {
// shift is released
_selection.clear();
}
for (int i = 0; i < size; i += 4) {
if (_selection.length >= picker.numberOfInstances) {
// selected all available objects, no need to keep searching
break;
}
PickerInstance pi = picker.findInstanceByColor(_color[i], _color[i+1], _color[i+2]);
if (pi == null) {
continue;
}
_selection.add(pi);
}
debug("bandSelection: $_selection");
}
// findInstanceByColor is method from PickerShader
PickerInstance findInstanceByColor(int r, g, b) {
return colorHit(_instanceList, r, g, b);
}
PickerInstance colorHit(Iterable<Instance> list, int r,g,b) {
bool match(Instance i) {
Float32List f = i.pickColor;
return (255.0*f[0] - r.toDouble()).abs() < 1.0 &&
(255.0*f[1] - g.toDouble()).abs() < 1.0 &&
(255.0*f[2] - b.toDouble()).abs() < 1.0;
}
Instance pi;
try {
pi = list.firstWhere(match);
} catch (e) {
return null;
}
return pi as PickerInstance;
}
Right now I can see small solutions that might speed up your algorithm to limit as much as possible iterating over all of your elements,
The first thing you can do is have a default colour. When you see that colour, you know you don't need to iterate all over your array of elements.
It will accelerate large poorly populated areas.
It's very easy to implement, just adding a if.
For more dense areas you can implement some kind of colour caching. That means you store an array of colour you encountered. When you check a pixel, you first check the cache and then go over the entire list of elements, and if you find the element, add it to the cache.
It should accelerate cases with few big elements but will be bad if you have lots of small elements, which is very unlikely if you have picking...
You can accelerate your cache buy sorting your cached elements by last hit or/and by number of hits, it's very likely to find the same element in a continuous raw of pixels.
It's more work but stays relatively easy and short to implement.
Last optimisation would be to implement a space partitioning algorithm to filter the elements you want to check.
That would be more work but will pay better of on the long run.
edit :
I'm not a dart guy but this is how it would look like to implement in a basic way the first two optimisations:
var cache = new Map<UInt32, PickerInstance>();
for (int i = 0; i < size; i += 4) {
UInt32 colour = _color[i] << 24 | _color[i+1] << 16 | _color[i+2] << 8 | 0; // I guess we can just skip transparency.
if (_selection.length >= picker.numberOfInstances) {
// selected all available objects, no need to keep searching
break;
}
// black is a good default colour.
if(colour == 0) {
// if the pixel is black we didn't hit any element :(
continue;
}
// check the cache
if(cache[colour] != null) {
_selection.add(cache[colour]);
continue;
}
// valid colour and cache miss, we can't avoid iterating the list.
PickerInstance pi = picker.findInstanceByColor(_color[i], _color[i+1], _color[i+2]);
if (pi == null) {
continue;
}
_selection.add(pi);
// update cache
cache[colour] = pi;
}
Im using a technique to control a sprite by rotating left/right and then accelerating forward. I have 2 questions regarding it. (The code it pasted together from different classes due to polymorphism. If it doesn't make sense, let me know. The movement works well and the off screen detection as well.)
When player moves off screen i call the Bounce method. I want the player not to be able to move off screen but to change direction and go back. This works on top and bottom but left and right edge very seldom. Mostly it does a wierd bounce and leaves the screen.
I would like to modify the accelerate algorithm so that i can set a max speed AND a acceleration speed. Atm the TangentalVelocity does both.
float TangentalVelocity = 8f;
//Called when up arrow is down
private void Accelerate()
{
Velocity.X = (float)Math.Cos(Rotation) * TangentalVelocity;
Velocity.Y = (float)Math.Sin(Rotation) * TangentalVelocity;
}
//Called once per update
private void Deccelerate()
{
Velocity.X = Velocity.X -= Friction * Velocity.X;
Velocity.Y = Velocity.Y -= Friction * Velocity.Y;
}
// Called when player hits screen edge
private void Bounce()
{
Rotation = Rotation * -1;
Velocity = Velocity * -1;
SoundManager.Vulture.Play();
}
//screen edge detection
public void CheckForOutOfScreen()
{
//Check if ABOVE screen
if (Position.Y - Origin.Y / 2 < GameEngine.Viewport.Y) { OnExitScreen(); }
else
//Check if BELOW screen
if (Position.Y + Origin.Y / 2 > GameEngine.Viewport.Height) { OnExitScreen(); }
else
//Check if RIGHT of screen
if (this.Position.X + Origin.X / 2 > GameEngine.Viewport.Width) { OnExitScreen(); }
else
//Check if LEFT of screen
if (this.Position.X - Origin.X / 2 < GameEngine.Viewport.X) { OnExitScreen(); }
else
{
if (OnScreen == false)
OnScreen = true;
}
}
virtual public void OnExitScreen()
{
OnScreen = false;
Bounce();
}
Let's see if I understood correctly. First, you rotate your sprite. After that, you accelerate it forward. In that case:
// Called when player hits screen edge
private void Bounce()
{
Rotation = Rotation * -1;
Velocity = Velocity * -1; //I THINK THIS IS THE PROBLEM
SoundManager.Vulture.Play();
}
Let's suposse your sprite has no rotation when it looks up. In that case, if it's looking right it has rotated 90º, and its speed is v = (x, 0), with x > 0. When it goes out of the screen, its rotation becomes -90º and the speed v = (-x, 0). BUT you're pressing the up key and Accelerate method is called so immediately the speed becomes v = (x, 0) again. The sprite goes out of the screen again, changes its velocity to v = (-x, 0), etc. That produces the weird bounce.
I would try doing this:
private void Bounce()
{
Rotation = Rotation * -1;
SoundManager.Vulture.Play();
}
and check if it works also up and bottom. I think it will work. If not, use two different Bounce methods, one for top/bottom and another one for left/right.
Your second question... It's a bit difficult. In Physics, things reach a max speed because air friction force (or another force) is speed-dependent. So if you increase your speed, the force also increases... at the end, that force will balance the other and the speed will be constant. I think the best way to simulate a terminal speed is using this concept. If you want to read more about terminal velocity, take a look on Wikipedia: http://en.wikipedia.org/wiki/Terminal_velocity
private void Accelerate()
{
Acceleration.X = Math.abs(MotorForce - airFriction.X);
Acceleration.Y = Math.abs(MotorForce - airFriction.Y);
if (Acceleration.X < 0)
{
Acceleration.X = 0;
}
if (Acceleration.Y < 0)
{
Acceleration.Y = 0;
}
Velocity.X += (float)Math.Cos(Rotation) * Acceleration.X
Velocity.Y += (float)Math.Sin(Rotation) * Acceleration.Y
airFriction.X = Math.abs(airFrictionConstant * Velocity.X);
airFriction.Y = Math.abs(airFrictionConstant * Velocity.Y);
}
First, we calculate the accelartion using a "MotorForce" and the air friction. The MotorForce is the force we make to move our sprite. The air friction always tries to "eliminate" the movement, so is always postive. We finally take absolute values because the rotation give us the direction of the vector. If the acceleration is lower than 0, that means that the air friction is greater than our MotorForce. It's a friction, so it can't do that: if acceleration < 0, we make it 0 -the air force reached our motor force and the speed becomes constant.
After that, the velocity will increase using the acceleration. Finally, we update the air friction value.
One thing more: you may update also the value of airFriction in the Deccelarate method, even if you don't consider it in that method.
If you have any problem with this, or you don't understand something (sometimes my English is not very good ^^"), say it =)
I'm working on a windows phone 7 project, with silverlight, and i'm trying to show 4 images in sequence to give the user the feeling of a short movie.
I have 4 urls pointing to 4 different jpeg images, and I'm using an Image control to show these jpeg in sequence.
The way I'm trying to achieve this is by doing:
private void RetrieveImages()
{
image1.ImageOpened += new EventHandler<RoutedEventArgs>(image1_ImageOpened);
frameNumber = 0;
gotoNextImage();
}
void image1_ImageOpened(object sender, RoutedEventArgs e)
{
System.Threading.Thread.Sleep(400);
gotoNextImage();
}
private void gotoNextImage()
{
if (frameNumber < 4)
{
webBrowser1.Dispatcher.BeginInvoke(()=> {
image1.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri(cam.framesUrl[frameNumber]));
frameNumber++;
});
}
else
{
image1.ImageOpened -= image1_ImageOpened;
}
}
But this just don't work as expected. I'm sure I'm missing something about how to interact with the UI.
Can anyone point me in the right direction?
Which is the best way to achieve this?
Edited:
I'll explain better what's wrong with my code... probably it's unclear what happens.
I don't get any error with my code, but I don't see the "movie effect" too. It just show 1 single image, without iterating between the image collection.
I think it's a threading problem... kind of I'm not doing the right thing in the right thread to see the UI updating as expected...
This seams to work best.
xaml
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="YourNamspace.YourClass"
d:DesignWidth="24"
d:DesignHeight="24">
<Grid x:Name="LayoutRoot">
<Image Name="YourImageName" Stretch="Fill" Source="YourPath" ImageOpened="onImageOpened"/>
</Grid>
</UserControl>
C#
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
namespace YourNameSpace
{
public partial class YourClass : UserControl
{
public int FirstImageIndex = 1;
public int LastImageIndex = 1000;
public int CurrentImageIndex = 1;
public YourClass()
{
InitializeComponent();
}
private void onImageOpened(object sender, System.Windows.RoutedEventArgs e)
{
Thread.Sleep(1000);
CurrentImageIndex = ( CurrentImageIndex == LastImageIndex ) ? FirstImageIndex : CurrentImageIndex++;
YourImageName.Source = new BitmapImage(new Uri("Your/path/to/image"+CurrentImageIndex+".jpg"), UriKind.RelativeOrAbsolute);
}
}
}
Hope that helps. I am pretty new to Silverlight.
So far the best way is to define the image as a resource. Via converter setting the image source.
But, your code should work fine as well. Try setting UriKind.RelativeOrAbsolute may be that should help. Because, this is the most common area while setting image source causes issue
HTH
Ok, I figured it out, and I think I also find a nice solution :) IMHO
I basically bound the Image.source to a proprerty of my class (that now extends INotifyPropertyChanged). But this gave me some issue about the transiction between images: since they were downloaded from internet there was a black images occurring between one images an the next one... but only the first time (i'm looping on a set of 4 images, looks like the video repeat), 'cause after that the images are cached.
So, what I've done is to cache the images the first time, without displaying the right Image control, but displaying instead another Image control (or whatever else) which says to the user "I'm loading".
For handle this scenario I've created a custom event:
public delegate void FramesPrefetchedEventHanlder();
public event FramesPrefetchedEventHanlder FramesPrefetched;
Now let's take a look at the RetrieveImages method:
private void RetrieveImages()
{
frameNumber = 0;
currentCycle = 0;
// set e very short interval, used for prefetching frames images
timer.Interval = new TimeSpan(0, 0, 0, 0, 10);
timer.Tick += (sender, e) => gotoNextImage();
// defines what is going to happen when the prefetching is done
this.FramesPrefetched += () =>
{
// hide the "wait" image and show the "movie" one
imageLoading.Opacity = 0;
image1.Opacity = 1;
// set the timer with a proper interval to render like a short movie
timer.Interval = new TimeSpan(0, 0, 0, 0, 400);
};
// when a frame is loaded in the main Image control, the timer restart
image1.ImageOpened += (s, e) =>
{
if (currentCycle <= cycles) timer.Start();
};
// start the loading (and showing) frames images process
gotoNextImage();
}
Ok, now what we need to handle is the step by step loading of the image and communicate when we finished the prefetching phase:
private void gotoNextImage()
{
timer.Stop();
if (frameNumber < 4)
{
CurrentFrame = new System.Windows.Media.Imaging.BitmapImage(new Uri(cam.framesUrl[frameNumber]));
frameNumber++;
}
else
{
// repeat the frame's sequence for maxCycles times
if (currentCycle < maxCycles)
{
frameNumber = 0;
currentCycle++;
// after the first cycle through the frames, raise the FramesPrefetched event
if (currentCycle == 1)
{
FramesPrefetchedEventHanlder handler = FramesPrefetched;
if (handler != null) handler();
}
// step over to next frame
gotoNextImage();
}
}
}
This works pretty fine to me... but since I'm new to Silverlight and Windows Phone 7 developement, any suggestion for improvement is welcome.
I wrote a component to display current FPS.
The most important part of it is:
public override void Update(GameTime gameTime)
{
elapseTime += (float)gameTime.ElapsedRealTime.TotalSeconds;
frameCounter++;
if (elapseTime > 1)
{
FPS = frameCounter;
frameCounter = 0;
elapseTime = 0;
}
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
spriteBatch.DrawString(font, "FPS " + ((int)FPS).ToString(), position, color, 0, origin, scale, SpriteEffects.None, 0);
spriteBatch.End();
base.Draw(gameTime);
}
In most cases it works ok, but recently I had a problem.
When I put following code into Update method of game strange thing starts to happen.
if (threadPath == null || threadPath.ThreadState != ThreadState.Running)
{
ThreadStart ts = new ThreadStart(current.PathFinder.FindPaths);
threadPath = new Thread(ts);
threadPath.Priority = ThreadPriority.Highest;
threadPath.Start();
}
Main idea of this code is to run pathFinding algorithm in different thread all the time.
By strange things I mean that sometimes FPS drasticly decreases, this is obvious, but displayed FPS changes more often than once a second. If I understand this code FPS can't change more often than once a second.
Can someone explain me what's going on?
Edit 26.03.2010
I've posted also code of Draw method.
Edit 31.03.2010 Answers to Venesectrix questions
1) are you running with a fixed or variable time step?
IsFixedTimeStep and SynchronizeWithVerticalRetrace is set to true.
2)Were you moving the XNA window around when this occurred?
No
3)Did the XNA window have focus?
Yes
4) How noticeable was it (ie, updating so fast you can't read it, or just barely updating more than a second)?
I was able to read updates, FPS was updating ~3 times a second.
5) And all of this only happens with the thread code in there?
Yes
Shawn Hargreaves has a great post about this here. The first difference I see between his code and yours is the fact that you reset your elapseTime to 0 each time, which will lose some time, whereas Shawn just subtracts 1 second from his elapsedTime. Also, Shawn uses ElapsedGameTime instead of ElapsedRealTime. He updates his frameCounter in the Draw function instead of the Update function as well.
As far as why he uses ElapsedRealTime, he explains it in a comment after the post:
> Surely 1 / gameTime.ElapsedRealTime.TotalSeconds
> will therefore give the current framerate.
That will tell you how long it was
since the previous call to Update, but
that is not the same thing as your
framerate!
a) If the game is dropping frames,
Update will be called more frequently
in order to catch up. You want to time
the number of actual draws that are
taking place, not just these extra
catch-up logic frames.
b) The time for a single Update can
fluctuate widely, so the figure you
get out of that will be too flickery
to be easily readable.
I would try his component, and see if it works for you. The post is pretty old, and I think you will have to change LoadGraphicsContent to LoadContent and UnloadGraphicsContent to UnloadContent, as another one of the comments points out.
Here is how I do it and with this method:
You average over n Frames
You can use it with any initialization method you choose
It should be easy to read and follow
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace _60fps
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont OutputFont;
float Fps = 0f;
private const int NumberSamples = 50; //Update fps timer based on this number of samples
int[] Samples = new int[NumberSamples];
int CurrentSample = 0;
int TicksAggregate = 0;
int SecondSinceStart = 0;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
graphics.SynchronizeWithVerticalRetrace = false;
int DesiredFrameRate = 60;
TargetElapsedTime = new TimeSpan(TimeSpan.TicksPerSecond / DesiredFrameRate);
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
OutputFont = Content.Load<SpriteFont>("MessageFont");
}
protected override void UnloadContent()
{/* Nothing to do */}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape))
this.Exit();
base.Update(gameTime);
}
private float Sum(int[] Samples)
{
float RetVal = 0f;
for (int i = 0; i < Samples.Length; i++)
{
RetVal += (float)Samples[i];
}
return RetVal;
}
private Color ClearColor = Color.FromNonPremultiplied(20, 20, 40, 255);
protected override void Draw(GameTime gameTime)
{
Samples[CurrentSample++] = (int)gameTime.ElapsedGameTime.Ticks;
TicksAggregate += (int)gameTime.ElapsedGameTime.Ticks;
if (TicksAggregate > TimeSpan.TicksPerSecond)
{
TicksAggregate -= (int)TimeSpan.TicksPerSecond;
SecondSinceStart += 1;
}
if (CurrentSample == NumberSamples) //We are past the end of the array since the array is 0-based and NumberSamples is 1-based
{
float AverageFrameTime = Sum(Samples) / NumberSamples;
Fps = TimeSpan.TicksPerSecond / AverageFrameTime;
CurrentSample = 0;
}
GraphicsDevice.Clear(ClearColor);
spriteBatch.Begin();
if (Fps > 0)
{
spriteBatch.DrawString(OutputFont, string.Format("Current FPS: {0}\r\nTime since startup: {1}", Fps.ToString("000"), TimeSpan.FromSeconds(SecondSinceStart).ToString()), new Vector2(10,10), Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
As for:
"but the question why displayed FPS was changing more often than once a second is still open"
The difference between ElapsedGameTime and ElapsedRealTime is that "ElapsedGameTime" is the amount of time since the last time you entered the Update or Draw statement (depending on which "gameTime" you're using - the one from Update or the one from Draw).
ElapsedRealTime is the time since the game started. Because of this, it increases linearly as the game continues to run. Indeed, after 1 second, you'll update every frame because your logic looked like this:
(Let's assume you were running 4 fps for the sake of easy explanation):
Frame 1: ElapsedRealTime: 0.25. Running total now: 0.25
Frame 2: ElapsedRealTime: 0.5 Running total now: 0.75
Frame 3: ElapsedRealTime: 0.75 Running total now: 1.5
Running total greater than 1!!! Show FPS!
Set Running total = 0
Frame 4: ElapsedRealTime: 1.00 Running total now: 1.0
Running total greater than 1!!! Show FPS!
Now that you've fixed the counter, you should now only be getting Elapsed Game Time changes of a steady 0.25 so the progression now moves:
Frame 1: ElapsedGameTime: 0.25. Running total now: 0.25
Frame 2: ElapsedGameTime: 0.25 Running total now: 0.50
Frame 3: ElapsedGameTime: 0.25 Running total now: 0.75
Frame 4: ElapsedGameTime: 0.25 Running total now: 1.00
Running total greater than 1!!! Show FPS!
Set Running total = 0
Frame 5: ElapsedGameTime: 0.25. Running total now: 0.25
Frame 6: ElapsedGameTime: 0.25 Running total now: 0.50
Frame 7: ElapsedGameTime: 0.25 Running total now: 0.75
Frame 8: ElapsedGameTime: 0.25 Running total now: 1.00
Running total greater than 1!!! Show FPS!
Set Running total = 0
Which is what you're expecting. In short, now that you corrected the first problem, you should have corrected the second too and "why" is explained above.
As an aside ... you should avoid setting the thread priority. By assigning the highest thread priority to what should be a background thread, you could end up starving the main thread of cpu time because the scheduler would give priority to threadPath
Are you actively checking if IsRunningSlowly is being changed? Even with IsFixedTimeStep to true, if your program isn't able to do as many Updates as it expects, it will call it more frequently.
A way I have mitigated this before is by directly calling ResetElapsedTime() instead of keeping track of it yourself.
Not sure if that'll work for you though. I did notice that when i was debugging the previous issue I had, it wouldn't call the extra Updates, probably a 'feature' when debugging.
You should run your fps counter under the draw method
Hi guys if you want to show your real framerate you have to implement framerate counter to method Draw, because XNA do it like this:
"If your computer can't serve the method Update it suspend Draw method and instead of that it serve the Update method"