• Aucun résultat trouvé

Animation Basics

Dans le document Using the Processing Language (Page 157-161)

Image Processing

6.1 Animation Basics

In our previous examples, we have created animation by repainting the graph-ics on every mouse movement. As you may have noticed, that was a controlled animation. Eventually, we may want to set an object in motion independently

6

Motion

want to set a series of objects in motion and control their behavior through a common clock. This involves understanding of the basics of a computer clock.

As you already know, computers have internal clocks that tick extremely fast, that is, for example, 1 GHz, which means a billion ticks per second. When we do animation, we need to use that clock as a guide of time. Sometimes we also need to keep track of two or more animations as they are deployed in parallel in the scene. For example, in a car race video game, there may be one car moving, and at the same time other cars that need to bypassed, not to mention moving obstacles on the road. It seems that these animations are happening in parallel.

But practically that cannot happen because then we would need parallel proces-sors, each taking care of one moving object. Instead, what we do is to divide the processor time in small time sections, called threads, each keeping track of an animated object in the scene. This is not too hard to do for the processor, since theoretically it can take care of 1 billion things every second!

In the following example, a maple leaf is drawn on a brown background and then redrawn after moving it by a random offset to produce the effect of trembling. The process is quite simple:

1 PImage leafImage; //define an image object 2 PImage myBackImage; //define an image object 3

4 void setup(){

5 leafImage = loadImage(“maple_leaf.gif”); //load it 6 myBackImage = loadImage(“ground.jpg”); //load it 7 size(myBackImage.width,myBackImage.height);

8 } 9

10 int x, y; //the location of the cursor 11 void draw(){

12 image(myBackImage,0,0); //draw the ground 13 image(leafImage,x,y); //then the leaf

19 x = mouseX-(leafImage.width/2); //move the cursor 20 y = mouseY-(leafImage.height/2);

21 }

In the first two lines of the preceding code we define two images that are loaded in lines 5 and 6. The size of the screen is then set to the background image’s size. Before we draw we define two integer variables x and y to hold the coordinate location of where to draw the leaf image1 (line 13). These two coordinates are randomly moved by five units every time the frame is refreshed.

The leaf image can be moved to any location in the screen simply by dragging it. A screen capture of the process is shown in Figure 6-1.

Figure 6-1: A leaf trembling on top of the ground

Suppose now that we want to draw multiple leaves that tremble at different speeds to produce an autumn scene. This process involves two modifications of the previous code. First, we need to create an object (i.e., a class) that would hold information about each leaf. Then we need to use the speed of the clock and draw each leaf one at a time. However, while those leaves that are redrawn at the speed of the clock will be the fastest, the ones that are redrawn at the same position twice or more will appear to be moving at half-speed and so on.

For example, if the rate of redrawing an image is 4, that is, it is drawn at a new position only every four clock ticks that will make it appear to move at a quarter of the speed of another leaf with speed 1. So, in the definition of the class, we will use that principle to control the speed of each leaf. We define therefore a class called Leaf:

1 class Leaf {

2 int x, y; //the leaf’s position 3 PImage picture; //an image object

4 int rate; //rate of waiting to be redrawn 5

6 Leaf(){ //constructor

7 x = int(random(width)); //get an initial location 8 y = int(random(height));

9 picture = loadImage(“maple_leaf.gif”); //get the image 10 }

11

12 int k=0; //a counter

14 if(k==rate){ //if the counter is as the rate then draw

The class Leaf contains the following variables: two coordinates, an image, and a rate. The rate is an integer number that indicates the number of times to wait before redrawing the image. Line 6 contains the constructor information about the leaf, that is, defining a random initial location and loading the image (maple_leaf.gif). Before drawing the image we define a counter k. This is used to skip drawing the image until the counter is equal to the rate (line 14). If they are equal, we draw the image at a randomly offset location; otherwise, we increase the counter k. This technique allows an image to be drawn at a variable rate resulting in a variable speed of trembling motion.

In the main code we define a number of leaves to be created that we put into an array myLeaf[]. Then, we loop through the number of leaves and create a Leaf object and assign it a random rate between 2 and 20 (line 10). Next, we draw all the leaves, but since each one has a different rate the overall result is a variable speed motion. We assume here that the frame rate is at a default 60 frames per second (fps). So, if the rate is 6 that means that a leaf will not be redrawn for six times, giving it a perceived frame rate of 10 fps (i.e., six times slower movement).

1 int numLeaves = 400; //number of leaves to draw 2 PImage myBackImage; //define a backgound image

3 Leaf[] myLeaf = new Leaf[numLeaves]; //define a Leaf object 4

5 void setup(){

6 myBackImage = loadImage(“ground.jpg”); //load it

7 size(myBackImage.width,myBackImage.height); //size screen to the image 8 for(int i=0; i<numLeaves; i++){ //for all the number of leaves 9 myLeaf[i] = new Leaf(); //create a Leaf object

10 myLeaf[i].rate=int(random(2,20));

11 } 12 } 13

14 void draw(){

15 image(myBackImage, 0,0); //draw first the backgound 16 for(int i=0; i<numLeaves; i++)

17 myLeaf[i].draw(); //draw all the leaves 18 }

The result of this process can be seen in Figure 6-2:

Figure 6-2: Multiple leaves of variable trembling speed

Dans le document Using the Processing Language (Page 157-161)