CS 111 f21 — Advanced Objects
1 Practice
1.1 Give a definition for the following words in the context of Python classes1
- Class
- Instance
- Instance Variables
- Methods
- Constructor
1.2 Extend Point class so we can add two points together2
2 Alien Clicker game
# Alien Clicker game, requires pgl.py # demonstrates class inheritance, static variables, and handling animation and mouse actions with pgl # (c) 2020 Aaron Bauer, Carleton College from pgl import GImage, GWindow, GRect import random class Alien(GImage): # inherit from the GImage class population = 0 def __init__(self, gw, x, y): # first thing we should do is construct the GImage (the superclass) super().__init__("alien-small.png", x, y) # call the GImage constructor self.xvel = 1 self.yvel = 1 self.gw = gw # each instance needs to keep track of the graphics window to refer to in other methods gw.add(self) # add this instance to the window Alien.population += 1 # increment our static variable def get_speed_factor(self): # use our static variable to return a multiplier for the velocity # Aliens move faster the fewer there are if Alien.population > 10: return 1 if Alien.population > 5: return 1.5 if Alien.population > 2: return 2 if Alien.population > 1: return 4 return 8 def update(self): # move this instance self.move(self.xvel * self.get_speed_factor(), self.yvel * self.get_speed_factor()) # bounce off window edges if self.x < 0 or self.x > self.gw.getWidth() - self.getWidth(): self.xvel *= -1 if self.y < 0 or self.y > self.gw.getHeight() - self.getHeight(): self.yvel *= -1 def mousedown_action(self, objects): # when an Alien is clicked on, remove it and decrement the population self.gw.remove(self) objects.remove(self) Alien.population -= 1 if __name__ == "__main__": # create the window and use a GRect to provide a black background gw = GWindow(600, 800) background = GRect(0, 0, 600, 800) background.setFilled(True) background.setFillColor("black") gw.add(background) # keep a list of the moving objects so we can call their update method objects = [] def update(): for obj in objects: obj.update() gw.setInterval(update, 10) # call the update function every 10 milliseconds # define a function for what to do when the user presses the mouse button def mousedown_action(e): elem = gw.getElementAt(e.getX(), e.getY()) # get the element at the location of the mouse if elem != None: # if there is an element there (i.e., getElementAt did not return None) print("mouse down on", elem) if hasattr(elem, "mousedown_action"): # if this element has a mousedown_action method, call it elem.mousedown_action(objects) else: # otherwise, create a new Alien (i.e., clicks on the background will create new Aliens) objects.append(Alien(gw, random.randint(0, 500), random.randint(0, 700))) # the GWindow object can associate functions with mouse actions # in this case, we tell it to call mousedown_action every time the user presses the mouse button gw.addEventListener("mousedown", mousedown_action)
Footnotes:
1
- Class: the definition of an object, including its functions (methods) and data (instance variables)
- Instance: a specific object in memory. A program might have many instances of the
Point
class (i.e., manyPoint
objects), each with their own data (i.e., values forx
andy
) - Instance Variables: a piece of data associated with a particular instance. A class will define what instance variables exist for objects of that class, and all instances will have their own versions of those variables
- Methods: a function associated with a class/object
- Constructor: the
__init__
method that assigns initial values to instance variables
2
# 2D point class with an x and y class Point: def __init__(self, x, y): self.x = x self.y = y def __repr__(self): return str((self.x, self.y)) def __add__(self, other): return Point(self.x + other.x, self.y + other.y) p = Point(2, 3) q = Point(-1, 10) print(p + q) # should print (1, 13) print(p) # p shold be unchanged, and this should print (2, 3) print(q) # same for q, should print (-1, 10)