# Copy a little picture onto a background picture at x,y # But only copy those parts of the little picture that are within the # bounds of the background picture def copyPicture(littlePic, bg, x, y): for fromX in range(1, getWidth(littlePic)): for fromY in range(1, getHeight(littlePic)): # Work out where the current pixel should be copied to fromPixel = getPixel(littlePic, fromX, fromY) destX = fromX + x destY = fromY + y # And copy it if it is within bounds. # This uses logical (true/false) variables as discussed in class betweenLeftAndRight = 0 < destX <= getWidth(bg) betweenTopAndBottom = 0 < destY <= getHeight(bg) if betweenLeftAndRight and betweenTopAndBottom: destPixel = getPixel(bg, destX, destY) setColor(destPixel, getColor(fromPixel)) # Write a frame to a file using the standard naming convention. # We can write up to 999 frames prepending leading 0 or 00 def writeFrame(frame, stem, num): numText = str(num) if num < 100: numText = "0" + numText # Pre-pend leading zero if num < 10: numText = "0" + numText # Pre-pend an additional leading zero fileName = stem + numText fileName = fileName + ".jpg" writePictureTo(frame, getMediaPath(fileName)) # Make a list of sprites (pictures) from sequence of named files # Note: This only works for 12 (count them) files called john_cleese_N.png # Where N is a number between 1 and 12, inclusive. # Those files have to be in the media path. def makeSprites(): sprites = [] # Start with an empty list # Make each sprite in turn and add it to the list for spriteNum in range(1, 13): # note that runs from 1 to 12 really currentFile = "john_cleese_" + str(spriteNum) + ".png" currentSprite = makePicture(getMediaPath(currentFile)) sprites = sprites + [currentSprite] # concatenate a 1-element list, not a picture return sprites # Make the Silly Walk video def makeSillyWalk(): numFrames = 100 width = 640 height = 480 # Variables for the cleese sprites speed = 4 cleeses = makeSprites() # Variables for the falling weight weight = makePicture(getMediaPath("weight.gif")) dropTime = 90 weightX = width - getWidth(weight) - 100 startingY = -getHeight(weight) distanceFallen = height timeToFall = (numFrames - dropTime) fallingRate = distanceFallen/timeToFall # And now for something completely different: the loop that produces the frames for frameNum in range(numFrames): printNow("Processing frame number " + str(frameNum) + " out of " + str(numFrames)) frame = makeEmptyPicture(width, height) # Find current sprite, cycling through the sprite list currentSprite = cleeses[frameNum % len(cleeses)] # Calculate x and y and copy sprite there x = frameNum * speed y = getHeight(frame) - getHeight(currentSprite) copyPicture(currentSprite, frame, x, y) # Drop the weight, but only if it is time if frameNum >= dropTime: weightY = startingY + fallingRate * (frameNum - dropTime) copyPicture(weight, frame, weightX, weightY) # Write frame to file writeFrame(frame, "sillyWalk", frameNum)