Lesson 18: Animation. Computer Programming is Fun!

Similar documents
Lesson 4: Who Goes There?

How to set up an Amazon Work Profile for Windows 8

Introduction to Flash - Creating a Motion Tween

Scripting Tutorial - Lesson 11: Advanced: Introducing Classes

Working with the Dope Sheet Editor to speed up animation and reverse time.

Android Programming Family Fun Day using AppInventor

Note: Photoshop tutorial is spread over two pages. Click on 2 (top or bottom) to go to the second page.

vi Primer Adapted from:

BEGINNER PHP Table of Contents

HYPERSTUDIO TOOLS. THE GRAPHIC TOOL Use this tool to select graphics to edit. SPRAY PAINT CAN Scatter lots of tiny dots with this tool.

[ the academy_of_code] Senior Beginners

Smoother Graphics Taking Control of Painting the Screen

Your First Windows Form

Adobe Flash CS3 Reference Flash CS3 Application Window

How to make a Work Profile for Windows 10

5. LAPTOP PROCEDURES

HOUR 4 Understanding Events

Lesson 6 page 1. If you look at the bottom right of the Scratch color choices, you will see it say MORE BLOCKS in Purple.

In our first lecture on sets and set theory, we introduced a bunch of new symbols and terminology.

Creating a Brochure in Publisher

Making ecards Can Be Fun!

SolidWorks Intro Part 1b

SolidWorks 2½D Parts

3.7. Vertex and tangent

MITOCW watch?v=4dj1oguwtem

Photoshop tutorial: Final Product in Photoshop:

Shape Cluster Photo Written by Steve Patterson

PowerPoint Introduction. Video: Slide Basics. Understanding slides and slide layouts. Slide Basics

= 3 + (5*4) + (1/2)*(4/2)^2.

PowerPoint Slide Basics. Introduction

COMP : Practical 6 Buttons and First Script Instructions

BCSWomen Android programming (with AppInventor) Family fun day World record attempt

Interactive Tourist Map

Fruit Snake SECTION 1

AN INTRODUCTION TO SCRATCH (2) PROGRAMMING

SPRITES Moving Two At the Same Using Game State

Create a unit using United Streaming and PowerPoint. Materials: Microsoft PowerPoint, Internet access, United Streaming account

The Fundamentals. Document Basics

Earthwork 3D for Dummies Doing a digitized dirt takeoff calculation the swift and easy way

Computer Essentials Session 1 Lesson Plan

Honors Computer Science Python Mr. Clausen Program 7A, 7B

MITOCW watch?v=flgjisf3l78

Adobe Illustrator. Quick Start Guide

Photoshop Tutorial: Basic Selections

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between

GOALS [HTDP/2e Chapters 1 through 3.5]

Introduction to the Turing Programming Language program commands run Exercise #1 not var put get put Programming Names File/Save As..

InfoSphere goes Android Flappy Bird

CISC 1600, Lab 2.3: Processing animation, objects, and arrays

1. What is the difference between a local variable and an object s attribute?

Computer Basics: Step-by-Step Guide (Session 2)

How to lower a car in Paint.NET (PDN) -Tools you will be using:

Workbook Also called a spreadsheet, the Workbook is a unique file created by Excel. Title bar

Draw beautiful and intricate patterns with Python Turtle, while learning how to code with Python.

MITOCW watch?v=se4p7ivcune

2. Write Your Test Questions & Create Interactions Page 12

CS Lab 8. Part 1 - Basics of File I/O

DOING MORE WITH WORD: MICROSOFT OFFICE 2010

Grade 8 FSA Mathematics Practice Test Guide

Lab 2: Conservation of Momentum

Recipes4Success. Animate Plant Growth. Share 4 - Animation

MITOCW watch?v=sdw8_0rdzuw

Adobe Photoshop How to Use the Marquee Selection Tools

Clickteam Fusion 2.5 Creating a Debug System - Guide

Dreamweaver Website 1: Managing a Website with Dreamweaver

Lesson 6 Adding Graphics

Handout Objectives: a. b. c. d. 3. a. b. c. d. e a. b. 6. a. b. c. d. Overview:

