I am doing an alert system that will show messages 'a la' Messenger, and I want them to move or resize to make them appear.
How can I do this without having to do this:
do
{
this.prop += 1;
} while (this. prop = destination);
You need to make a Timer component and call the form's SetBounds method in the timer's Tick event.
You need a frame rate independent interpolator.
Take a look at: Frame Rate Independent interpolation. Basically, the idea is that you compute what your current position should be based upon the expected animation time and how long you've been animating... This means that the animation will take the same amount of time to go from point a to point b on any hardware.
Of course, you'll need to position the form with the values coming out of this, but thats the easy part!
set form.size property to change size, form.position to change position
Related
Okay, so I started developing a game. The first thing I wanted to set up was an extensive Debug viewer, which can ultimately show things like buttons pressed (only those that I want to listen to of course) and a graph containing information about frametime, a histogram of sorts. However, I wanted to do this the correct way. It occurred to me that I wanted to use the DrawableGameComponent class for the debugviewer, and draw the debug information there. However it seems that it can't measure the Update and Draw times correctly, as I start the update timer at the beginning of the update and end the update at the beginning of the draw. However, I shortly thereafter realized that first the main game is executed (update - draw - wait) and then are all the other components executed (update component 1, draw component 1), so they aren't intertwined. This means that I can't calculate the elapsedtime (for both Update, Draw and overhead). As we can read in this blog it's better to measure frametime as opposed to frames per seconds.
So enough with the back story and on to my main question: How do I measure the frametimes needed for both the Update, the Draw and the overhead from the main game in another DrawableGameComponent, or should I just use a class and update that in the game?
I hope that everything is clear, have a great day.
i found this http://gamedevwithoutacause.com/?p=876 which explaines exactly what you need.
If you can't measure the Update and Draw times correctly, using the update timer, can't you simply use DateTime.Now? You get it at the beginning of your Update, then every next cycle (after Update, Draw and overhead) you just subtract the DateTime.Now measured previously.
in my form, I have a small media player, it's pretty basic, it has the basic functionalists
nest, previous, play, stop, volume increasing and a track bar.
I was able to seek the song by dragging the track bar via this code::
(Assuming that the maximum value of the track bar is the total number of seconds of the sound file)
private void SeekBar_Scroll(object sender, EventArgs e)
{
Player.Position = TimeSpan.FromSeconds(SeekBar.Value);
}
But I wasn't able to make the bar move forward by itself when the music is playing ..
I came up with this idea:
let's say we have a 90 secs duration song.
now the track bar maximum value is 100
so:
100 --> 90
1 --> X
X = 0.9 sec
this is the interval between the ticks of the bar and the value that the track bar value should be increased in every tick. Here is my code:
while (SeekBar.Value < 100)
{
System.Windows.Duration duration = Player.NaturalDuration;
SeekBar.Value += duration.TimeSpan.Seconds / 100;
Thread.Sleep(duration.TimeSpan.Seconds * 10);
}
Now I think this should be run in a separate thread right ?
but the problem, when i do that, I get the annoying message of saying that the TrackBar is being used in a thread other than the thread it was created on ..
how can i get around that ?
I wanted to put this code in both the MouseLeave and MouseEnter events, but it's pointless, cuz it will be on the same thread and the app will freeze..
How can i make the bar move by it self ?
You should create a WinForms Timer with an interval or 1,000 milliseconds, and update the trackbar in its Tick event.
It sounds like you have the hardest part done (mapping the length of the scroll bar to the length of the audio file). The rest is easy.
You can tackle this with a Timer. Set the interval to some value (such as 1000ms or maybe 500ms, and in Tick, update the scrollbar (call SeekBar_Scroll). For the exact interval, test and see what looks the most natural.
A while-loop will probably eat unnecessary CPU, not to mention lock up the rest of your application.
To get around the control updating, you need to check this SO question. You need to check control.InvokeRequired and set it via the Invoke method if that's the case.
I'm trying to give users of my GUI library unrestricted customization of in/out transition effects while still maintaining simplicity / preventing misuse (for when a Control enters or exits the view).
To do so, I added a delegate to the Control class, which would take a Control reference and a transition-completion percent, so that the user would be able to smoothly translate a control's position / opacity in any way he wanted, based on the given percent. All he'd have to do is subscribe a transition function before control entrance/exit.
However, I realized it would be impossible to transition / animate the controls using only the current completion percent, because you'd have to store and compare the control's initial position as well.
In order make this storage requirement apparent, should I force usage of a delegate-functor?
If so, how might I do that in a minimalistic / clean way?
Feel free to suggest another way to allow users to apply custom transition animations!
If I understood you correctly, your Control invokes Animation(calculation) delegate (from time to time, probably on each frame) and passes transition Competition percent.
The Animation delegate then calculates and returns/applies translation and position to the Control.
Is this correct?
Assuming that above is correct there are several solutions:
When animating only position and opacity:
Beside competition percent, you must also send initial state of control's position and opacity when calling delegate. Initial state must be remembered on the transition start and sent into delegate in each call.
When animating arbitrarily properties in general:
Beside competition percent, you also provide State property (type of Object or even better Dictionary). This State property is fully controlled by delegate and it's animation logic.
To your Control, State property would not have any semantics or meaning.
Your Control only MUST retain value of State property between subsequent calls to delegate.
Putting it all together, The Delegate fills the State with the initial values on the first call, uses these values on subsequent calls - does anything it wants. Delegate also applies calculated values to Control. Note that all properties that can be used in delegate must be public.
IMO you don't have to provide the user of the control with the initial position of the control since he can position it relatively to the initial position:
negative numbers are for left and top, and positive numbers are for right and bottom.
The following code is a function for a fast transition:
Point FastTranDiagonial(float Percentage){
Thread.Sleep(10);
int pixelsDist = (1 - Percentage)* 300;//300 is the maximum distance
return new Point(-pixelsDist ,pixelsDist);
}
When you invoke the delegate you have to add the Point to the initial position of the control. You have to notice that the delegate contains a Thread.Sleep(X), this must be in control of the user since he might want to do a fast or a slow transaction.
You might also want to consider adding sequential transitions like jQuery so one transition starts after an other's completion.
good luck
I think you need to pass in at least the following parameters to the delegate:-
the control itself
the container that contains the control (eg. a panel)
the completion percent
By passing the control itself, the user will have all its initial state information (such as position). Also, if the user need to set any property of the control, he will definitely need the reference to the control itself.
The container may be needed by the user if he needs its size/position information, or if he needs to do something special to it for the control.
I'm working on a real-time WPF/Silverlight (and soon WP7) visualization component and I'm looking for the best solution to force a redraw of the entire component in a Game-loop style. Redraw should be on-demand, but I don't want to back up the message pump with re-draw calls. Most of the drawing in my component is done using non-WPF primitives (e.g. Bitmap Interop, Direct2D) so my code does not use InvalidateVisual, and as a result, currently looks like this
// Pseudocode, doesnt compile, just to convey the meaning
public void InvalidateElement()
{
if (CurrentlyDrawing)
return;
Dispatcher.BeginInvoke(() =>
{
CurrentlyDrawing = true;
DoDrawInternal();
CurrentlyDrawing = false;
}
}
Ok so this is great. If I call InvalidateElement lots of times I get good responsiveness. However, what I want to do is ensure I can push data to my visualization component as fast as possible but only draw when the component is able to draw, and not keep drawing to catch up with the data once the input stream completes.
No I can't override OnRender, I'm using non-WPF drawing inside WPF ;-)
Basically what I want is something like the old Invalidate() / OnPaint in WindowsForms, or better yet, a game loop in DirectX.
At the moment I get the situation where if I have an external thread that pushes data to the visualization component at a high rate then if I Stop pushing data I get another 20 seconds worth of refreshes to get through before the component stops drawing. I want to stop drawing as soon as data has gone in.
Another idea I had was to handle CompositionTarget.Rendering in the visualization component then implement some sort of rudimentary Queue to push data to and the Rendering event consumes this data as fast as it can.
In Summary
Given a WPF visualization component, V, and a datasource which pushes it data every 1ms, D, how can I ensure that no matter the datarate of D, V draws data at 30FPS (or whatever it can do) and updates itself in chunks, sort of how a game render loop does in DirectX?
When the data stops, V should redraw everything it has up to now in one go. When the data is too fast, V draws larger chunks at a time to compensate.
If you need more information I'd be happy to share it. Right now I've just posted a synopsis to gauge if there are any quick fixes but a fuller Q with code examples can be provided on request.
Best regards,
You might want to consider rendering on the CompositionTarget.Rendering event and throttling on the invalidated state.
Silverlight game loop example (F#):
/// Run game
let runGame () =
let state = gameState.GetEnumerator()
let rate = TimeSpan.FromSeconds(1.0/50.0)
let lastUpdate = ref DateTime.Now
let residual = ref (TimeSpan())
CompositionTarget.Rendering.Add (fun x ->
let now = DateTime.Now
residual := !residual + (now - !lastUpdate)
while !residual > rate do
state.MoveNext() |> ignore
residual := !residual - rate
lastUpdate := now
)
Play the game: http://trelford.com/blog/post/LightCycles.aspx
Read the source: https://bitbucket.org/ptrelford/lightcycles
You can listen to the CompositionTarget.Rendering event, which is triggered right before WPF renders the UI, and do your drawing in there.
Another tidbit.. InvalidateVisuals() is nothing like Form.Invalidate(), as it also causes re-layout which is expensive. If you want something like Form.Invalidate(), then create a DrawingGroup (or bitmap image) "backingStore", place it in the DrawingContext during OnRender(), and then update it whenever you want. WPF will automatically update and repaint the UI.
Have you thought of using a dispatch timer running at 30FPS, then take a snapshot of the current data and rendering it at each timer tick? If you want to avoid redrawing if nothing has changed, you can simply keep timestamps for LastChanged and LastRendered, only performing an actual redraw if LastChanged > LastRendered. Basically updating the data and rendering the data are decoupled from one-another; the main trick is making sure you can somehow get a coherent snapshot of the data when the rendering thread wants to render it (i.e. you'll need some sort of locking.)
I was recently working with a project that required a game loop like style. Although my example is purely in F#, you can figure it out how you can do that way in C# too, may be use some interop code to initialize the timer and hooking up events as given in this below link,
http://dl.dropbox.com/u/23500975/Demos/loopstate.zip
The sample doesn't show how to redraw, it just updates the underlying stock data for every 500ms, It should pretty much work for any kind of drawing mechanisms with WPF. The core idea is to use composable events, in F# an event is a first-class citizen + an IObservable (reactive extensions for C#), so we can easily compose functions that in-turn return a set of events or a single event. There is a function Observable.await, which takes in an Observable and also has a state to return.
eventSource
|> Observable.await(fun (t:State.t) e ->
// return the modified state back on every check or in the end
match e with
// start button click
| Choice1Of3(_) ->
{t with start=true}
// stop button click
| Choice2Of3(_) ->
{t with start=false}
// timer tick event,
| Choice3Of3(_) ->
if t.start = true then
handleStockUpdate(t)
else t
) (state)
I just used some of FP terms here, but it should work just fine with normal C# (OO) way of doing things here.
Hope this helps!
-Fahad
I'm not sure why you would use WPF for your front-end if you're drawing using non-WPF elements and require the Invalidate() method that was provided by WinForms? Can't you just switch the UI to use WinForms?
I'm quite new in XNA C# and I would like to know how do I create a model in XNA C# that will blink every second. I'm trying to make an invulnerability effect for my model.
Currently, my own idea is that I will set the visible of my model to false and true every second.
Thanks.
EDIT: I cannot find any model.visible = false in XNA C#??
Your idea is fine, but you'll need to track whether it should be visible or not yourself, and only draw it when it's visible. Every object gets explicitly redrawn by your code every frame; so simply don't draw it when it shouldn't be visible.
There is no built-in way to do this (that I know of); it wouldn't make much sense if there were, since you'd be calling a drawing function on invisible objects. Not drawing invisible objects in the first place makes more sense.
To get the blinking to work, you'll need to track how much time has elapsed since the last time the visibility was flipped, and toggle the visibility when that time exceeds one second. For example, in your Update() method, you'd have something like this:
if (gameTime.TotalGameTime.TotalMilliseconds >= nextBlinkTime) {
modelVisibility = !modelVisibility;
nextBlinkTime = gameTime.TotalGameTime.TotalMilliseconds + 1000;
}
For more complex scenarios (e.g. multiple models need visibility toggled, etc.), I suggest you abstract this behaviour away into a reusable class.