Click here to Skip to main content
15,879,096 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I have 2 graphics I draw onto a form.

1 Graphic is a Randomly Generated Star Field, these stars move, and are updated every tick on a timer(50ms)

Once the stars have been drawn/updated a cockpit is overlayed onto this image to give the appearance of moving through space.

The problem I am having is that the stars are drawn onto the cockpit of the previous iteration of the loop giving the allusion that the stars are in the ship.

I have not a clue how to solve this and would love any advice. I have tried making it redraw the cockpit after it updates each star, this just makes updating the stars take too long.

One option is to kill each star once it reaches the edge of the cockpit's "window" I fear though that this would cause an equal problem with delay as it would have to check many conditons as the cockpit window is not even in shape.

A friend has suggested double buffering - I have only ever came across this as an option in VS to Enable or Disable.

Any help would be appreciated, especially in regards to if Double Buffering is the way to go.

I can provide the code if need be it is just obnoxiously long and makes the post look quite messy.

Thank you in advance.

Please see my past answers:
Drawing Lines between mdi child forms[^],
capture the drawing on a panel[^],
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^].

The point is: you always paint in Paint event or in overridden OnPaint, and in timer handle you only call Invalidate (if you use timers at all, I would rather recommend to use a thread instead, with the same rendering technique). Only this way, you get all control over rendering.

Also, never use System.Windows.Forms.Timer. It's only good when you have no requirements on the accuracy at all, for example, if you don't care if you wait twice or more as long. Yes, this is that bad.

And it can be much better to use a thread with Sleep instead of timer. If you want time, you can poll the value of System.DateTime.Now or Stopwatch every time you are about invalidation of the rendered scene. In can give you much better accuracy then a timer, but with timer, you can get additional hassles. Did you ever tried to resolve the situations when a timer event happens when the handler invoked by the previous timer tick is not yet completed? Timers are hard to deal with.

With other timers, the problem is that you the event is invoked in some other thread. So, anyway, you would need to use invocation mechanism. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in[^],
Control events not firing after enable disable + multithreading[^].

Share this answer
Espen Harlinn 19-Nov-12 17:25pm    
Well answered :-D
Sergey Alexandrovich Kryukov 19-Nov-12 17:26pm    
Thank you, Espen.
Rahul K Singh 20-Nov-12 0:56am    
Too good...
Sergey Alexandrovich Kryukov 20-Nov-12 0:58am    
Thank you. I guess I understand the hint... :-)
Daniel Verbatim Hallam 20-Nov-12 4:53am    
Hi, thank you for your response, about not using timers to call the paint invalidate and instead using a thread and sleep. The problem that I have had with that is that there is some conflict with manipulating the control from outside the thread it was created in. Its been a long time since we tried it but would you know why that would be caused?
Make your spaceship with no areas of transparency. Draw both in your paint event, not with random timers. That way, you have complete control over the order they are drawn in
Share this answer
Daniel Verbatim Hallam 19-Nov-12 16:49pm    
Thanks for the speedy reply. I am not sure I follow you, there is nothing random about the timer and the cockpit is not drawn until all the stars have been updated, I guess what I need to do is draw the stars and UI simultaneously?
Christian Graus 19-Nov-12 16:52pm    
Yes. You need to draw them all in your paint event, otherwise your code is sub optimal. That was my point, if you're not doing that, you have a race condition.
Daniel Verbatim Hallam 19-Nov-12 16:53pm    
Ok Do you have any suggestion has to how I could achieve this, I am quite new to graphics processing, this is all a bit experimental for me
Christian Graus 19-Nov-12 16:58pm    
If you're writing games, you should use XNA. Otherwise, my advice is what I told you. The Paint event is when Windows tells your form to draw itself. Do all drawing in there, and have your timer call Invalidate() to force it to redraw itself. you've not posted any code ( no code dumps please, but some sort of targetting code listing would tell me what you're doing )
Daniel Verbatim Hallam 19-Nov-12 17:12pm    
I have looked into XNA, this was more of a learning exercise before I stepped into it.
I have put the relevant code in a pastebin as I cannot see an edit post button, nor do I think code tags work here

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900