Click here to Skip to main content
11,920,377 members (47,405 online)
Rate this:
Please Sign up or sign in to vote.
See more: VB graphics VB.NET
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.
Posted 19-Nov-12 11:36am
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

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[^].

Espen Harlinn 19-Nov-12 17:25pm
Well answered :-D
Sergey Alexandrovich Kryukov 19-Nov-12 17:26pm
Thank you, Espen.
Rahul K P Singh 20-Nov-12 0:56am
Too good...
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?
Sergey Alexandrovich Kryukov 20-Nov-12 11:21am
It's not quite clear without seeing your code, but did you use Invoke/BeginInvoke? Read again on it starting with "you cannot call anything..."
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

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
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)

  Print Answers RSS
0 OriginalGriff 415
1 phil.o 170
3 F-ES Sitecore 130
4 RyanDev 120
0 OriginalGriff 6,778
1 KrunalRohit 4,495
2 Sergey Alexandrovich Kryukov 3,203
3 George Jonsson 2,805
4 Suvendu Shekhar Giri 2,181

Advertise | Privacy | Mobile
Web03 | 2.8.151120.1 | Last Updated 19 Nov 2012
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100