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
I just answered a similar question here.
NOTE: Depending on your needs, it is possible to achieve smooth animations under winforms (under certain conditions) though you are responsible for everything. wpf provides an animation framework but wpf is perhaps a milestone harder.
It probably does not matter should you pursue winforms first or WPF. You arguably could learn the basics under winforms then move over to wpf. wpf 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. xna does a similar thing
Please refer to my full SO answer complete with sample code
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!
Related
I'm creating a program that simulates that of the Breakout Game using C#.
I've been learning various techniques on how to create the bricks, paddle and ball for the game but cannot work out on how to add them all into one picture box in Visual Studio.
The main issue I'm facing is that in order to move the ball for example, I have to clear the 'canvas' by using the following section of code:
paper.Clear(Color.White); This basically clears the picture box to the colour white in order for the new coordinate (of the ball for example) to be dawn within the picture box and this is where my issue begins.
Each of the components within the Breakout game (that I have practised) all use the paper.Clear(Color.White); code. This means that if for example I want to move the paddle, display the bricks and bounce the ball simultaneously, the program just decides to do one function at a time. If I remove paper.Clear(Color.White); from one of my assets then the program just won't function in the way I want it to.
Is there a way for all these components to run simultaneously within the game without missing any of them out completely?
At its simplest you need to change your approach to have the 'layouting' or 'painting' be centrally controlled, presumably on a timer or similar, and do a single 'clear' operation and then redraw all your components. In other words, do not have each component clear the canvas, they should just be concerned with their own rendering.
The above is the simplest approach. Beyond that you could take an approach of only redrawing what has changed from one frame to another. This can make for much more optimized performance, especially if your game canvas is large or has many components. However it requires a completely different, and in some ways more complex design. You would need to determine the rectangle / rectangles that have had 'movement' or other modifications to them from the prior frame, clear only those rectangles and ask those components that are wholly or partially in those rectangles to re-draw themselves.
In my WinRT app I need to draw about 3000 objects on a canvas, where I can translate and zoom the view. Unfortunatley, after adding about 1500 lines to my canvas my Windows 8 App always crashes. What could be the best practice to achieve this?
One solution could be rendering everything on an image (how do I do this?). But then I loose comfort of easy access and editing of every element.
Also my scale and translate is very slow. But since I also need a big overview, it makes no sense to put only the objects of the visible area in the canvas, since on minimum zoom it's still everything and zoomed it's still very laggy cause of add and remove operations.
There are a couple of different things you should employ to have a smooth UX:
Use a Quadtree, whenever you add a shape to your canvas you also put it on your Quadtree. This will be helpful when you will zoom on a portion of the image: you will know what objects are in this portion of the image; you will render them again (against using a cached/pixellated version).
To overcome the potentially lengthy drawing process you could do the following:
display the portion of the cached image overview at the right scale
use a progress indicator to let know the user that the program is working render this portion
when the faint rendering is done, blit it on the screen
A concrete example: Google Maps does that.
There are quite some topics available about GDI drawing and flickering issues, but I haven´t been able to find any regarding drawing in an other process.
The issue
Basically I´m trying to draw to a Hwnd using Graphics.FromHwnd. This works perfectly, but there is a lot of flickering involved. The application I´m trying to draw on is a game (not made by me) and has quite a high refresh rate, unlike forms.
Attempts
I´ve tried doing the drawing both using a GDI.Rectangle function that used the HDC to draw and using Graphics.DrawRectangle to draw to the Hwnd. I don't notice a difference in performance but 'Graphics' seems a bit easier in use since it doesn't need gdi32.dll to draw shapes, unlike GDI.
I've also tried doublebuffering but yet again I do not notice any difference.
To me it seems that the doublebuffering is not working because of the fact that I'm trying to draw in such a high refresh rate window.
Question
Is it possible to get the window's refresh rate and use that for a timer to update the graphic?
is it possible to make graphics 'stick' until updated so they don't automatically disappear?
If anyone knows how to do this, or knows other solutions to get rid of the flickering I would appreciate the help!
Thanks in advance.
After doing some research I've come to the conclusion that using a transparent window will suit my case best. Here's how I came to that conclusion:
I've used an application to read window events to check if there was any continuous event stream that could be the window invalidation, but there wasn't.
I did find out a way that should make it possible to actually read when the game invalidates the window, but it's kind of a hack: It's possible to replace the game's d3d9.dll file with your own, calling all the original functions, but catching the events. I don't have any details on how or even if it works since having to distribute a dll to end-users is not an option for me, not to mention that this is in fact hacking.
I'm trying to make a picturebox move smoothly across a winform and the only way it even looks smooth is if I use a timer and lower the pixel speed to 1 px per 1 microsecond, and even then the movement of the picturebox is slow.
How do I use microseconds to make the picturebox move alot faster while still maintaining the level of smoothness when moving?
First I have no idea what your asking so maybe this will help maybe not.
Timing is a tricky issue. First All of the .net timers are at the milli second resolution and below that you have no assurance what the system is returning you with out using some type high resolution timer. The .net stopwatch uses the underlying high resolution timer but does not have a call back mechanism so you will need to build that your self utilizing a different thread and polling. That said you may want to look at animating in a different fashion then moving a picture box such as using bit blt or overloading the low level paint.
I'd imagine that moving a control across a form is a reasonably slow operation; so it's not that your timer isn't fine grained enough, it's going to flicker anyway. Rather than moving a picture box, you could paint whatever you had in the picture box onto the form background in the Paint event instead, changing the position you draw it to when a timer ticks. This way you could take advantage of things like double buffering for more smooth animation. You'll find that even a comparatively large interval like 40ms (25Hz refresh) should be enough in this case.
So I've been trying to wrap my head around shaders in 2D in XNA.
http://msdn.microsoft.com/en-us/library/bb313868(v=xnagamestudio.31).aspx
This link above stated that I needed to use SpriteSortMode.Immediate, which is a problem for me because I have developed a parallax system that relies on deferred rendering (SpriteSortMode.BackToFront).
Can someone explain to me the significance of SpriteSortMode in shaders, if Immediate is mandatory, anything I can do to maintain my current system, and anything else in general to help me understand this better?
In addition, my game runs off of multiple SpriteBatch.Begin()/End() calls (for drawing background, then the game, then the foreground and HUD and etc). I've noticed that the Bloom example does not work in that case, and I am guessing it has something to do with this.
In general, I've been having some trouble understanding these concepts. I know what a shader is and how it works, but I don't know how it interacts with XNA and what goes on there. I would really appreciate some enlightenment. :)
Thanks SO!
The sort mode will matter if you are attempting to do something non-trivial like render layered transparency or make use of a depth buffer. I'm going to assume you want to do something non-trivial since you want to use a pixel shader to accomplish it.
SpriteSortMode.Immediate will draw things in exactly the order of the draw calls. If you use another mode, SpriteBatch will group the draw calls to the video card by texture if it can. This is for performance reasons.
Keep in mind that every time you call SpriteBatch.Begin you are applying a new pixel shader and discarding the one previously set. (Even if the new one is just SpriteBatch's standard pixel shader that applies a Tint color.) Additionally, remember that by calling SpriteBatch.End you are telling the video card to execute all of the current SpriteBatch commands.
This means that you could potentially keep your existing sorting method, if your fancy pixel shaders are of limited scope. In other words, draw your background with one Effect and then your foreground and characters with another. Each Begin/End call to SpriteBatch can be treated separately.
If your goal is to apply one Effect (such as heat waves or bloom) to everything on the screen you have another option. You could choose to render all of your graphics onto a RenderTarget that you create instead of directly to the video card's backbuffer. If you do this, at the end of your rendering section you can call GraphicsDevice.SetRenderTarget(null) and paint your completed image to the backbuffer with a custom shader that applies to the entire scene.
I'm not one hundred percent sure on how much the sprite sorting mode effects shaders, i would think it would vary depending on what you were using the shader for.
as for bloom if you're using multiple begin and ends (which you really want to minimise if you can). you can create a render target the size of the screen, draw everything as you are now. then at the very end, take that render target back (using graphicsdevice.SetRenderTarget(null);) then draw your full screen render target (at 0,0 position) with the bloom shader, that way you will bloom the entire scene, regardless of the components of the scene using various sort modes.