discrete-event simulation example - c#

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.

Related

Timer makes my application lags

Well, I've got list of objects (picture boxes) with 30 objects which have location same as players in the game I'm playing. Players positions change fast,so positions of my picture boxes should change too.
I've tried to do this using timer,but application lags,and it looks like players are warping.
Is there any other way to change objects' positions on the form fast,without lagging?If not,maybe some suggestions what to do to prevent lag?
Consider reading this tutorial by MSDN on threading. Threading allows you to improve the performance of your program by make more use of your CPU.
https://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx
Hope it helps
Edit: You can also use a background worker which makes threading slightly easier.
https://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx

Trouble with Rectangles overlapping instead of touching XNA 4.0

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.

Scrolling momentum on mobile devices

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.

XNA 2D mouse picking

I'm working on a simple 2D Real time strategy game using XNA. Right now I have reached the point where I need to be able to click on the sprite for a unit or building and be able to reference the object associated with that sprite.
From the research I have done over the last three days I have found many references on how to do "Mouse picking" in 3D which does not seem to apply to my situation.
I understand that another way to do this is to simply have an array of all "selectable" objects in the world and when the player clicks on a sprite it checks the mouse location against the locations of all the objects in the array. the problem I have with this approach is that it would become rather slow if the number of units and buildings grows to larger numbers. (it also does not seem very elegant) so what are some other ways I could do this. (Please note that I have also worked over the ideas of using a Hash table to associate the object with the sprite location, and using a 2 dimensional array where each location in the array represents one pixel in the world. once again they seem like rather clunky ways of doing things.)
For up to hundreds of units, it should be fast enough to simply do a linear search O(n) over all the units in the world if the click regions are circles or rectangles. Especially seeing as it will be once per click, not once per frame.
If your units are not circular or rectangular, check against a bounding circle or rectangle first, and if that passes check against the more complicated bounding shape.
For a more detailed answer, here's my answer to a similar question about space partitioning. There I mention bucketed grids and quadtrees as potential structures for performance optimisation.
But you should never do performance optimisation until you have tested and actually do have a performance problem!
If you have a class that manages drawabel objects you could have a static int that you increase every time you make a new object, and save the old one as a local instance of Color in the drawabel object. You can then use the .Net type converter to make its to bye arrays and back, dont remember its name and im on my phoneon a train so can't check for you im afraid.
When you build the color from the byte array just remember to max the alpha channel, and if you happen to get too many objects you might overrun the indexes you can use.. not sure what to do then... probably have all your objects reaquire new colors from 0:0:0:255 again since hopefully some old ones are no longer in use :P
Not sure i made alot of sense but since im on a train thats all i can give you, sorry :)
You could use pixel perfect picking, which scales very well to massive numbers of objects (and has the advantage of being pixel perfect).
Essentially you render your scene using a unique colour for each object. Then you resolve the backbuffer into a texture and get the texture data back, finally you can simply check the pixel underneath the mouse and find out which object the mouse is on.
You can be clever about the information you get back, you can request just the single pixel the mouse is on top of.
Color[] pixel = new Color[1];
texture.GetData(pixel, mousePosition.Y * texture.Width + mousePosition.x, 1);
//pixel[0] == colour of the item the mouse is over. You can now look this up in a dictionary<Color, item>
You should be careful not to stall the pipeline by doing this (causing the CPU to wait for the GPU to render things). The best way to do this is to swap between 2 render targets, and always GetData from the render target you used last frame, this means the data is a frame out of date, but no human has fast enough reactions to notice.
Addendum in response to your comment.
To assign a unique colour to each object, simply increment a byte for each object. When that byte overflows, increment another, and when that one overflows increment another; Then you can use those three bytes as Red, Green and Blue. Remeber to keep alpha at max value, you don't want any see through objects!
To resolve the backbuffer is slightly changed in XNA4. Now you must render to a rendertarget and resolve that. To do this is pretty simple, and outlined by Shawn Hargreaves here

Which method should I use to give the perception the computer is thinking in programming?

I want to create a simple game like tic tac toe where the human user is playing against the computer. The computer function takes a couple of milliseconds to run but I would like to give the perception of the computer taking 5 seconds to make a move. Which method should I use?
1) Create two memory threads. One for the computer and one for the human user. When the computer is taking 5 seconds to imitate thinking, the human user thread is paused for 5 seconds.
2) Disable input devices for 5 seconds using timer or dispatchertimer
3) Any better methods you can think of..
Thanks!
Edit - The question is about the how and now the why. 5 seconds is just an example. I prefer 1-2 seconds but for example purposes I just chose 5. So please focus on what is the best way to do this and not on the 5 seconds. Thanks again.
Noise and Blinking lights = digital thought.
Rev up the CPU to 100% with an infinite loop to generate heat.
Start looping through all the files to get the hard drive light blinking and making spinning noises.
Run a shell command to change directory to the optical drive to make the optical drive spin.
Set caps lock, numlock and scroll lock on and off, some keyboards have lights for that.
Check to see if your motherboard supports any additional blinking lights.
Ah! Good point. Many fans have API access, so turning the fans on to 100% is cool. The revert to normal could be dangerous though, because if you accidentally turn off the fans for good, it could be serious damage.
you could just make the cursor into an hourglass and disable the main form (which will stop the user from inputting anything), start a timer for 5 secs (i'd make this time configurable), when the timer fires enable the main form and set the cursor back to normal again. Something like this:
Call this method when the user has made their move:
private void UserHasMoved()
{
Enabled = false;
timer1.Interval = 5000;
timer1.Start ();
}
then the event for the timer:
private void timer1_Tick(object sender, EventArgs e)
{
Enabled = true;
timer1.Stop ();
}
wouldn't this be annoying to the faster players? Maybe a second for the turn, but you'll soon find out that 5 seconds is too much.
Either way, do not pause the UI thread, because the interface would 'freeze'.
Because the human is using the GUI as its interface, you can't pause its thread. Pausing the GUI thread would disable your form from repainting, thus not showing the computer's move.
I'd just disable all game related input, and show an animation of the computer working its brain.
Two very important usability principles:
Don't block the UI thread! Only disable the game control so that the player cannot perform a step during the thinking.
Show a visual feedback to the user indicating the thinking and that he can't perform the step for a while.
And of course, balance the exact duration of thinking carefully. Treat the players' time as very precious.
From your question it seems you do not want the computer play to be so lightning fast that the human player can't see it. For that effect, why don't you display some random animation showing possible plays, and ultimately animating the chosen move.
Edit: I have to agree that disabling input devices is a bit harsh. Maybe switch the application to a state in which any input by the user cannot affect the board, but can affect other commands, such as save, restart or quit.

Categories

Resources