< Back

Lecture 3- Event-Based Programming


As usual, create a directory to hold today's activities:

$ mkdir ~/cs170/labs/lab3 
$ cd ~/cs170/labs/lab3

Events

Up to this point, every program you have written has executed in sequential order. It was very easy to trace through the code by hand, since you could always start with the first instruction and follow through to the next. However, sometimes this is not entirely desireable. There are occasions where non-sequential execution is useful.

Tkinter is designed so that events can occur, and allows you to define an event handler that decides what to do when the event happens. You will use this to create programs that allow for user interaction in today's lab.


Lab Activity 1
Pong Paddles

Back to the old classics. You can now draw to the Tk canvas. Today we start manipulating the objects we have drawn. We performed animation on Wednesday by using a loop. However, we also would like to interact with the program. Use the event based programming constructs to allow users to control two rectangles on the screen.

Details

Create a program in a file called pong.py that allows two different players to control two different pong paddles. Each pong paddle will be represented by a single rectangle on either side of the window.

One of the players should control their paddle with the mouse, while the other will be controlled by the keyboard. The mouse player should change the y location of the paddle by moving the mouse when the left mouse button is depressed , while the keyboard player should use the up and down arrow keys to change the position of the paddle.

Hint

  • You need to create two rectangles, one for each paddle. Since the create_rectangle method returns an ID that can be used to later change the drawn rectangle, you will need to keep track of this separately for each paddle.

  • You will need to bind both the <B1-Motion> and the <Key> events, and you will need one event handler for each of them.

    The event object for the mouse will have x and y as attributes, which is the current coordinates of the mouse in the canvas. The event object for the keyboard will have a keysym attribute, which will describe which key was pressed.

  • The keyboard controlled player can change the paddle using the move method. However, because the mouse gives you a new position you need to use the coords method to update the mouse controlled paddle.

 

Challenge

Using rectangles is fine, but kind of a bit boring. A "real" pong game wouldn't use a simple rectangle for the paddle. Instead, it would use an image for the paddles!

Search on Google, or use GIMP to create your own paddle images. Then look at the documentation for the Tk Canvas Object, as well as the PhotoImage documentation. Load your images instead of using the rectangles. Can you make the paddle images you are using the same size as the rectangles, without manipulating the image manually?


Lab Assignment 3
Pong

Details

In the pong.py file with your paddle code, create an oval that can travel around the screen. You already have code that allows the ball to bounce around all 4 sides of the screen. Modify this code so it also bounces off the paddles.

Remember, you can use canvas.coords to get the current location of some entity that you have tagged. It gives you 4 values back: the upper left coordinate, and the lower right coordinate. You can use this method to get the current coordinates of not only your ball, but the paddles as well. That should simplify things greatly.

Collisions here can be perfect collisions: They only flip the sign on the a single dimension of the ball's velocity. You can make more complicated collisions later.

Hint

  • Collisions with the paddles is easier if you abstract the logic. Create a function called collision_detection_rectangles, which takes 2 parameters: the tag for the ball and the tag for the paddle. This should return True if the bounding rectangle of the ball intersects with the rectangle for the paddle.

    Plan this out on paper first. Which coordinates of the paddle need to be compared with which components of the ball?

  • With the above function written, collisions with the paddle should basically replace the collisions with the two side walls. Just call the above function with both paddles, and if either returns True change the sign of the x-coordinate of the ball.

 

Challenge

As you have probably noticed, the ball gets stuck in the paddle if you happed to collide with the top (or bottom) of the paddle! There are two ways to deal with this: either make the paddle thin enough that it is not an issue, or handle collisions better. I personally prefer the latter, so why don't you fix the collisions.

The simple way to fix the top collisions is to also flip the y velocity if you hit the top or bottom of the paddle. That fixes the main issue, but is still less interesting. Real pong games change the angle at which the ball is moving, depending on where the ball hit on the paddle.

So, instead of simply flipping the velocity in the direction that intersects, you should determine a new angle for the ball that varies depending on the distance the center of the ball is from center of the paddle. Then, update the x an y components of the velocity based off this new angle.

 


Submission

When you have finished, create a tar file of your lab3 directory. To create a tar file, execute the following commands:

cd ~/cs170/labs
tar czvf lab3.tgz lab3/

To submit your activity, go to inquire.roanoke.edu. You should see an available assignment called Lab Assignment 3. Make sure you include a header listing the authors of the file.