I'm trying to get a general smooth scrolling mechanism that I can implement in my mobile applications.
I want it to be generic enough so that it can port to any platform, but I am currently working in C# on the .net Compact Framework.
What I'm doing right now is:
Create a Stopwatch object (in the panel's ctor)
on mouse down start the Stopwatch and save the current mouse point _lastMouse
on mouse move, stop the Stopwatch, and store velocity = (_lastMouse - curMouse) / Stopwatch.TotalSeconds then reset the Stopwatch and start it again
In most cases Stopwatch.TotalSeconds is between 0.02 and 0.03
on mouse up, I pass the velocity value into a smooth scrolling function, and that function continues to scroll the panel until either the end is hit or the increasing friction causes the velocity to be == 0
My problem is in the final step. The velocity values are generally int the 2,000-3,000 pixel range. The velocity is in pixels per second, so this is to be expected. I take the Stopwatch (which should be still running), stop it and I find the elapsed time from last mous move and multiply velocity by Stopwatch.TotalSeconds, get that distance and then reset and start the Stopwatch, then loop back and start all over again.
The expected result is that the elapsed time between refreshes multiplied by the velocity should give me the number of pixels (according to the last mouse move) that I should scroll. My actual result is that sometimes the panel goes flying and sometimes it bearly moves! the gradual slowdown is fine, it's just the beginning velocity that is off
Is there a flaw in the logic? Should I be doing something else?
Thanks for any help!
It seems to me that there are three possible sources of inaccuracy here. Firstly, as "A.R." said, you'll have problems if the granularity of your timer isn't good enough. Have you checked IsHighResolution and Frequency to make sure it's OK?
Secondly, even if your timer is perfect, there may be some inaccuracy in your position measurements, and if you're taking two in very quick succession then it may hurt you. My guess is that this isn't a big deal, but e.g. if you're on a capacitive touchscreen then as the finger lifts off you may get variation in position as the contact area goes down.
Thirdly, the physical motion of the finger (or stylus or mouse or whatever you've got doing the actual input; I'm going to guess a finger) may not be all that well behaved. At the end of a gesture, it may change from being mostly horizontal to being mostly vertical.
All these problems would be substantially mitigated by using a longer sampling period and maybe (try it both ways) ignoring the very last sample or two. So, keep a little circular buffer of recent samples, and when you get the mouse-up look back (say) 100ms or thereabouts and use that to decide your velocity. Or, if you don't want to keep that much history, use a simple IIR filter: every time you get a sample, do something like
filtered_dt = filtered_dt + SMALL*(latest_dt-filtered_dt);
filtered_dx = filtered_dx + SMALL*(latest_dx-filtered_dx);
filtered_dy = filtered_dy + SMALL*(latest_dy-filtered_dy);
where SMALL should be, at a guess, somewhere around 0.2 or so; then use filtered_dx/filtered_dt and filtered_dy/filtered_dt as your velocity estimate. (I think this is better than calculating a velocity every time and filtering that, because e.g. the latter will still blow up if you ever get a spuriously small dt. If in doubt, try both ways.)
If you use the IIR approach, you may still want to make it ignore the very last sample if that turns out to be unreliable; if you remember the latest dt,dx and dy you can do that by undoing the last update: use (filtered_dt-SMALL*latest_dt)/(1-SMALL), etc.
Here's an off-the-wall suggestion that may or may not work. You mentioned that you get more erratic results when there's a "flick" at the end of the gesture. Perhaps you can use that to your advantage: look at, say, how rapidly the estimated velocity is changing right at the end of the gesture, and if it's changing very rapidly then increase the velocity you use somewhat.
Related
I am working with a 3D-WPF Application that contains very larg as well as tiny 3D-Objects at the same time. (a satellite simulation)
To display them at the same time I have to set the NearPlaneDistance to a much lower value than the FarPlaneDistance (factor 10^9 times smaller), which seems to be the root of the problem
Now I have the problem that some polygons disappear (e.g are not drawn) at certain camera settings ( look direction etc. ) -> When the camera moves it flickers. (Example Picture of an MWE i coded just one really big cube and and a very small one)
I suspect this is caused by Z-fighting, but I am not sure because sometimes whole objects disappear, and there is also a big difference between objects ModelVisual3Ds that have been transformed or not.
I tried various combinations of Near and FarPlaneDistances but there is always some problems.
Is there a way to increase the z-Buffer precision or make it logarithmic ?
I know Wikipedia suggest cheating about the distance (making an object smaller to simulate distance), but i thought before getting into that I ask here :)
It's probably z-fighting due to floating point rounding error at those high sizes. The larger the floating point numbers get, the more their accuracy decreases.
You could try scaling everything down by an order of magnitude to get more floating point accuracy. This shouldn't affect your simulation or anything visual as long as you scale everything down equally to match, such as cameras, positions, and entity movement.
I've been stuck on this the last few days so I'm hoping you guys can help.
I'm making a 2D game and I want my character to slip, fall backwards, and hit his head when he tries to run on ice for too long.
My goal is to have it where if you keep holding the run button long enough on ice, he will slip backwards and damage himself.
I'm using playmaker but I do know a little c# programming.
The first thing I tried was making an animated float that adds the rotation to the Z axis over time, but that went horribly wrong and makes the character jump/skip/glitch all over the place.
The second thing I thought of was to add 2D torque to make him start slipping backwards, but he stays in the same rotation with fixedAngle true.
So then I made it where fixedAngle is false when he is on ice, but he immediately falls forward or backwards as soon as I start running. I made the center of mass right in the middle so he stands fine as long as he is not moving.
Does anybody know a way of achieving the effect I want?
This is my first game and I am a noob, so hopefully there is an easier/correct way of going about this. I could be doing this all wrong, so any guide in the right direction would be greatly appreciated.
It seems like from your verbage, you want to be tracking the amount of time the player has been running on ice.
If you want to tie this to the run key being down, start the timer if the button is down and trigger the "slip-and-fall" event to occur after a certain amount of time.
If you want to tie this to the amount of time the player has been on the ice, start the timer when the player reaches the ice and trigger the "slip-and-fall" event to occur after a certain amount of time.
If you want there to be a visual tilting, tie the time delta to the angle of the object. Set a certain angle to trigger the "slip-and-fall" event.
Update(){
if(this.running && _terrainAtPos == <Ice> && isGrounded){
transform.Rotate(0,0,3*Time.deltaTime);
if(tranform.rotation.z > 180){
//do falling event
}
}
}
EDIT: The above is not a working sample. Just something I whipped up to illustrate.
I am making the character run but the animation is extremely quick as I am doing:
_frameIndex++;
_frameIndex; is the value which points to the image in the SpriteSheet. Does anyone know how I can use gameTime.ElapsedGameTime.TotalMilliseconds to slow the animation down?
I saw that you've asked a couple of questions tonight concerning animation and spritesheets, so here's an example from Aaron Reed's "Learning XNA 4.0," from Chapter 3 under the "Adjusting the Animation Speed" heading.
First, create two class-level variables to track time between animation frames:
int timeSinceLastFrame = 0;
int millisecondsPerFrame = 50;
The first variable tracks time passed since the animation frame was changed, and the second is an arbitrary amount of time that you specify to wait before moving the frame index again. So making millisecondsPerFrame smaller will increase the animation speed, and making it larger will decrease the animation speed.
Now, in your update method, you can take advantage of game.ElapsedGameTime to check time passed since the last frame change, and change the frame when when that value greater than millisecondsPerFrame, you can do work:
timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
if (timeSinceLastFrame > millisecondsPerFrame){
timeSinceLastFrame -= millisecondsPerFrame;
// Increment Current Frame here (See link for implementation)
}
This sort of solution is similar to what you've found works, except that you can take an extra step to specify exactly how often you want the animation to update, or even change that duration later on in your code if you like. For example, if have some condition that would "speed up" the sprite (like a power-up) or likewise slow it down, you could do so by changing millisecondsPerFrame.
I removed the code that actually updates the current frame, since you should already have something that does that since you have a working animation. If you'd like to see the example in-full, you can download it from the textbook's website.
I debugged the code and noticed that the gameTime.ElapsedGameTime.TotalMilliseconds always equated to 33. So I did the following:
milliSeconds += gameTime.ElapsedGameTime.Milliseconds;
if (milliSeconds > 99)
{
_frameIndex++;
milliSeconds = 0;
}
Which basically means that if this is the THIRD frame of the game, then make he _frameIndex go up. Reset the milliseconds to start over.
I'm making the skeleton for the typical BubbleShooter game in XNA, and I'm having issues with my collision detection algorithm, which is explained in the picture here
Depending on where the colliding Rectangle position is at the moment of collision, a new position is assigned to the colliding Bubble.
The issue appears when I shoot a bubble and this happens at the moment of collision.
I have run the debug step by step, and the moment when the collision happens is exactly like the picture, so my algorithm fails.
I tried to post the images directly, but it seems I can't since I'm still a new user here. Sorry about that.
Is there a way I can detect exactly when the boundaries of the Rectangles touch each other?
You can perform a per pixel collision instead, it is explained here:
Click here
So, if I understand, your problem is that you miss the exact moment of collision ?
I guess you are computing collisions in a discreet way, ie. even if your algorithm runs 60 times a second, it is only 60 times when a second could be subdivised in an infinity of instants.
The simple (and bad) solution is to make your objects move slower.
The good one implies to retrieve what happens between the frames. you will need some kind of direction vector and the object speed. With both these values, you can determine where and when the collision did occur.
You will also need the elapsed time between frames. This is the purpose of the GameTime object : it has a property "ElpasedGameTime", which has a property "TotalElapsedMilliseconds".
MSDN Documentation on GameTime class : http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.gametime.elapsedgametime.aspx
Some reading material on Wikipedia about collision detection: http://en.wikipedia.org/wiki/Collision_detection#A_posteriori_.28discrete.29_versus_a_priori_.28continuous.29
"A priori" and "A posteriori" detection : that's the keywords you might be missing.
I don't have time to test it right now but you should try to limit your number of collisions per frame to 1.
With a counter when it enters the update part if one collision has been detected block all other collision for the same frame.
This way if your projectile its the bottom part, your code for
if(hitBottomPart)
{
// Logic
}
part will execute in this same frame before the projectile has time to hit another rectangle of the texture.
Although this is just a guess.
Good luck with your game ! Collisions are always a pain to implement.
I want to perform a discrete-event simulation in C#. I want three balls rolling on the screen simultaneously following a random walk pattern. At time 1 ball one should appear and start rolling, at time 5, ball 2 and at time 10, ball 3 should appear. When any two balls come enough closer the color of balls should change (as long as they stay close).
I am very new to discrete event simulation, and i want to understand, how we do it in C# programming? what steps are required in creating the model. I know graphics and other stuff.
New comers be advised:
Using operating system timers or threads is NOT the way the discrete event simulations should work. Using one of these as a building block might be misleading or a plain wrong.
Read the wikipedia article first about Discrete Event Simulation (DES)
There are" models" so called "formalisms" that mathematically proven to work in event simulation. You need to implement one (for example DEVS).
You may want to look at some listed DES List of discrete event simulation software at the wikipedia.
Also you may find useful sigmawiki (programs,examples, tutorials) about DES. SharpSim and React.NET are DES implementations in C#.
Use a Timer (drag one from the Toolbox over to your form in the designer, or instantiate it in code if you prefer). Double click the timer to set a _Tick event in your code which will fire every N milliseconds (the .Interval property of the timer governs this). Set the .Interval to 1000 (1 second), and use objects that keep track of their own position in X and Y coordinates.
Use a Random object to generate the direction of the next position change of the ball, and within the _Tick event of the timer, update the position variables for each of the balls.
Using raw threads is a possibility, too, but the Timer gives you some of that power without having to manage everything yourself.