First and foremost take the following questions and hints into consideration:
- When does Tracker.update() ever get called?
- When is your window instantiated?
- When do you actually draw a circle onto the window?
- Check out the observer pattern
Your Tracker class is not getting informed about the updates of its object. Also you build the Tracker and Window after the simulation of the cannon ball flight. Right now your call Tracker(GraphWin("Tracker",500,500),cball)
will lead to a single draw operation on the final position of the cannon ball.
To achieve a plot of the curve do:
def main():
angle, vel, h0, time = getInputs()
cball = Projectile(angle, vel, h0)
win = GraphWin("Tracker",500,500,autoflush=False)
while cball.getY() >= 0:
cball.update(time)
Tracker(win,cball)
print("\nDistance traveled: {0:0.1f} meters.".format(cball.xpos))
input("Ready to close? Type any key")
win.close()
Now you create a Tracker after every update, which will draw a circle on the graphics window. This results in many circles being drawn on top of each other, plotting the curve. The drawing is still upside down, so think about your coordinate system again. Also create the window outside of the Tracker objects, otherwise it will be closed once the tracker object gets deleted.
For an animation of the cannon ball you need to change your main() so that the tracker knows that something has changed. For more complex situations the observer pattern is useful, but in this case simply call Tracker::update() after the cannon ball update:
import time as sleeper
def main():
angle, vel, h0, time = getInputs()
cball = Projectile(angle, vel, h0)
win = GraphWin("Tracker",500,500)
win.setCoords(0, 0, 500, 500) #fixed coordinates
tracker = Tracker(win,cball)
while cball.getY() >= 0:
sleeper.sleep(0.1) # wait 0.1 seconds for simple animation timing
cball.update(time)
tracker.update()
print("\nDistance traveled: {0:0.1f} meters.".format(cball.xpos))
input("Ready to close? Type any key") #keep the window open
win.close()