Excel 2010: Basics Learning Guide

This chapter is intended to take you through the basic steps of using the Visual Basic

Introduction to Microsoft Excel

Spira Mirabilis. Finding the Spiral tool. Your first spiral

Intro To Excel Spreadsheet for use in Introductory Sciences

The Official E-Portfolio Tutorial Guide

Art, Nature, and Patterns Introduction

Introduction. Table Basics. Access 2010 Working with Tables. Video: Working with Tables in Access To Open an Existing Table: Page 1

Direct Variations DIRECT AND INVERSE VARIATIONS 19. Name

Caustics - Mental Ray

PARTS OF A COMPUTER. (Class III, IV and V)

ICS 61 Game Systems and Design Introduction to Scratch

New to the Mac? Then start with this lesson to learn the basics.

Velocity: A Bat s Eye View of Velocity

Objective: Construct a coordinate system on a plane.

5.1. Examples: Going beyond Sequence

Introduction. Watch the video below to learn more about getting started with PowerPoint. Getting to know PowerPoint

AppyBuilder Beginner Tutorials

Get comfortable using computers

Self-Teach Exercises 1-12 Turtle Pascal

Figure 1: A picture of a ruler inside a sheet protector. Figure 2: Example of measuring a water drop.

CommCare for Android Smartphones

Digital Mapping with OziExplorer / ozitarget

HOW TO. In this section, you will find. miscellaneous handouts that explain. HOW TO do various things.

Windows XP. A Quick Tour of Windows XP Features

VBA Excel 2013/2016. VBA Visual Basic for Applications. Learner Guide

4. Write sets of directions for how to check for direct variation. How to check for direct variation by analyzing the graph :

On the Web sun.com/aboutsun/comm_invest STAROFFICE 8 DRAW

Using Visual Studio.NET: IntelliSense and Debugging

Erasmus+ Project: Yestermorrow Year 1 Maths: Pythagorean Theorem

Tangents. In this tutorial we are going to take a look at how tangents can affect an animation.

Microsoft Excel 2007

Transcription:

