Snyder 3 November 1999

Project 2

"Yes, But Is It Art?"

The purpose of this project is to acquire additional experience with writing procedures in VB6.0, especially procedures with parameters. You will be expected to write procedures with the following characteristics:

  1. A procedure with two or more parameters
  2. A procedure that calls another procedure of yours
  3. A procedure that is called more than five times

Unlike Project 1 where the guess procedure referred to global variables, only event-handlers are allowed to use global variables in this project. Further, to acquire experience with other features of VB6.0, you should try to use at least one Do While loop. These will be the primary basis for grading the assignment, but they will probably be a natural outcome of your programming effort.

The question that will be explored by this project is, "Can VB6.0 be used ‘artistically’?" Naturally, art is usually a matter of opinion, and in this case the opinion that matters is yours. What is the most artistic or aesthetic way in which you can use the graphic and computational facilities of VB6.0? Of course, Visual Basic 6.0 was not designed as a graphics package, or even intended for use in any serious graphics applications. But with a little imagination, almost any general purpose programming facility can be used to do interesting things graphically. Our goal is not to push the limits of graphics; we want to push the limits of VB6.0. What can you think of? How creative can you be?

As an added incentive to being as ingenious as possible, we will have an in class display of some of the better designs (in the opinion of the staff) and award prize(s) for the best.

Suggestions: One way to apply graphics is simply to produce a pleasing or clever picture. Or try making an electronic greeting card … how about an ecard to usher in the new century?! Motion or action in which the image develops dynamically on the screen can lead to interesting results. Also, remember that motion can be produced by changing colors, as well as by moving shapes around.

Project Design: Plan on constructing two separate designs, the first to be graded at an intermediate point (see due dates), and one as your final submission. (The second can be an embellishment of the first, or it can be entirely different.) One strategy might be to accomplish the requirements (first paragraph) on the first design, and concentrate on aesthetics exclusively on the second design.

When a project begins executing, it should show an empty form to the user. The user then clicks on the form, causing the image to be drawn. You will not be using controls extensively. All of the graphics will be produced by program code, written by you as procedures. Of course, since the image is produced when the user clicks on the form, the focus of your programming efforts will start with the Form_Click() event handler. The window can be closed to terminate its execution, i.e. you do not need to stop it explicitly.

In developing this program, you should emphasize writing procedures. (One could easily imagine writing a dozen small procedures for this project.) First of all, writing procedures is the purpose of the project. Secondly, and more importantly, procedures allow you to organize the development, encapsulating effects that you can then compose into more complex images. Accordingly, the Form_Click() event procedure should not be a very long piece of code, but rather it should merely orchestrate the calling of procedures that do the work, probably by calling other procedures.

So, that’s it: The project is to create a VB6 program that is graphically interesting. What you will program is up to you 100%. This may seem daunting, so an easy way to get started is to experiment with some of the different effects as suggested below to see what is possible.

Resources: As noted above, VB6.0 is not a graphics programming system, but there are many things that can be done with the basic primitives that it supplies. Chapter 5 of the Visual Basic 6.0 book discusses graphics. (You can safely skip 5.3, Layering Controls.) Using this information it is possible to find quite a bit of useful information there that is explained well. See the examples below. If you see something in the Chapter that you’d like to use, but don’t understand it, ask.

