CSC111 Animating A Stick Figure
--D. Thiebaut 21:49, 2 December 2011 (EST)
Contents
Original Image
Taken from www.eracewalk.com
Split into frames
- Use an online splitter, such as gifninja.com
Resulting 10 Gif Images
- Once split, the individual images are transformed into individual gif files, and reduced in size:
Step by Step Approach
Step 1: Make the figure appear
from graphics import *
W = 800
H = 600
class StickFig:
def __init__( self, x, y ):
self.index = 0 # frame index
self.image = Image( Point( x, y ), "walk0.gif" )
def draw( self, win ):
self.image.draw( win )
def move( self, dx ):
return
def main():
global H, W
win = GraphWin( "Stick Figure", W, H )
stick = StickFig( W/4, H/2 )
stick.draw( win )
win.getMouse()
win.close()
main()
Step 2: Make figure walk
- Note: we capture the graphics window win in draw() so that we can draw a new image in the move() method. We could also have passed win to move, but it's less logical if we do so...
from graphics import *
W = 800
H = 600
class StickFig:
def __init__( self, x, y ):
self.index = 0 # frame index
self.image = Image( Point( x, y ), "walk0.gif" )
def draw( self, win ):
self.win = win
self.image.draw( win )
def move( self, dx ):
x = self.image.getAnchor().getX()
y = self.image.getAnchor().getY()
self.image.undraw()
self.index = (self.index+1) % 10
self.image = Image( Point( x+dx, y ), "walk%d.gif" % self.index )
self.image.draw( self.win )
def main():
global H, W
win = GraphWin( "Stick Figure", W, H )
stick = StickFig( W/4, H/2 )
stick.draw( win )
while True:
stick.move( 3 )
if win.checkMouse() != None:
break
win.getMouse()
win.close()
main()
Step 3: remove flicker
from graphics import *
W = 800
H = 600
class StickFig:
def __init__( self, x, y ):
self.index = 0 # frame index
self.image = Image( Point( x, y ), "walk0.gif" )
def draw( self, win ):
self.win = win
self.image.draw( win )
def move( self, dx ):
x = self.image.getAnchor().getX()
y = self.image.getAnchor().getY()
# keep track of the old image
tempImage = self.image
# draw a new image
self.index = (self.index+1) % 10
self.image = Image( Point( x+dx, y ), "walk%d.gif" % self.index )
self.image.draw( self.win )
# erase the old image (this avoids the flicker)
tempImage.undraw()
def main():
global H, W
win = GraphWin( "Stick Figure", W, H )
stick = StickFig( W/4, H/2 )
stick.draw( win )
while True:
stick.move( 3 )
if win.checkMouse() != None:
break
win.getMouse()
win.close()
main()
Step 4: Wrap Around Edges
from graphics import *
W = 800
H = 600
class StickFig:
def __init__( self, x, y ):
self.index = 0 # frame index
self.image = Image( Point( x, y ), "walk0.gif" )
def draw( self, win ):
self.win = win
self.image.draw( win )
def move( self, dx ):
global W, H
x = self.image.getAnchor().getX()
y = self.image.getAnchor().getY()
# make figure "wrap around edge of window"
if x > W + self.image.getWidth():
dx = -W -self.image.getWidth()
# keep track of the old image
tempImage = self.image
# draw a new image
self.index = (self.index+1) % 10
self.image = Image( Point( x+dx, y ), "walk%d.gif" % self.index )
self.image.draw( self.win )
# erase the old image (this avoids the flicker)
tempImage.undraw()
def main():
global H, W
win = GraphWin( "Stick Figure", W, H )
stick = StickFig( W/4, H/2 )
stick.draw( win )
while True:
stick.move( 3 )
if win.checkMouse() != None:
break
win.getMouse()
win.close()
main()
Step 5: A Group of Stick Figures
from graphics import *
W = 800
H = 600
class StickFig:
def __init__( self, x, y, index=0 ):
self.index = ( abs( index ) )%10 # frame index
self.image = Image( Point( x, y ), "walk0.gif" )
def draw( self, win ):
self.win = win
self.image.draw( win )
def move( self, dx ):
global W, H
x = self.image.getAnchor().getX()
y = self.image.getAnchor().getY()
# make figure "wrap around edge of window"
if x > W + self.image.getWidth():
dx = -W -self.image.getWidth()
# keep track of the old image
tempImage = self.image
# draw a new image on top of old one
self.index = (self.index+1) % 10
self.image = Image( Point( x+dx, y ), "walk%d.gif" % self.index )
self.image.draw( self.win )
# erase the old image (this avoids the flicker)
tempImage.undraw()
def main():
global H, W
win = GraphWin( "Stick Figure", W, H )
sticks = []
for i in range( 4 ):
stick = StickFig( W/4, (i+1)*H / 5, i*3 )
stick.draw( win )
sticks.append( stick )
while True:
for stick in sticks:
stick.move( 10 )
if win.checkMouse() != None:
break
win.getMouse()
win.close()
main()
Step 1
Step 1
Step 1
Step 1
Step 1
Step 1
Finished Source Code
from graphics import *
import time
import random
class Walker:
def __init__( self, x, y, index=0 ):
self.current = index
self.image = None
self.x = x
self.y = y
def move( self, dx, dy ):
x, y = self.x, self.y
if self.image != None:
x = self.image.getAnchor().getX()
y = self.image.getAnchor().getY()
self.image.undraw()
if dx > 0:
self.current = ( self.current + 1 ) % 10
else:
self.current = ( self.current + 10 - 1 ) % 10
self.image = Image( Point( x+dx, y+dy ),
"walk30_%d.gif" % self.current )
self.image.draw( self.win )
def draw( self, win ):
self.win = win
if self.image == None:
self.image = Image( Point( self.x, self.y ),
"walk%d.gif" % self.current )
self.image.draw( win )
def justOne():
W = 800
H = 600
win = GraphWin( "walker", W, H )
walker = Walker( W/2, H/ 2 )
walker.draw( win )
while True:
walker.move( 5, 0 )
time.sleep( 0.2 )
win.getMouse()
win.close()
def several():
W = 800
H = 600
win = GraphWin( "walker", W, H )
walkers = []
for i in range( 4 ):
walkers.append( Walker( W/2, 140 * i + 70, (i*2)%10 ) )
for walker in walkers:
walker.draw( win )
while True:
for i, walker in enumerate( walkers ):
if i == 0:
walker.move( -5, 0 )
else:
walker.move( 5+random.choice( [0,1,2,3] ), 0 )
win.getMouse()
win.close()
def main():
#justOne()
several()
main()