/* CSC15 Lab5: Introduction to Object Oriented Programming Due Wednesday March 14th This lab is designed to allow you to "get a feel" for object oriented programming (OOP) by completing a class definition and then using its instances in a program. Do not be intimidated by this assignment. It only seems difficult. But even if you don't completely understand oop yet, you'll still be able to complete it (that's part of the advantage of oop!). Follow the steps closely, but also think about what's happening in general while you're doing it. The stickfigure class below groups together information pertaining to a stick figure. You'll recognize the x, and y coordinates and the scale factor s. I've added a few more. You are to: 0. Download "animation.C" from the homepage and do "moc animation.C -o animation.moc" (after source useqt). You only have to create the .moc file once. 1. Cut and paste code from your first stick figure assignment into the draw function. Make sure you ONLY include the code for setting the brush, pen, and statements for drawing lines and circles. Do not include declarations and assignments to the x, y and s variables. Why? Because these variables are already declared inside the class, and they will be given values when the objects are created. Remember, you are now defining not one figure but a "class" of figures! *** NOTE: if you did not successfully complete your first stick figure assignment, you may borrow the code from someone else, PROVIDED you properly cite them in your code. 2. Study the code for the stick figure class and understand it to the best of your ability. A number of self-explanatory functions have already been defined for you: move, grow, armsUp, and armsDown. ***Note how they use both variables already defined in the class as well as varibles passed in as parameters at the time they're called. Write a shrink function that does the opposite of grow. THINK about this: Why is s, the scale variable, not declared inside the function, and why is it not passed in as a parameter? Why does it return no value? You need to understand why if you are to write your own classes from scratch some day (soon). 3. Find the template for the mywindow::animate function towards the end of this file. Here you will create an animation sequence. In order to do that you need to understand a basic concept in computer animation. One naive way to animate would be to draw the figure, erase it, then draw it in a new position. But the stick figure consists of many components, and this method would cause the image to *flicker* - an unpleasing effect. The solution is to use what's called a "double buffer". When we watch a film, we do not actually see images "moving" on the screen but rather a secession of still, *complete* images, each distinct. This is the effect that we must create. The double buffer is used to create a complete image off-screen, inside the computer's memory. When you call the draw function of a figure object (see the existing sample code in the animate function), the image does not appear on the screen but internally, on the double buffer. Nothing is shown on the actual screen until you call "refresh();". This allows us to create complete images before showing them, resulting in a frame-by-frame animation effect. Along with refresh, "clear();" clears the double buffer by drawing a big white rectangle on top of the old image, so that a new image can be drawn. "delay(ms);" is a function that suspends the program for ms milliseconds. This allows you to control the speed of the animation. The human eye can not keep up with a speed of more than 30 frames per second. So, to draw an image, you would: a. call the move, grow, etc... functions of the figures so that they'll look the way you want b. call the draw function of each figure to draw to the double buffer. c. call refresh to actually display the image d. call delay to wait a short moment before drawing the next frame e. call clear to clear the old image before drawing the next image. If you do not call clear, the old image will persist. You are to create an animation sequence of at least 10 separate frames, with at least three stick figures. You can make your program more interesting by using while loops. Instructions and illustration of how to creat different stick figure objects are included in the existing sample code in the animate function, which you should study and then replace with your own. 4. When you've had enough fun, you need to modify your code in the draw function so that it respects the armfactor variable. You can use an if-else statement to either draw the arms of a figure up or down. Alternatively, you can just multiply the y-offset of the coordinates of the end of the arms by armfactor. Also, change the animation sequence to reflect this new feature. 5. Notice that in the private section of the class there is a "QColor" variable. QColor is a class that's already defined in the Qt graphical library, without which writing a graphical program would be a monumental task. QColor objects represents specific colors. As you probably should know, all colors of the spectrum are combinations of red, green, and blue (RGB). Qt uses three values, each ranging from 0 to 255, to let you combine different intensities of these primary colors to form a vast variety of colors. To declare a new "color object", you say QColor mycolor(redValue, greenValue, blueValue); For example, to declare white you would say: QColor mywhite(255,255,255); // white == when all three colors are at max value. Once you've declared QColor objects, you can assign them to other QColor variables like the "color" variable inside the stickfigure class. You are then to define an additional method called void changeColor(QColor c) {...} that changes the color variable to the specified color. You also need to add a line that sets the drawing pen to the chosen color in the "draw" function, before the code that draws your figure: brush->setPen(QPen(color,1)); // set to right color If in your original code you used multiple colors, then you can just change any one of them. Alternatively, you can get ambitious and declare different color variables, like hairColor, eyeColor, etc... Reflect this new feature in your animation sequence. */ // program skeleton: #include "animation.C" #include "animation.moc" #include #include // Some commonly used colors #define myblack QColor(0,0,0) #define myblue QColor(0,0,255) #define myred QColor(255,0,0) #define mygreen QColor(0,255,0) #define mywhite QColor(255,255,255) class stickfigure { private: int x; int y; int s; // center coords and scale QColor color; QPainter *brush; // ignore int armfactor; // 1 is arms down, -1 is up public: stickfigure(int x0, int y0, int s0, QPainter *b0) { x = x0; y = y0; s = s0; color = QColor(0,0,0); // RGB value == black brush = b0; armfactor = -1; // 1 for arms down, -1 for arms up } void move(int dx, int dy) // shift position by amount dx,dy { x = x+dx; y = y+dy; } void armsUp() // raise arms up { armfactor = 1; } void armsDown() // lower arms { armfactor = -1; } void grow(int ds) // increase scale factor by indicated ammount { s = s+ds; } // student defines shrink void draw() // draws figure to double buffer (not directly on screen) { // Code you already have for drawing stick figure goes here. // It should be modified so that the arms can go up or down // Make sure you do not include code for setting x,y, and s. // That's already done in the constructor. // The following lines are for drawing a diamond, delete'em: brush->setPen(QPen(color,2)); // set to right color brush->drawLine(x-s,y,x,y-s); // left to top brush->drawLine(x,y-s,x+s,y); // top to right brush->drawLine(x+s,y,x,y+s); // right to bottom brush->drawLine(x,y+s,x-s,y); // bottom to left } }; // end class stickfigure void mywindow::animate() { stickfigure fig1(100,200,50,brush); // this is how you create an object. // the above line creates a stick figure object with initial x,y coords // at (100,200) and scale factor 50. Don't worry about the "brush" parameter // for now, but it must be there. // Create a few more stick figures (at least three). fig1.move(-2,3); // move figure 2 points to left, 3 point downward fig1.grow(4); // increase size of figure by 4 fig1.draw(); // draws to double buffer refresh(); // updates screen (new figure will be shown!) delay(80); // 80 millisecond delay before next frame should be shown clear(); // clears screen of old image fig1.move(3,-3); // move figure 3 points to right, 3 points upwards fig1.grow(-4); // increase size of figure by 8 fig1.draw(); // draws to double buffer refresh(); // updates screen (new figure will be shown!) // you get to make up the rest. You must make up 10 different frames // showing smooth animation. Instead of creating the frames one by one, // you might want to make your task easier AND more interesting by using // a while loop! }