0

Hello: I am trying to create an app which will display a moving sphere. App will vary speed and direction. I've tried Adobe Flash but cannot get it smooth. Smoothness is essential in this case. So I am trying C#.

Initially, I can see that this can be implemented by: 1) Creating a PictureBox of a sphere, and using a Timer, change its coordinates. or 2) Using the this.paint function to draw a filled circle, and somehow, with a timer, erasing and redrawing it.

Can someone recommend the best path to take? I'll have a main menu where the user will chose speed/direction/how many etc... and then simply show the "game window" with the moving spheres. Any guidance would be much appreciated.

This is to be displayed on a PC only.

Thanks -Ed

Ed Landau
  • 966
  • 2
  • 11
  • 24
  • 2
    You should probably post the code you're trying already - but as a general approach, use GDI+ (by overriding `OnPaint`), turn `SmoothingMode` to anti aliased, and make sure you're using `float` or `double` coordinates, rather than `int`. That should be enough to get you started, or if you update with some code, I can probably suggest some basic changes instead. – Octopoid Feb 14 '15 at 16:34
  • You could do this with using GDI like @Octopoid suggests, or you could use DirectX technology like WPF/Direct2D etc. The later will be smoother. – Aron Feb 14 '15 at 16:55
  • I'd also add - using a Timer will be fine while you only have a few basic objects, although you want to be sure you use ONE in the form, *not one per circle/object*. If you want to make anything more complicated though you'll probably want to start looking at game frameworks, or at least put some thought into how to manage single global updates/redraws. This is essential for coordinating collision checks and ensuring movement speed remains consistent even if the frame rate dips. – Octopoid Feb 14 '15 at 17:04
  • Thanks folks. I will post what I have come up with tomorrow :). – Ed Landau Feb 14 '15 at 20:21

2 Answers2

0

Here are a few hints to get you going:

First you will need to come to a decision about which platform to target: WPF or Winforms.

Then you should know what to move across what; a nice Bitmap or just a circle across an empty background or a Bitmap or a Form with controls on it.

In Winforms both your approaches will work, esp. if you set a circular region see here for an example of that. (The part in the fun comment!)

And yes, a Timer is the way to animate the sphere. Btw, a Panel or even a Label can display an Bitmap just as well as a PictureBox.

For smooth movements make sure to set the Form.Doublebuffered=true, if you move across a Form. If you move across any other control (except a PictureBox or a Label) you will need to subclass it to get access to the DoubleBuffered property!

It is often also a good idea to keep the Location of a moving item in a variable as a PointF and use floats for its speed because this way you can fine grain the speed and Location changes and also the Timer Intervals!

TaW
  • 53,122
  • 8
  • 69
  • 111
  • Thanks TaW. I'm looking at your Windows Example. Thanks for that example. Is WPF hard to learn? In my previous life as a 3D graphics hardware pipeline designer, I never could get a grasp of DirectX... but that was 20 years ago!! – Ed Landau Feb 14 '15 at 20:21
  • _Is WPF hard to learn?_ Imo: yes. But your mileage may vary. Its use of DirectX will not be your problem as it is completely integrated (unless you need to access its internal). Perfect video smoothness requires being synch'ed with the monitor's refresh rate, which is built-in with wpf and simply not feasible in Winforms. But I found WPF too hard to learn so far.. - Play with the example to decide it'll be good enough.. – TaW Feb 14 '15 at 20:24
  • ..But note: the example does not move anything by itself, is only shows how to create a spherical picturebox. – TaW Feb 14 '15 at 20:27
  • TaW: I've been at this all afternoon. Can you explain why you are using the "using" clause? in other words, how do you know CreateGraphics returns an iDisposable item? That aside, I cannot get your code to work. The pictureBox does not move. I know the click routine is getting called because I have a debug.writeline there... I am not yet familiar with CreateGraphics to understand what this is supposed to do? I made the picturebox have a border so I could tell where it is... nothing shows up in the picture box even thought I am using a full path: – Ed Landau Feb 15 '15 at 05:28
  • Ok... I have no idea why your example used pb2, what setting its parent does, nor what CreateGraphics is. Since it did not work, I just tried using the timer at 10ms, and moving pictureBox1.location. IT IS JERKY AS HELL ! Even with DoubleBuffered set to true: – Ed Landau Feb 15 '15 at 06:27
  • Winforms animation is anything but smooth once the animated objects grow in size. For best results with games or similar animation moving to XNA would be recommended. It is no longer developed but still supported and has an active community. MS seems to be moving towards Unity.. WPF will be the best choice if the animation is meant to be only a part of a real life application... – TaW Feb 15 '15 at 06:48
  • As for your questions: In the example I use CreateGraphics to copy a certain rectangle from a Bitmap which is in memory onto the 2nd PictureBox (pb2), which moves only with the cursor, like a lens or a peek-through hole. And yes, like Brush, Pen or Bitmap (and then some ) Graphics is a type that must be disposed __if & when__ you create it. Normally you don't create it though but use the one in the Paint event's parameter.. – TaW Feb 15 '15 at 06:51
0

I just answered a similar question here.

NOTE: Depending on your needs, it is possible to achieve smooth animations under (under certain conditions) though you are responsible for everything. provides an animation framework but is perhaps a milestone harder.

It probably does not matter should you pursue first or WPF. You arguably could learn the basics under then move over to . may require you to learn quite a bit before you can do anything.

Summary

Essentially what this does is to create an offscreen bitmap that we will draw into first. It is the same size as the UserControl. The control's OnPaint calls DrawOffscreen passing in the Graphics that is attached to the offscreen bitmap. Here we loop around just rendering the tiles/sky that are visible and ignoring others so as to improve performance.

Once it's all done we zap the entire offscreen bitmap to the display in one operation. This serves to eliminate:

  • Flicker
  • Tearing effects (typically associated with lateral movement)

There is a Timer that is scheduled to update the positions of all the tiles based on the time since the last update. This allows for a more realistic movement and avoids speed-ups and slow-downs under load. Tiles are moved in the OnUpdate method.

If you note in the code for Timer1OnTick I call Invalidate(Bounds); after animating everything. This does not cause an immediate paint rather Windows will queue a paint operation to be done at a later time. Consecutive pending operations will be fused into one. This means that we can be animating positions more frequently than painting during heavy load. Animation mechanic is independent of paint. That's a good thing, you don't want to be waiting for paints to occur. does a similar thing

Please refer to my full SO answer complete with sample code

Community
  • 1
  • 1