I want to animate a UIImage, or better said a UIView. I've got a Background consisting of multiple layers where each layer should be animated a little differently (lets assume this is a picture of a jungle and the second background layer is a plant). My first thoughts were to use a gif, but sadly this results in poor quality and big image sizes. The next thought was to use a "sprite sheet" image where the animation consists of 4 images which will be updated every 0.x seconds. Well this could work but i wanted to code as much as possible and use as less images as possible.
After the background is animated I want to animate a monkey running from the left to the right side. For sure the monkey itself should a animated and it should do this again after a random amount of seconds.
Which way would you implement such a thing and where would you start?
Edit
Forgot to mention that this should run with as low battery usage as possible
Related
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!
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.
So, I've been searching ALOT for this and I feel like I've tried pretty much everything, and still I'm coming up short.
The basic idea is to have a chat and also be able to have things in front of that chat window (lets say a draggable menu of sorts).
As a first thing I setup my chat as a GUI element. It works perfect.. word-wrapping and all, but it's always on top of everything else, so this doesn't really work for what I want to do.
The chat box is also scaling depending on your screen resolution.
I think the main issue is going to get it nicely word wrapped when NOT using GUI and I'm just all out of ideas.
Also wanted to state that the "menu" that's going over the chat is going to be containing gameobjects so it's not going to be another GUI element.
Can this even be done?
use GUI.depth=10 before drawing your chat window, and GUI.depth=5 after everything should appaer on top now.
From the documentation:
Set this to determine ordering when you have different scripts running simultaneously. GUI elements drawn with lower depth values will appear on top of elements with higher values (ie, you can think of the depth as "distance" from the camera).
if you dont want to do this.. determine order of drawing. Whatever gets drawn last is on top.
I understand at this stage it may be hard to do this, but its best to have one OnGUI active in your whole game/app. Having more than one deteriorates performance.
edit: to include scene renders on top of the GUI, you render your scene to a seperate camera (without gui) and have this camera render to texture. this texture can then be used in your gui by using for instance GUI.DrawTexture.
I'm creating a map editor for game in C# Windows Forms. What I need is a grid that will have to store even a few thousands of images.
My first approach was to create a Panel control and then add multiple PictureBoxes to it. Unfortunately 2000 images took about 3 seconds to draw.
Then I decided to try creating Rectangles and drawing Images on them in Panel's OnPaint() method in hope to get better results but it's still very slow.
Is there any better, efficient way to render so many images in Windows Forms?
Thanks in advance for any advices.
Use the Paint event as you have done but...
As part of the loading of the images, cache a zoomed out version where you merge 16 images into one, which is only 125 images, when you zoom out over a certain scale, switch to using the pre-rendered zoomed out version.
You can do that as often as you like for multiple zoom levels with the idea of keeping as few images as possible on screen at anyone time. So you could divide it by 4 again.
I do this for a project which has a map comprised of 65536 images (256 x 256). The cache is also writted to disk so each time you zoom out you see the same number of images. In my editior I can only view 16 images at any one time, even if I'm looking at the whole map.
You can further improve on the this by knowing the available options to the user (e.g. Pan and Zoom) this gives you a limited subset of images the user could potentially view next so you can preload these to improve performance.
You'll increased load time initially but I bet you already have a significant load time pulling 2000 images off disk
I'm skeptical if I'm doing this the right way.
I have to play an animation at about 60fps. I'm using a List<Image> to load all the frames at the time of initialization. And then using a System.Timers.Timer to call an event at every 10ms which will change the image in the pictureBox.
List<Image> imageList = new List<Image>();
private static Timer_Event(o, e)
{
pictureBox.Image = imageList[i++];
}
So, am I doing this right? Is there a better approach?
What you're describing seems unlikely to work in a robust fashion. Here's a brief summary:
In my experience, timers aren't generally accurate. Since timer messages go through the Windows Message pump, they can only move as fast as your Windows UI processes messages. Any application that interferes with messages will cause your timers to stutter, although careful work can prevent most of this. Some classic discussion of timers here: Winforms Timer for Dummies
In general, List is a very inefficient way to store images. For a one-second animation at 60 frames per second, you will have to hold 60 images in memory and decompress each one individually.
Here are some possible solutions, and the tradeoffs they entail:
Full Motion Video
If you are looking to present a full motion video on your form, you should really consider using a MediaElement (for WPF applications: http://www.c-sharpcorner.com/uploadfile/dpatra/media-element-in-wpf/ ) or a MediaPlayer object (for WinForms applications: http://msdn.microsoft.com/en-us/library/bb383953(v=vs.90).aspx ).
This will allow you to play a lengthy video that contains extremely high quality images, varied compression, and start or stop the playback arbitrarily. However, the startup and memory usage requirements of a full video player are greater than just displaying a single image on screen. You will find that your application takes a moment to initialize the video subsystem, which may be annoying.
Animated Images
It's possible to show an animated image in a picturebox in Windows Forms or WPF. You would simply generate the animated image - generally using a GIF animation file. This will work smoothly for a majority of simple animations, and it's possible to get free-to-use animated GIFs from websites like this one: http://www.chimply.com/Generator
Here's a walkthrough of how to place an animated GIF on your form: http://trompelecode.com/2010/12/animated-progress-indicator-in-csharp-windows-forms/
Sprite Animation
Let's say you need to accurately represent each image exactly (which isn't necessary if you're simply trying to look appealing), and that you don't want the overhead of a video system (which is okay if you're only playing a second or two worth of animations). What you want to do then is create a single composite "sprite" image. This reduces the memory overhead requirements of your application and reduces the amount of time decompressing files.
For example, here's a website that generates PNG sprites for you: http://wearekiss.com/spritepad
Once you generate an image with sprites, you can place it within a picturebox and animate the image by changing the relative position of the image within the picturebox. Here's a walkthrough of how to accomplish this: C# picturebox load image with an offset
Summary
Any way you choose to display an animated image, you will have some tradeoffs. I like to pick the simplest possible solution for myself - and in my case I like to use an animated GIF image. Good luck animating!
The .avi is alternative otherwise, however, if you have bunch of images than probably utilizing threads/timers apparently seems to be the way forward.
The easiest way would be to use an animated gif in that pictureBox and don't mess with timers.
You may also be able to put your animation together using WPF or Silverlight ... if you need the animation to be interactive or programmatically controllable that would probably be the way to go.
If on the other hand the animated content is static then AVI (or MPEG etc.) is probably your best bet.
You don't say exactly what you're trying to accomplish so I can't be sure.