Example: OOPy Dots Demo
# oopyDotsDemo.py
# starts with betterDotsDemo and adds:
# * a dotCounter that counts all the instances of Dot or its subclasses
# * a MovingDot subclass of Dot that scrolls horizontally
# * a FlashingMovingDot subclass of MovingDot that flashes and moves
from cmu_112_graphics import *
import random
####################################
# customize these functions
####################################
def distance(x0, y0, x1, y1):
return ((y1-y0)**2 + (x1-x0)**2)**0.5
class Dot(object):
def __init__(self, x, y):
self.x = x
self.y = y
self.r = random.randint(20, 50)
self.color = random.choice(['cyan', 'green', 'yellow'])
self.score = 0
def getBounds(self):
return self.x-self.r, self.y-self.r, self.x+self.r, self.y+self.r
def draw(self, canvas):
x0, y0, x1, y1 = self.getBounds()
canvas.create_oval(x0, y0, x1, y1, fill=self.color)
canvas.create_text((x0+x1)/2, (y0+y1)/2, text=self.score)
def clicked(self, x, y):
return distance(self.x, self.y, x, y) <= self.r
def onTimerFired(self, canvasWidth):
pass
class MovingDot(Dot):
def onTimerFired(self, canvasWidth):
speed = 5
self.x = (self.x + speed) % canvasWidth
class FlashingMovingDot(MovingDot):
def __init__(self, x, y):
super().__init__(x, y)
self.timer = 0
self.isFlashing = False
def onTimerFired(self, canvasWidth):
super().onTimerFired(canvasWidth) # do the regular moving part
self.timer += 1
if self.timer % 5 == 0:
self.isFlashing = not self.isFlashing
def draw(self, canvas):
if self.isFlashing:
x0, y0, x1, y1 = self.getBounds()
canvas.create_rectangle(x0, y0, x1, y1, fill="light gray")
# still do the regular drawing
super().draw(canvas)
def appStarted(app):
app.dots = []
def mousePressed(app, event):
clicked = False
for dot in app.dots:
if dot.clicked(event.x, event.y):
dot.score += 1
clicked = True
if clicked: return
dotType = len(app.dots) % 3
if dotType == 0:
app.dots.append(Dot(event.x, event.y))
elif dotType == 1:
app.dots.append(MovingDot(event.x, event.y))
else:
app.dots.append(FlashingMovingDot(event.x, event.y))
def keyPressed(app, event):
# use event.key
pass
def timerFired(app):
for dot in app.dots:
dot.onTimerFired(app.width)
def redrawAll(app, canvas):
for dot in app.dots:
dot.draw(canvas)
runApp()