As usual, create a directory to hold today's activities:
$ mkdir ~/cs170/labs/lab4 $ cd ~/cs170/labs/lab4
Hand in your Pseudocode at the beginning of class. I will look at them this evening, and upload comments to inquire by tomorrow. My structure is here, and we will talk about it in class today.
Sorry, but it had to be done. This is a timed quiz, so please answer the questions located here. When you are done, look at the comments I uploaded for lab 2 on inquire.
For the first time in the CPSC 120/170 sequence, I allowed you to
use the global
statements on Friday. We needed to use
a global statement because we needed more information in our event
handler than we were allowed to provide. This is going to be a
commonly occuring problem with Tkinter, so we need to figure out a
way around that.
One mechanism for getting around this is through the use of objects. Writing an event handler in a class allows for us to access the attributes of that object on top of the event object that gets passed. Today we will see how this can be done, and you will practice writing classes and creating objects today.
On Friday we seemed to struggle with getting paddles moving with the bouncing ball. Today, we are going to reduce the work load by going back to just getting a ball bouncing around the screen. However, we are going to accomplish this today using classes!
Create a class called Ball
in a file
called ball.py. This class should have two
methods: __init__
and move_ball
.
The __init__
method should create ALL of the
necessary attributes for the ball, while move ball should actually
move the ball, making sure the ball bounces off the boundaries of
the canvas.
In addition to this class, write a file called test_ball.py. This file should generate and animate at least 20 randomly generated balls bouncing around the screen. Each ball should have a random starting location, radius, and velocity.
In order to draw and animate the ball, you need at least 5 attributes: The canvas the ball is drawn on, the id of the ball on the canvas, the radius of the ball, and the speed in the x and y directions.
Your constructor needs to take 6 parameters to get the ball started: the canvas the ball is drawn on, the initial x and y position of the ball, the radius of the ball, and the speed of the ball in the x and y directions. You should set all of the 5 attributes above in the constructor, which means you should draw the ball in the constructor as well.
move_ball should perform the exact same operation as our
previous bouncing ball program did. Get the coordinates of
the ball using the coords
method of the canvas.
If the coordinates of the ball are outside the boundary of
the canvas, flip the appropriate speed.
test_ball.py should create a list of 20 Ball
objects. It should then loop through this list
calling move_ball
on each one of them before
calling canvas.update
and sleeping.
Your animation right now is going to look a little dull, since it will be just a
bouncing around the screen. Alter the ball class so that it randomly generates a fill color for the circles.Let's assume that this program you have written is now a physics simulation of a bunch of
bouncing around in a rectangular environment. The one piece that is missing is for the balls to bounce off of each other. To accomplish this, you will need to add a method for determining if two balls are colliding.
Modify your Ball
class to have a method
called handle_collisions
, which should take another
ball as a parameter and alters the speeds of the ball if it is
colliding with the passed ball. For these collisions, you simply
need to swap the respective components of speed between the two
balls. So, if ball A collides with ball B, ball A gets ball B's velocity
and vice versa.
Alter your test program so it also checks for collisions between all of the balls. When you run your program, you should be able to see the balls bouncing off of one another.
You do not need to add any attributes to the Ball class for this.
The method header should look like handle_collisions(self, other_ball)
.
Two circles are colliding if the distances between their center points is less than the sum of their radii. You can compute the distance using the euclidean distance formula: $$d = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}$$
test_ball.py now needs to check collisions between all possible pairs of balls in your program. You need to have a nested for loop to accomplish this.
The collisions required for this exercise are not really physically realistic. This simulation essentially assumes that all of the balls have the same exact mass. Let the radius of the ball also define its mass. Accounting for differing masses, the new component of the speed of the ball can be computed using the equation: $$v_1 = \frac{u_1 \times (m_1 - m_2) + 2 \times m_2 \times u_2}{m_1 + m_2}$$
Where \(u_1\) is the velocity of this ball before the collision, \(u_2\) is the velocity of the other ball before the collision, \(m_1\) is the mass of this ball, and \(m_2\) is the mass of the other ball.
When you have finished, create a tar file of your lab4
directory. To create a tar file, execute the following commands:
cd ~/cs170/labs tar czvf lab4.tgz lab4/
To submit your activity, go to inquire.roanoke.edu. You should
see an available assignment called Lab Assignment 4
.
Make sure you include a header listing the authors of the file.