animation and double-buffering. the animation methods described here are based on standard...
TRANSCRIPT
![Page 1: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/1.jpg)
Animation and Double-Buffering
![Page 2: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/2.jpg)
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).
Introduction
![Page 3: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/3.jpg)
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 generic list to hold the collection of balls being animated
Balls in SPACE !!! Overview
![Page 4: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/4.jpg)
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{ public partial class FormMain : Form { List<ball> balls = new List<ball>(); private Bitmap aBitmap; Random rnd = new Random();
public FormMain() { InitializeComponent(); makeBalls(); timerAnim.Interval = 30; timerAnim.Start(); }
Source Code
aBitmap will be our frame buffer
generic List to hold members of the ball class
30 millisecond frame time 1/0.03 = 33.33 frames/sec
![Page 5: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/5.jpg)
private void resetFrameBuffer() { Graphics g = CreateGraphics(); if (aBitmap != null) aBitmap.Dispose(); aBitmap = new Bitmap(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).
resetFrameBuffer( )
![Page 6: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/6.jpg)
private void 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;}
drawBalls( )
Graphics region g not visible in picBox
center of Ellipse (ball)
color of ball
width, height of ball
transfer finished frame to picBox
![Page 7: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/7.jpg)
private void updateBalls(){ foreach (ball b in balls) { b.move(); b.bounce(picBox.Width, picBox.Height); }}
private void timerAnim_Tick(object sender, EventArgs e){ drawBalls(); updateBalls();}
updateBalls( ) & timerAnim_Tick(. . .)
public void move(){ x += vx; y += vy;}
public void 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; }}
methods from the ball Class
![Page 8: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/8.jpg)
private void 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(new ball( (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)));
}}
makeBalls( )
calls the constructor for the ball Class
![Page 9: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/9.jpg)
Original Size of FormMain
![Page 10: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/10.jpg)
Effect of resizing FormMain
![Page 11: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/11.jpg)
private void 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; } }
picBox_MouseDown(. . .)
This method resets the x,y positions of all the balls to the mouse click location, without changes the ball velocities vx, vy.
![Page 12: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/12.jpg)
Effect of Clicking in FormMain
![Page 13: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/13.jpg)
using System;using System.Drawing;using System.Drawing.Drawing2D;using System.Collections.Generic;using System.Linq;using System.Text;
namespace BallsInSpace{ class ball { protected float x; protected float y; protected float vx; protected float vy; protected float size; protected Color color;
public float Y { get { return y; } set { y = value; } }
public float X { get { return x; } set { x = value; } }
ball Class
ball Class defines the properties and provides methods for an instance of a ball.
Properties: position, velocity, size and color
Methods: move( ), and bounce( )
![Page 14: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/14.jpg)
public float Vx { get { return vx; } set { vx = value; } }
public float Vy { get { return vx; } set { vx = value; } }
public float Size { get { return size; } set { size = value; } }
public Color Color { get { return color; } set { color = value; } }
More Accessors for ball Class Properties
![Page 15: Animation and Double-Buffering. The animation methods described here are based on standard techniques of double-buffering applicable to most high-level](https://reader030.vdocuments.us/reader030/viewer/2022032605/56649e7c5503460f94b7e787/html5/thumbnails/15.jpg)
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;}
public void 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 void move() { x += vx; y += vy; }
ball Constructor and move( ) & bounce( ) methods
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.