Lesson 18: Animation So how do you make your drawings move and change? That's what this section is about. I'd like to introduce you to your new friend, Mr. Timer. A timer gives you the ability to tell your DrawingWindow to run some code again and again at regular time intervals. This is how you make things moved at a controlled speed. To start a timer, use the ontimercall() method on DrawingWindow. Here is a description of ontimercall(): dw.ontimercall(interval_sec, callback) Set a timer that will call a function at regular intervals. dw is a DrawingWindow object. interval_sec is the time interval of the timer, in seconds. callback is the function or method that the timer will call. Return a timer object. You can stop the timer by calling the stop() method on the timer object. In general here are the steps for using a timer. (We will do a specific example in just a moment.) 1. Think about what code you want the timer to run for you. Decide on a name for a function to hold this code. 2. Decide how often you want the function to be called. 3. Decide what data the function needs to use. If the function needs to modify data, then it is better to use a method on a class instead of a function. (I'll show an example of using a class later, in bounceball.py.) 4. Write the function or method. 5. Call dw.ontimercall(interval_sec, callback) where interval_sec is the how often you want the function called, and callback is the name of your function or method (without parenthesis). Here is our first timer example: 1. I have decided that I want the timer to call code that will draw a blue box and print the words drawing a box. I will name the function that does this drawbox(). 2. I want the timer to call my drawbox() function every 5 seconds. 3. The data that my function needs is a DrawingWindow object, because you can't draw anything without a drawing window. I will use a global variable, dw, for DrawingWindow, as usual. 4. In the commands below we will define the drawbox() function. 5. In the commands below we will call dw.ontimercall() with the correct parameters. Try these commands in the Python Shell window to execute our first timer example. >>> from cpif.graphics import DrawingWindow >>> dw = DrawingWindow(100, 100) 123

>>> def drawbox(): print drawing a box dw.box(10, 10, 90, 90, 'black', fill='blue') >>> timer = dw.ontimercall(5.0, drawbox) A blank white DrawingWindow will appear. After a delay of about 5 seconds a blue square appears in the window, and the words drawing a box appear in the Python Shell window. About 5 seconds after the blue square appears, Python prints drawing a box again. Every 5 seconds it will do that. To stop the timer from drawing the box over and over again, call the stop method on the timer, like this: >>> timer.stop() You may be interrupted by the drawing a box message while you are typing. Just keep typing, Python will still accept your command. The Moving Ball Example The moveball.py sample program moves a ball across the screen using a function called by a timer. The function name is moveball(). The function needs two data items: The DrawingWindow object and the ID of a ball that the program drew. Open the moveball.py program in the samples directory. Here is the code: # moveball.py # Draw a ball and make it move from cpif.graphics import DrawingWindow dw = DrawingWindow(200, 200) ball = dw.circle(0, 100, 20, 'black', fill='red') def moveball(): dw.moveby(ball, 10, 0) # move 10 pixels right dw.ontimercall(0.1, moveball) dw.run() # end of file Whoa, don't hit that F5 key yet! There are some other important things about this program I need to point out to you first. Take a look at the moveball() function. New to you is the DrawingWindow moveby() method. Here is how to use it: 124

dw.moveby(id, deltax, deltay) dw is a DrawingWindow object. id is an ID returned by a drawing method, such as dw.circle(). deltax and deltay are the horizontal and vertical distance, in pixels, that the drawing will be moved. In this example, deltax is 10, meaning move 10 pixels right. If it were a negative number it would move the drawing left. deltay is 0, meaning don't move it up or down at all. Finally, please notice that the program ends with dw.run(). If you didn't call dw.run(), the program wouldn't wait while you looked at the window, but instead would exit immediately. You wouldn't see anything and it wouldn't be any fun. dw.run() pauses until the DrawingWindow is shut down, either by your program calling dw.close() or by you clicking the close button in the upper-right corner of the window frame. Ok, that's enough explaining. Press F5 and let's see this thing roll. Hey, where did that ball go? After about two seconds the red ball moved across the window, and then kept on going. It's completely out of view, but the timer keeps on running anyway. A Thought Provoking Question Here's a thought provoking question for you that's not part of the quiz: how would you modify this program to make the ball bounce off of the edges of the window? Right now the ball never changes speed nor direction. We need to find a way to store the speed and direction of the ball, detect when we hit the edge of the window, and change direction. How can we keep track of all that changing data? The answer is, by creating our own Python class. I'll show how to do this in the bounceball.py example next. The Bouncing Ball Example Understanding this example requires a knowledge of Python classes. If you skipped the section on Classes, you might want to go back and read that now. The Moving Ball Example in the previous section got boring very quickly, because after two seconds you are left with an empty window. One way we can fix that problem is to make the ball bounce back when it hits the edge of the window. Of course the ball doesn't actually bounce, but we can simulate bounces by making it change direction. Let's talk a little more about speed and direction, before we get going on our bouncing ball example. Normally we think of speed as a single number, that is, how fast you are going. But to simulate moving objects in a computer program we need to be a little more sophisticated. We'll use a more sophisticated word too: velocity. The velocity of an object moving in a two-dimensional plane must be measured by two numbers. We will use one number for velocity in the X (horizontal) direction, and another number for velocity in the Y (vertical direction.) In my examples I will often use the variables vx and vy as the names for these two numbers. 125

Numbers in the real world are seldom useful unless they are connected with units of measurement. Velocity is measured in units of distance per time, such as meters per second or miles per hour. In our example program, x and y are the location of the ball measured in pixels, and vx and vy are the velocity of the ball measured in pixels per update. The update time is determined by the interval in seconds that we specify when calling dw.ontimercall(). In this program the update time in seconds is controlled by the delay variable. When the ball goes off of the right or left edge of the window, the program will reverse the ball's horizontal velocity by changing the sign of vx, like this: vx = -vx. Likewise when the ball goes past the top or bottom edge of the window, the program will reverse the sign of vy. This will simulate bouncing. Our simulation will not be perfect, however, because the ball may go several pixels past the edge before the program detects that it has gone too far and reverses its direction. I know how to fix this problem, but doing so would make the program much more complicated. Let's just try it out the way it is. Open the bounceball.py program in the samples directory. Here is the code: # bounceball.py # Animate a ball, making it "bounce" off the edges of the window from cpif.graphics import DrawingWindow interval = 0.02 # interval between updates, in seconds width, height = 200, 200 # size of window class MovingBall: def init (self): # starting position of ball self.x = 100 self.y = 100 # starting velocity of ball self.vx = 1.4 self.vy = 0.8 # draw the ball and save its ID self.ball = dw.circle(self.x, self.y, 10, 'black', fill='red') def moveball(self): dw.moveby(self.ball, self.vx, self.vy) self.x = self.x + self.vx self.y = self.y + self.vy 126

if self.x < 0 or self.x >= width: self.vx = self.vx if self.y < 0 or self.y >= height: self.vy = self.vy dw = DrawingWindow(width, height) mb = MovingBall() dw.ontimercall(interval, mb.moveball) dw.run() # end of file This program defines a class called MovingBall, and creates an instance of that class called mb. Notice the function that we passed to dw.ontimercall() was a method on the MovingBall object, mb.moveball. This is necessary in order to give the timer callback access to data that it can change. In this case it needs to change the position and the velocity of the ball, and remember that information from one update to the next. The bouncing effect is accomplished by these lines in the moveball() method: if self.x < 0 or self.x >= width: self.vx = self.vx if self.y < 0 or self.y >= height: self.vy = self.vy Press F5 in the bounceball.py window and watch the little red ball bounce around for a while. Mouse and Keyboard Input This section shows how you can you can make a DrawingWindow respond to input from the mouse and the keyboard. Making Buttons You can create customized buttons that respond to mouse button clicks by following these steps: 1. Draw an object in a DrawingWindow, and save the object's ID. 2. Create a callback function or method that takes one parameter, event. 3. Call dw.onclickcall(), and pass the ID of the drawing, the callback function or method, and your data. Type the following commands in the Python Shell to create a blue circle and turn it into a button that prints a green message: >>> from cpif.graphics import DrawingWindow >>> dw = DrawingWindow(100, 100) >>> def showmessage(event): 127

dw.drawtext(0, 0, Hello, 'green') >>> id = dw.circle(50, 50, 25, 'black', fill='blue') >>> dw.onclickcall(id, showmessage) When you run this code, a white window with a blue disk will appear. When you click the left mouse button on the blue disk you should see this result: Illustration 10Result of clicking example button There is some similarity between setting up a button and setting a timer. In both cases you create a function and then tell Python to call it later. Most graphical programming frameworks follow this general pattern; it's called event-driven programming. There is a very important difference between onclickcall() and ontimercall(): When you use onclickcall(), the first parameter that is passed to your callback function is always an event object. This event object is used to find the current mouse coordinates at the time you clicked the mouse button. This can be useful if you want to click and drag objects. When you write your own callback functions for handling clicks on drawings, follow the example of showmessage() above. If you create a callback function with the wrong number of parameters (say, you forget the event parameter), then when you call onclickcall() or a similar method you will get an error that looks something like this: Traceback (most recent call last):... ValueError: callback must be a function or method that takes 1 parameters Check the callback function that you passed to onclickcall() (in this case, callbackfunc ()) and make sure that it has an event parameter. Here are the details about the DrawingWindow onclickcall() method: dw.onclickcall(id, callback) Set a function to be called when a drawing is clicked. dw is a DrawingWindow object. 128

id is an ID number returned by a drawing method, or an ID returned by begindrawing(). callback: The function to call when the left mouse button is pressed over the drawing. It will be called like this: callback(mouse_event) mouse_event is an object with the following attributes: button_num: 1 for left button, 2 for middle, 3 for right, 0 for no button x: the X window coordinate of the mouse event y: the Y window coordinate of the mouse event If callback is None then any function previously associated with this event is deactivated. Responding to Key Presses You can make your graphics program respond to keyboard commands by following these steps: 1. Write a callback function or method that takes one parameter, event. The function should look at event.char or event.keysym to find out which key has been pressed. (I will explain more about event.char and event.keysym later.) 2. Call the DrawingWindow onkeydowncall() method and pass it your callback function or method, in order to activate your keyboard command. Open the keynames.py program in your samples directory to see an example program that uses onkeydowncall() and prints the event.char and event.keysym values every time you press a key. Here is the program: # keynames.py # Print the key character and symbol name as it is pressed. from cpif.graphics import DrawingWindow dw = DrawingWindow(480, 100) dw.drawtext(0, 0, "Click this window, then type on the keyboard.\n" "See the key names in the text output window.") def callback(event): 129 print "Key pressed:",

print " event.char==" + repr(event.char), print " event.keysym==" + repr(event.keysym) dw.onkeydowncall(callback) dw.run() # end of file I pressed F5 to run the program, and then typed test and pressed Enter. I got the following result: Key pressed: event.char=='t' event.keysym=='t' Key pressed: event.char=='e' event.keysym=='e' Key pressed: event.char=='s' event.keysym=='s' Key pressed: event.char=='t' event.keysym=='t' Key pressed: event.char=='\r' event.keysym=='return' When a key is a letter of the alphabet or a regular typewriter symbol, then event.char is the same as event.keysym, and is usually a string containing one character. When a key is a control character or something that makes the cursor move, etc. then event.keysym contains the name of that key (event.char will usually not be useful for control characters.) Notice that the event.keysym value for the Enter key is 'Return' that's what it is called on older typewriters. Here are the event.keysym values for some of the control keys found on computer keyboards: Esc F1 Left arrow Right arrow Up arrow Down arrow Key 'Escape' 'F1' 'Left' 'Right' 'Up' 'Down' Value of event.keysym You can find the event.keysym values for the rest of the keys on your keyboard by running keynames.py and pressing the keys. Example of Controlling a Program with the Keyboard Some useful things you can do with keyboard commands are exit the program or move an object. The keymove.py program in your samples directory moves a little blue box in the window when you press the arrow keys, and exits the program when you press the Esc key. Here is the program: # keymove.py 130

# Move the box using the arrow keys. Press Esc to exit. from cpif.graphics import DrawingWindow dw = DrawingWindow(640, 480) dw.drawtext(0, 0, "Use the arrow keys to move the box, Esc to quit") box_id = dw.box(310, 230, 330, 250, 'black', fill='light blue') def keycallback(event): if event.keysym == 'Escape': dw.close() elif event.keysym == 'Left': dw.moveby(box_id, 20, 0) elif event.keysym == 'Right': dw.moveby(box_id, 20, 0) elif event.keysym == 'Up': dw.moveby(box_id, 0, 20) elif event.keysym == 'Down': dw.moveby(box_id, 0, 20) dw.onkeydowncall(keycallback) dw.run() # end of file Responding to Key Releases There is a DrawingWindow method called onkeyupcall() that works just like onkeydowncall(), except that the callback function is called when the key is released instead of when the key is pressed. The Lander game example program at the end of the book uses this method. FYI: Appendix 3: Message Boxes on page 162 contains more ways for displaying messages to the user and getting simple input from the user. This lesson gives lots of examples. Hopefully you saw in the examples something similar to a program or part of a program that you'd like to write. Feel free to change and experiment with these sample program; that's a great way to learn. 131

Quiz 18 1. Adapt bounceball.py so that it makes the PythonPowered.gif image move and bounce around instead of the little red ball. Name it bouncelogo.py. (See Drawing Images on page 101.) 2. Write a program called digiclock.py that displays the current time in the upper-left corner of a window, updated once per second, using the DrawingWindow ontimercall() method. Here is an example of how to get a string containing the current time: >>> import time >>> s = time.ctime() >>> print s Sat May 29 18:04:34 2004 Here's a hint: each time the timer is called, you need to delete the previous text you have drawn before drawing the new time. Otherwise, your clock will look very strange. You'll need to use a class to keep track of the data, and have the timer call a method of that class, as in bounceball.py. 3. Write a program called clickme.py that draws a circle of radius 25 in the middle of a 200 by 200 window. When you click on the circle, it moves 25 pixels to the right. If you keep on clicking it, it moves completely out of sight. Reminder: The function or method that is called when you click the circle needs to take an event parameter as described above. 132