The goal of this project is to give you more experience writing child classes, working with equations and code, and integrating user input.


RotatingBlock Class

The first task is to create a RotatingBlock class. You could create this in your physics_objects.py file, or in the rotation.py file you created for lab, or in a new file. (The test code provided, however, will be written as if RotatingBlock is in physics_objects.py.)

The RotatingBlock class should inherit from the Thing class, just like Ball, Wall, Floor and Block. The RotatingBlock.__init__() method should have the following arguments:

winReference to a GraphWin object
x0Value of the x coordinate of the center of the block.
y0Value of the y coordinate of the center of the block.
widthThe horizontal distance of the block.
heightThe vertical distance of the block.
AxValue of the x coordinate for the anchor point of the rotation. The default value is None.
AyValue of the y coordinate for the anchor point of the rotation. The default value is None.

Using the same terminology as for rotating lines, [x0, y0] is the anchor point for the block (i.e., the center of its rectangular shape), whereas [Ax, Ay] refers to the anchor point for the rotation of the block (i.e., the point around which the block rotates). Also, as with the RotatingLine class, if there are no values input for Ax and Ay, we'll use [x0, y0] as the anchor point for the rotation.

As with the Ball class, the first action in the __init__() method is to call the parent Thing.__init__() method. Specify the type as the string "rotating block", and set the position to be [x0, y0]. Next, assign the parameters width and height to two fields width and height.

Next, create the list of vertex points (self.points), which should be a list of four 2-element lists. The coordinates of the block should be (-width/2, -height/2), (width/2, -height/2), (width/2, height/2), and (-width/2, height/2). (Note: The order of these 2-element lists matters! It's used to specify how the block is drawn. If you'd like, try changing the order and see how the shape that's drawn changes!)

The remaining unique fields should be identical to the ones you created in the RotatingLine class: angle, rvel, anchor, and drawn. Note that scale and vis are already created and initialized in the Thing parent class.


Make the methods draw(), getAngle(), setAngle(), getAnchor(), setAnchor(), getRotVelocity(), setRotVelocity(), and rotate(). These should be very similar, if not identical to, the methods in the RotatingLine class from lab.

Make the render() method. Again, this will be essentially identical to the RotatingLine version, except that the last step will be to create a graphics Polygon instead of a Line, using the list of rotated points.

At this point, you can run the first test function. (Recall that you may need to modify the test code, depending on where you wrote your RotatingBlock class.) The block should spin around once.

Next, create an update() method in the RotatingBlock class--we can't just inherit update()from the Thing class, because the Thing.update() method does not include rotational velocity. This new update() method needs to take self and dt (the timestep) as arguments.

First, the update() method should calculate how much the angle changes during the timestep (self.rvel * dt) and assign that to a local variable (e.g., da). If the da value is not equal to zero, then call the rotate() method, passing in da as the argument. Then, call the update() method in the Thing class, passing in self and dt. (Please make sure the acceleration and force are initialized to 0 in both x and y dimensions in your Thing.__init__() method.)

Once you have the update() method done, try out the second second test function. Since the anchor point is different, the block should appear to rotate around the center of the screen.


Download the new collision.py file. Update the code at the bottom of the file to include keys for ('ball', 'rotating_block') and ('rotating_block', 'ball') in the collision_router part of the code. As part of this update, notice how a few short functions above the collision router enable the router to handle collisions whether or not 'ball' is the first element of the key, and add to that block of functions whatever is needed to handle the two new keys you added to the collision_router code.

Once this is completed, run the third test function.

Obstacle Course

Create a very simple obstacle course with one or two rotating objects. Launch one or more balls into the scene.

Create a video of your simple obstacle course in action and include a link to it on your wiki.

User Interaction

Create a scene that includes at least one rotating object and incorporates some form of user interaction. For example, add paddles to your pinball-style scene from last week that activate when the user hits the space bar. Make something very simple that responds to user input before doing anything more complex.

Create a video of your reactive scene in action and include a link to it on your wiki.


The following are a few examples of potential extensions. Please do not feel that your extensions must be drawn from this list. Get creative, design extensions that interest you, and explain why they are awesome when you present the results in your writeup. Your interest in your own extensions really does make a difference.


Make a new wiki page for your assignment. Put the label cs152f18project10 on the page. Each of you needs to make your own writeup.

In addition to making the wiki page writeup, put the python files you wrote on the Courses server in your private directory in a folder named project10.

Colby Wiki

In general, your writeup should follow the outline below.

© 2019 Eric Aaron (with contributions from Colby CS colleagues).