The Source Code
from gturtle import *
from math import *
from time import sleep
from random import randint
BACKGROUND = makeColor("sky blue")
BULLETCOLOR = makeColor("yellow")
TARGETCOLOR = makeColor("red")
MAXX = 440
CANONPOS = -350
GROUNDLEVEL = -250
INITSPEED = 36
posX = 0
posY = 0
speedX = 0
speedY = 0
def fireBullet(initSpeedX, initSpeedY):
"""Fire the bullet. This function will not return as
long as the bullet is flying."""
global posX, posY, speedX, speedY
posX = CANONPOS
posY = GROUNDLEVEL + 15
speedX = initSpeedX
speedY = initSpeedY
moveBullet()
drawCanon()
while posY > GROUNDLEVEL and posX < MAXX:
moveBullet()
if targetHit():
msgDlg("You hit the target!\nCongratulations!")
repositionTarget()
break
sleep(0.1)
def moveBullet():
"""Move the flying bullet. Recalculate the new position
and speed according to gravity."""
global posX, posY, speedX, speedY
global canonDrawing
while canonDrawing:
sleep(0.001)
setPos(posX, posY)
setPenColor(BACKGROUND)
dot(12)
posX += speedX
posY += speedY
speedY -= 1.25
if posY > GROUNDLEVEL+6:
setPos(posX, posY)
setPenColor(BULLETCOLOR)
dot(10)
targetX = 0
targetY = 0
def repositionTarget():
"""Reposition the target at a random position."""
global targetX, targetY
if targetX > 0:
setPos(targetX, targetY)
setPenColor(BACKGROUND)
dot(60)
targetX = -CANONPOS - randint(0, 50) -20
targetY = randint(GROUNDLEVEL, -GROUNDLEVEL // 2 - 20)+20
setPos(targetX, targetY)
setPenColor(TARGETCOLOR)
dot(40)
setPenColor(makeColor("white"))
dot(25)
setPenColor(TARGETCOLOR)
dot(10)
def targetHit():
"""Check if the bullet hit the target."""
dist = sqrt((posX - targetX)**2 + (posY - targetY)**2)
return (dist <= 25)
canonAngle = 0
canonDrawing = False
def drawCanon():
"""Redraw the canon in the right angle.."""
global canonAngle, canonDrawing
canonDrawing = True
setPos(CANONPOS+15, GROUNDLEVEL+30)
setPenColor(BACKGROUND)
dot(60)
setPos(CANONPOS, GROUNDLEVEL+15)
heading(canonAngle)
penWidth(10)
setPenColor(makeColor("#1A1A1A"))
forward(20)
setPos(CANONPOS, GROUNDLEVEL+15)
setPenColor(makeColor("black"))
dot(20)
canonDrawing = False
def onMouseClick(x, y):
angle = radians(canonAngle)
fireBullet(INITSPEED * sin(angle), INITSPEED * cos(angle))
def onMouseMove(x, y):
global canonAngle
deltaX = x - CANONPOS
deltaY = y - GROUNDLEVEL
if deltaX >= 0 and deltaY >= 0:
canonAngle = degrees(atan2(deltaX, deltaY))
drawCanon()
def mouseMovedCallback(e):
onMouseMove(toTurtleX(e.getX()), toTurtleY(e.getY()))
makeTurtle(mouseMoved = mouseMovedCallback,
mouseHitX = onMouseClick)
hideTurtle()
clear(BACKGROUND)
setPenColor(makeColor("dark green"))
penWidth(10)
setPos(-MAXX, GROUNDLEVEL-5)
moveTo(MAXX, GROUNDLEVEL-5)
setFillColor(makeColor("saddle brown"))
setPos(0, GROUNDLEVEL-10)
fill()
drawCanon()
repositionTarget()