1 / 15

Animation and Double-Buffering

Animation and Double-Buffering. Introduction. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level programming languages. It DOES NOT make use of .NET or C# api double-buffering controls.

Download Presentation

Animation and Double-Buffering

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Animation and Double-Buffering

  2. Introduction The animation methods described here are based on standard techniques of double-buffering applicable to most high-level programming languages. It DOES NOT make use of .NET or C# api double-buffering controls. The trick to animation is to generate and display successive images without creating flicker or ghost images caused by an interference between the monitor/display refresh rate and/or the drawing of the animated objects in a way that is visible to the viewer. Essential elements of a smooth animation: (1) Frame Rate – When successive images of an animation are displayed at a rate faster than about 24 frames per second the human eye-brain perceives a continuous flow rather than a sequence of static images. (2) Continuity – The amount of motion of “moving” objects should be relatively small between successive frames. When we need to animate a very fast moving object we have to simulate limitations in the human eye-brain by artificially blurring the image of the moving object in the direction of motion. (Not an issue in most animation applications.) (3) Double-Buffering – The viewer SHOULD NOT see the image while it is being generated. Rather the viewer is shown the previous image in the sequence until the next image is ready. Then the new image is transferred to the display in a single display interval. Double-buffering requires a hidden location in which to generate new image (called a frame buffer) and a means of transferring an image to the display in a single time unit (called the bitmap block transfer or BitBlt).

  3. Balls in SPACE !!! Overview FormMain – this is the main form of the application it is comprised of a picBox and a timer to control the animation. picBox – this pictureBox is docked to fill the available space in FormMain. It's background image is “starfield.jpg” with properties set to tile the picBox if it is larger than the image. timerAnim – the interval for this timer is set to 20 milliseconds it calls a method to move the balls and to bounce any that have reached the border of the pictureBox aBitmap – in order to enable double-buffering we create a device context (DC) in which to draw the objects being animated. Then the image aBitmap is ready it is passed to the pictureBox by picBox.Image = aBitmap ball class – this class defines the ball object, whose properties include position, x and y, velocity vx and vy, diameter called size and a color. This class also defines methods move( ) and bounce( ) for moving the ball and bouncing it off the containing boundaries List<ball> - a genericlist to hold the collection of balls being animated

  4. Source Code using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms; namespace BallsInSpace { publicpartialclassFormMain : Form { List<ball> balls = newList<ball>(); privateBitmap aBitmap; Random rnd = newRandom(); public FormMain() { InitializeComponent(); makeBalls(); timerAnim.Interval = 30; timerAnim.Start(); } generic List to hold members of the ball class aBitmap will be our frame buffer 30 millisecond frame time 1/0.03 = 33.33 frames/sec

  5. resetFrameBuffer( ) privatevoid resetFrameBuffer() { Graphics g = CreateGraphics(); if (aBitmap != null) aBitmap.Dispose(); aBitmap = newBitmap(picBox.Width, picBox.Height, g); } We will be using a bitmap image called aBitmap in which to draw the new frames of our animation. The size of the picBox (since it is docked to FormMain) can be changed by the user. When this occurs we need to create a new frame buffer (aBitmap).

  6. drawBalls( ) Graphics region g not visible in picBox privatevoid drawBalls() { resetFrameBuffer(); Graphics g = Graphics.FromImage(aBitmap); System.Drawing.SolidBrush aBrush = new System.Drawing.SolidBrush(Color.Black); foreach (ball b in balls) { aBrush.Color = b.Color; g.FillEllipse(aBrush, b.X -b.Size/2.0F, b.Y, b.Size/2.0F, b.Size, b.Size); } picBox.Image = aBitmap; } color of ball center of Ellipse (ball) width, height of ball transfer finished frame to picBox

  7. updateBalls( ) & timerAnim_Tick(. . .) privatevoid updateBalls() { foreach (ball b in balls) { b.move(); b.bounce(picBox.Width, picBox.Height); } } privatevoid timerAnim_Tick(object sender, EventArgs e) { drawBalls(); updateBalls(); } publicvoid bounce(float w, float h) { if (x < size/2.0F) { vx *= -1.0F; x = size/2.0F; } if (x > w - size/2.0F) { vx *= -1.0F; x = w - size/2.0F; } if (y < size/2.0F) { vy *= -1.0F; y = size/2.0F; } if (y > h - size/2.0F) { vy *= -1.0F; y = h - size/2.0F; } } publicvoid move() { x += vx; y += vy; } methods from the ball Class

  8. makeBalls( ) privatevoid makeBalls() { int w = picBox.Width; int h = picBox.Height; float vmax = 10.0F; float s; for (int i = 0; i < 200; i++) { s = (float)(rnd.Next(40) + 10); balls.Add(newball( (float)rnd.Next()/(float)int.MaxValue*(w - s) + s / 2.0F, (float)rnd.Next() / (float)int.MaxValue * (h - s) + s / 2.0F, (float)rnd.Next() / (float)int.MaxValue * vmax - vmax / 2.0F, (float)rnd.Next() / (float)int.MaxValue * vmax - vmax / 2.0F, s, Color.FromArgb(rnd.Next(128)+127, rnd.Next(128)+127, rnd.Next(128)+127))); } } calls the constructor for the ball Class

  9. Original Size of FormMain

  10. Effect of resizing FormMain

  11. picBox_MouseDown(. . .) privatevoid picBox_MouseDown(object sender, MouseEventArgs e) { float xp; float yp; xp = (float)(MousePosition.X - FormMain.ActiveForm.Location.X); yp = (float)(MousePosition.Y - FormMain.ActiveForm.Location.Y); foreach (ball b in balls) { b.X = xp; b.Y = yp; } } This method resets the x,y positions of all the balls to the mouse click location, without changes the ball velocities vx, vy.

  12. Effect of Clicking in FormMain

  13. ball Class using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Collections.Generic; using System.Linq; using System.Text; namespace BallsInSpace { classball { protectedfloat x; protectedfloat y; protectedfloat vx; protectedfloat vy; protectedfloat size; protectedColor color; publicfloat Y { get { return y; } set { y = value; } } publicfloat X { get { return x; } set { x = value; } } ball Class defines the properties and provides methods for an instance of a ball. Properties: position, velocity, size and color Methods: move( ), and bounce( )

  14. More Accessors for ball Class Properties publicfloat Size { get { return size; } set { size = value; } } publicColor Color { get { return color; } set { color = value; } } publicfloat Vx { get { return vx; } set { vx = value; } } publicfloat Vy { get { return vx; } set { vx = value; } }

  15. ball Constructor and move( ) & bounce( ) methods publicvoid bounce(float w, float h) { if (x < size/2.0F) { vx *= -1.0F; x = size/2.0F; } if (x > w - size/2.0F) { vx *= -1.0F; x = w - size/2.0F; } if (y < size/2.0F) { vy *= -1.0F; y = size/2.0F; } if (y > h - size/2.0F) { vy *= -1.0F; y = h - size/2.0F; } } public ball(float newX, float newY, float newVx, float newVy, float newSize, Color newColor) { x = newX; y = newY; vx = newVx; vy = newVy; size = newSize; color = newColor; } Expressing the position and velocity of the balls as floats rather than integers significanly improves the flow of the animation. This is true even though all objects are drawn using integer data types. The bounce(. . .) method checks to see if the ball position is outside the drawing boundary, moves the ball back inside the boundary and reverses the sign of the velocity. publicvoid move() { x += vx; y += vy; }

More Related