Top Banner
Animation and Double-Buffering
15

Animation and Double-Buffering

Jan 03, 2016

Download

Documents

benjamin-buck

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. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Animation and Double-Buffering

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 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

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

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

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

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

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

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

Original Size of FormMain

Page 10: Animation and Double-Buffering

Effect of resizing FormMain

Page 11: Animation and Double-Buffering

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

Effect of Clicking in FormMain

Page 13: Animation and Double-Buffering

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

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

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.