In an effort to provide some useful raw material for creating interesting images, consider the following resources.

  1. Recall from Lecture (18) that the size of the window that you have to work with is given by the ScaleWidth and ScaleHeight properties. See p. 117.
  2. It is possible to "splash" the window across the whole display, i.e. maximize it, by setting the WindowState property of the form to 2, e.g.
  3. Form1.WindowState = 2

    After this, ScaleWidth and ScaleHeight will be huge. Find out by running this version of the Form_Click() procedure from a normal size window:

    Private Sub Form_Click()

    MsgBox "The initial size is " & ScaleWidth & " x " & ScaleHeight

    Form1.WindowState = 2

    MsgBox "The new size is " & ScaleWidth & " x " & ScaleHeight

    End Sub

  4. The QBColors mentioned in Lecture (18) are pretty basic. It is possible to create, using a combination of red, green and blue, any color that can be displayed. This is explained on pages 117-118. As an example of producing a color by the combination of red, green and blue, use the RGB(r,g,b) function which has the three obvious parameters. The numbers given for each of the parameters have to be between 0 and 255. Try it by writing in the Form_Click() procedure
  5. Form1.BackColor = RGB(221,31,203)

    which turns the background to "Husky purple". Of course, it is possible to change these values dynamically.

  6. It is possible to develop the code discussed in the book to find the proper R-G-B values for your desired colors, but that kind of code is already running in many applications. So, to find the R-G-B values for a given color, go to some "More Colors" window from some other application, e.g. Word. (From Word go Format à Background à More Colors à Custom to get to one of the places where the color palette is available; there are many others, of course.) When you set the color you want, read off the R-G-B numbers that define for the color you want, and then use them in your program when calling the RBG() procedure.
  7. As discussed in Lecture (18) to draw a box on Form1, use the line drawing facilities as follows:
  8. FillColor = RGB(_,_,_) ‘ Say what color is inside the rectangle

    Form1.Line (boxLeft, boxTop) – (boxLeft + boxWidth, boxTop +

    boxHeight), RGB(_,_,_),B

    where you must put everything after the first line on a single line in your program. Also, fill in the blank R-G-B values with numbers or variable values from 0 through 255. Remember the key points about this call, namely the facts that you are specifying two corners of a rectangle, the "" is required between the two corners, and the "B," which means "box," is required. If you don’t put in the second RGB() call shown, then the line around the rectangle is black.

    Drawing a circle is even easier:

    FillColor = RGB(_,_,_)

    Form1.Circle (centerLeft, centerTop), radius, RGB(_,_,_)

    where, if the RGB() is omitted, the line around the circle is black. Of course, (centerLeft, centerTop) is the center point of the circle, and radius is the radius.

  9. An interesting technique is shown as the Confetti Program in the book (pp. 116-117):
  10. This can be called a splatter painting, and you should read about how it works in the book. I used it in the following procedure to get the effect shown:

    Private Sub Form_Click()

    Dim count As Integer ‘ define an iteration variable

    Dim nXCoord As Integer, nYCoord As Integer

    Dim nRed As Integer, nGreen As Integer, nBlue As Integer

    Randomize ' Set up random number generator

    count = 0

    Do While count < 10000

    count = count + 1

    nXCoord = Int(Rnd(1) * Form1.ScaleWidth)

    nYCoord = Int(Rnd(1) * Form1.ScaleHeight)

    nRed = Int(Rnd(1) * 255)

    nGreen = Int(Rnd(1) * 255)

    nBlue = Int(Rnd(1) * 255)

    PSet (nXCoord, nYCoord), RGB(nRed, nGreen, nBlue)

    Loop

    End Sub

    The form starts out with a white background, and the words "Hi, Mom!" written with a label. It enters a loop in which it generates on each cycle a random x,y coordinate and a random color as an RGB triple, and sets the pixel at that position to that color.

    The loop goes through 10,000 iterations. (The book uses only 1,000.) It is not possible to go through more than 32,767 using a standard Integer. So, to do more iterations of splattering, you will need to enclose the basic loop shown in another, outer loop.

    A key idea in this example is random numbers. Computers cannot generate true random numbers, because they follow instructions faithfully. But, they can generate number sequences that "look" random and that can be verified scientifically to have the same properties as random numbers. To use random numbers, you need to do two things: First, you must put the Randomize command at the start of your program so the computer sets up the randomization. Second, when you want a random number, just write the function Rnd(1). The result is a random number between 0 and 1. So, the procedure above finds a random color value between 0 and 255 by the code

    Int(Rnd(1)*255)

    Suppose the random number from Rnd(1) was 0.5 (which doesn’t seem too random, I suppose!), then the product would yield 127.5 Since this must be converted into a whole number, the Int function is applied to the result to throw away the fractional digits, giving 127.

    The splatters will normally cover the form, including the letters. This looks kind of dumb, so the way to avoid this (on black letters) is to change the form’s drawing technique DrawMode to 9, Mask Pen. The DrawModes give different affects, and you might want to experiment with them.

  11. Recall how we got the clock to "run" by redisplaying it whenever the time event went off? That same idea can be used for animations, too. Place a timer control on your form as we did before. (Don’t worry about where you place it, because it will disappear when the program starts running.) Next, declare a global variable at the top of your form code,

Dim tickTime As Integer, yDim As Integer

so that it is global to the timer routine. Next, initialize the tickTime variable in the Form_Load() event procedure

Private Sub Form_Load()

tickTime = 0

End Sub

Finally, write some code to draw on each time tick:

Private Sub tmrMyClock_Timer()

FillStyle = 0 ‘Set style to opaque

FillColor = RGB(221, 31, 203) ‘Husky purple

If tickTime * 200 > ScaleWidth Then

yDim = yDim + 200

tickTime = 0

End If

Line (200 + tickTime * 200, yDim)-(400 + tickTime * 200, yDim + 200), RGB(221, 31, 203), B

tickTime = tickTime + 1

End Sub

Remember the line drawing command must be on a single line. Then, whenever the timer goes off, the box is drawn in the next position. Run it. Nothing happen? Did you set the Interval on the timer? Experiment with different "speeds", smaller numbers make the timer go off more frequently, speeding up the image drawn. How does it stop from running off the form?