CSE 203 Closed Lab 15 Instructions
Table of Contents
1. Objectives
- To learn about objects of type Circle, of type Line, of type
Point, and of type Vector.
- To learn about using Phrogram's Console subwindow to ask the user
for information and to gather that information.
- To learn about using an object that is a list of other
objects. In particular, an object of type CircleList is a list of
objects of type Circle.
- To learn about using Methods, included as part of your program,
that someone has written. In particular, to learn about Methods
that detect any interaction of a moving circle with another circle or a
line segment, and, if there is such interaction, change the velocity
according to a "bounce".
- To learn that the main event loop is not the only loop that there
may be in our programs. Having other "while" loops can be useful.
2. Set Up
- Two students should work together at one workstation.
- In one student's account, follow the instructions given
below in section 3, Method. Remember, trading roles (driver and
non-driver) for each new session is a very good
idea.
3. Method
- Start Phrogram, and open file
Bounce_Among_Many_Circles_Incomplete.kpl from folder Week06 within
folder OSU (i.e., folder OSU/Week06).
- I modified program Test_Bounces (also available in folder
Week06), which you saw in a previous closed lab session, to create
Bounce_Among_Many_Circles_Incomplete. I removed the green
diagonal line segment and the big static circle in the middle of the
window. I made other changes to help us move toward getting our
moving circle to bounce off a number of circles randomly scattered
about the window, this number of circles being specified by the
user. This program still uses the F1 and F2 keys in the user
interface. If you prefer, you can modify it to use mouse clicks
instead.
- The part at the bottom of the main event loop in Method Main()
that causes our moving circle to bounce off the window's borders is
still there, but it has changed somewhat. In program
Test_Bounces, we used a Function,
NV_Circ_Bounce_Line, to bounce a moving circle off a line
segment. The "NV" stood for "New Velocity" because a new velocity
is what the function returned to the program. In this program,
that function is gone, replaced by Method CV_Circ_Bounce_Line.
The "CV" stands for "Change Velocity" because this Method changes the
velocity that is given to it as its second parameter. Hence, the
call "CV_Circ_Bounce_Line( MC, MC_Velocity, TE )" changes (at least
potentially, when it detects interaction) MC_Velocity. I prefer
using a Method here because we only have to write "MC_Velocity" once
for each call. When we used a Function, we had to write (and
read!) MC_Velocity twice.
- A few more things to note about the call "CV_Circ_Bounce_Line(
MC, MC_Velocity, TE )": MC is an object of type Circle, MC_Velocity is
an object of type Vector, and TE is an object of type Line. The
property, Center, of object MC, MC.Center, is the center of the circle
(obviously, I guess). Anyhow, MC.Center is an object of type
Point.
- Take a minute or so now to read the comment that describes Method
CV_Circ_Bounce_Line.
- Let's get ready to complete this program. Change the
program name at the top of the program to "Bounce_Among_Many_Circles",
and, from the File menu, choose Save As New Program to save this
program with that name.
- Now run the program. Notice that, at the bottom of the
window, it's asking you a question. Try answering the question
with nonsense like "what?" or semi-nonsense like "three". The
program just sits there, not responding! That's because we
programmed it to be looking only for an integer, typed using digit keys
only. Maybe our question should have said so! Anyhow, if
you type "14", it will show up in the little window at the bottom of
our program window. Then, you can either click the Submit button
or just tap the Enter key.
- Well, I don't see 14 bumpers. That's because we still have
more programming to do to make that happen. Still, the moving
"ball" has shown up (although it's not moving yet). It's smaller
now, and red, not blue. Tap the F2 key to get it moving.
I'm hoping you'll see it bounce off an edge of the window at least once
before it escapes past one of the window's edges. If it hasn't
escaped yet, wait a while, I think it will! You can use the F1
key to bring it back. Remember to close the running program's
window.
- Why did it escape? When I made the ball smaller, I made it
more likely that, at this high speed, the ball would move in one
iteration, in one jump, from not interacting with an edge to having its
center just past the edge. If that happens, the ball won't
interact with any edges at all and will just keep moving out beyond the
window somewhere. What shall we do about this problem?
Reasonable solutions include making the ball larger and/or reducing its
speed. However, at least in the special case of the four window
edges, we can make a correction to the ball's (MC's) position whenever
it goes out of bounds. The following sequence of two If
statements makes this correction for the bottom and right-hand edges of
the window. Type them in after the comment that says "// bounce
off window borders". LR is the Point at the lower right-hand
corner of the window.
If LR.Y <= MC.Center.Y Then
MC.Center.Y = LR.Y - 1
End If
If LR.X <= MC.Center.X Then
MC.Center.X = LR.X - 1
End If
- See if you can figure out why those two If statements keep MC
from escaping past the window's bottom and right-hand edges.
- Now invent two more If statements to add to this sequence of
statements, one to "guard" the window's top edge, the other to guard
its left edge.
- OK, back to the issue of asking the user for information and
gathering that information. Find near line 39 of the program in
Method Main() where Integer object Number_Of_Circles is defined.
There you see that we call Console.ShowConsole() to begin the process
of prompting for and getting input from the user. Calling
Console.SetHeight() is optional, but doing so allows the rest of the
program window to be visible above the Console portion of the
window. You can comment out this line to see how the behavior
differs. Console.ReadInt() is a Function that returns an Integer
(in our case, into object Number_Of_Circles). The Integer it
returns is the one it gets from the user. The question that the
user sees is supplied as ReadInt()'s only parameter. It is
ReadInt() that doesn't allow non-digit characters to appear in the
input window when the user attempts to type them. When we're done
getting user input, we Hide the Console.
- The next definition, with assignment statement and Function call,
"Define CL As CircleList = List_Of_Scattered_Circles( Number_Of_Circles
)", defines CL as an object of type CircleList and gives it a value
that is a list of Number_Of_Circles circles. The Function
List_Of_Scattered_Circles() is defined at the bottom of this
program. Take a minute or so now to read the comment that
describes it.
- What we've done so far is pretty amazing: the user has told us
how many circles to have, and we have that many circles in our list,
CL. All we need to do now is display those circles and make sure
that MC bounces off them.
- The circles in CL are numbered from 1 to Number_Of_Circles.
Circle 3 (if there is one!), has the name CL.Item( 3 ). So, the
call to draw that circle would be "CL.Item( 3 ).Draw()".
Similarly, the call to bounce MC against that circle would be
"CV_Circ_Bounce_Circ( MC, MC_Velocity, CL.Item( 3 ) )". What we
want to do, at the bottom of the main event loop, before the call the
RefreshScreen(), is repeat those two actions for each of the circles in
the list. We can do this by defining an Integer object, say "cn"
for circle number, and having cn's value be 1, 2, 3, 4, and so on up to
Number_Of_Circles, and making the two repeated actions on circle number
cn.
- A "while" loop can help us make cn take on this sequence of
values. Type the following before the call to RefreshScreen():
Define cn As Integer = 1 // circle number
While cn <= Number_Of_Circles
cn = cn + 1
End While
- OK, left like that, this loop won't do anything for us but take
up a little time. But, now, you can insert, before the assignment to cn (order
is especially important here), the two necessary actions, one to draw
the circle and the other to bounce MC against it.
- Please note that you have used a "while" loop to good effect when
it wasn't the main event loop of the program. In fact, this
"while" loop is inside the
program's main event loop.
- Run the program to try it!
- You could also note that there is a "while" loop in the body that
implements Function List_Of_Scattered_Circles().
- There is one important difference to note between a program that
moves sprites, but doesn't draw things like circles, and this one, that
draws circles (but could also move sprites). The main difference
is the call, near the beginning of the main event loop, to
BeginFrame(). This call causes Phrogram to not display any
changes in the program window until the next call to
RefreshScreen(). Handling it this way keeps things from happening
in the window one at a time and keeps the frame time lower by not
slowing things down to draw one thing at a time. For example, the
very next statement, ClearBackground( Colors.White ), if BeginFrame()
had not been called, would immediately cause the whole window to be
white, then, later, the program would begin to draw on this white
background. This would cause us to see the static circles
flicker, I think. As it is, the call to ClearBackground() only logically makes the whole window
white, and the subsequent drawings happen only logically. Then,
the whole new scene is repainted on top of the old scene by the call to
RefreshScreen().
- If you have extra time, consider making MC large enough to
contain a sprite, calculating where the upper left-hand corner of the
sprite should be based on MC's center, showing the sprite, and always
moving it to MC's new location. Then, you could even comment out
the call "MC.Draw()".
- If you think that using things that you've learned in this closed
lab exercise might help you in your
project, think about how you might change your course project to
include one or more of these attractive things. If you want to
know more, just ask!
4. Proctor Help
If you have a question or get stuck,
raise your hand and one of the proctors will come by to chat.