# 15-112 Agenda 18-June

• No lecture thursday
• review in recitation wed/thurs
• thurs 8pm-10pm is practice midterm review
• Optional lectures coming up
• Some hints on the structure of the final
• Attendance Check: https://tinyurl.com/summer112att17
• How do we merge animations and OOP?
• Tour of homework
• Why do this?
• Reuse code
• Easier to maintain
• Much easier to read: circle[0] vs circle.x
```from tkinter import *

class BasicMovingSquare(object):

def __init__(self, x, y, r, fill):
self.x = x
self.y = y
self.r = r
self.fill = fill

def draw(self, canvas):
x,y,r = self.x, self.y, self.r
canvas.create_rectangle(x - r, y - r,x + r, y +r, fill=self.fill, width=0)

def move(self, dx, dy):
self.x += dx
self.y += dy

def intersects(self, other):
dx = abs(self.x - other.x)
dy = abs(self.y - other.y)
dis = self.r + other.r
return dx <= dis and dy <= dis

class Bullet(BasicMovingSquare):

def __init__(self, x, y):
super().__init__(x,y,5, "blue")

def move(self):
dy = -80
super().move(0, dy)

class Player(BasicMovingSquare):

def __init__(self,x,y,r):
self.bullets = []
self.dx = 30
super().__init__(x,y,r,"black")

def draw(self,canvas):
super().draw(canvas)
gunR = 50
canvas.create_line(self.x, self.y, self.x, self.y - gunR , width=4)

def moveLeft(self):
super().move(-self.dx, 0)

def moveRight(self):
super().move(self.dx, 0)

def getActiveBullets(self):
return self.bullets

def shoot(self):
self.bullets.append(Bullet(self.x, self.y))

class Enemy(BasicMovingSquare):

def __init__(self, x,y,r, health=1):
self.health = health
self.dir = 1
super().__init__(x,y,r,"red")

def isHit(self, bullet):
if self.health == 0:
return False
return self.intersects(bullet)

def kill(self):
self.health = 0
self.fill = "black"

def move(self, screenWidth):
if self.health == 0:
return
super().move(self.dir * 30, 0)
if self.x + self.r >= screenWidth:
self.dir = -1
self.x = screenWidth - self.r -1
if self.x - self.r <= 0:
self.dir = 1
self.x = self.r + 1

####################################
# customize these functions
####################################

def init(data):
playerR = 20
playerX = data.width // 2
playerY = data.height - playerR
data.player = Player(playerX,playerY, playerR)
enemyR = 40
enemyX = playerX
enemyY = 80
data.enemy = Enemy(enemyX, enemyY, enemyR)
data.score = 0

def keyPressed(event,data):
if event.keysym == "Left":
data.player.moveLeft()
elif event.keysym == "Right":
data.player.moveRight()
elif event.keysym == "space":
data.player.shoot()

def timerFired(data):
data.enemy.move(data.width)
for bullet in data.player.getActiveBullets():
bullet.move()
if data.enemy.isHit(bullet):
data.enemy.kill()

def mousePressed(event,data):
pass

def redrawAll(canvas, data):
canvas.create_text(20,20,text=str(data.score))
data.player.draw(canvas)
data.enemy.draw(canvas)
for bullet in data.player.getActiveBullets():
bullet.draw(canvas)

####################################
# use the run function as-is
####################################

def run(width=300, height=300):
def redrawAllWrapper(canvas, data):
canvas.delete(ALL)
canvas.create_rectangle(0, 0, data.width, data.height,
fill='white', width=0)
redrawAll(canvas, data)
canvas.update()

def mousePressedWrapper(event, canvas, data):
mousePressed(event, data)
redrawAllWrapper(canvas, data)

def keyPressedWrapper(event, canvas, data):
keyPressed(event, data)
redrawAllWrapper(canvas, data)

def timerFiredWrapper(canvas, data):
timerFired(data)
redrawAllWrapper(canvas, data)
# pause, then call timerFired again
canvas.after(data.timerDelay, timerFiredWrapper, canvas, data)
# Set up data and call init
class Struct(object): pass
data = Struct()
data.width = width
data.height = height
data.timerDelay = 100 # milliseconds
root = Tk()
init(data)
# create the root and the canvas
canvas = Canvas(root, width=data.width, height=data.height)
canvas.pack()
# set up events
root.bind("<Button-1>", lambda event:
mousePressedWrapper(event, canvas, data))
root.bind("<Key>", lambda event:
keyPressedWrapper(event, canvas, data))
timerFiredWrapper(canvas, data)
# and launch the app
root.mainloop()  # blocks until window is closed
print("bye!")

run(600,600)
```