
Lesson 3 - Creating Motion
In this lesson we look at how to move an object.
Objectives
By the end of the lesson the student should be able to:
Understand how to move an object across the screen.
Understand how to detect obstacles and take some action, eg reflection.
Understand how to run an infinite loop and control it with the'rate()' function.
Add an attribute to an object "on-the-fly" and use it in calculations.
Timings
Teaching: 40 min
Exercises: 20 min
The progam
The code below constructs 4 walls on all sides of the scene, which encase a ball.
In this lesson we will learn how to make the ball move and how it interacts with other objects inside the scene.
right_side = 4.0 #define user variable 4 units in the x direction for the right side of box
left_side = -4.0 #define user variable -4 units in the x direction for the left side of box
top_side = 4.0 #define user variable 4 units in the y direction for the top side of box
bottom_side = -4.0 #define user variable 4 units in the -y direction for the bottom side of box
thickness = 0.3 # define user variable to represent the 'wall' thickness
wallw = 2*right_side - thickness # use the wall thickness to generate the wall width
wallh = 2*right_side + thickness # use the wall thickness to generate the wall height
# create the walls
wallR = box (pos=vector( right_side, 0, 0), size=vector(thickness, wallw, wallh), color = color.red) # left wall
wallL = box (pos=vector(left_side, 0, 0), size=vector(thickness, wallw, wallh), color = color.red) # right wall
wallB = box (pos=vector(0, top_side, 0), size=vector(wallw, thickness, wallw), color = color.blue) # bottom wall
wallT = box (pos=vector(0, bottom_side, 0), size=vector(wallw, thickness, wallw), color = color.blue) # top wall
#create a ball using a sphere
ball = sphere (color = color.green, radius = 0.4)
#create a vector attribute for direction and bind it to the ball
ball.direction = vector (1, 0, 0) # an 'x' component is added to the direction vector: this determines the direction the ball moves in
side = right_side - thickness*0.5 - ball.radius # since all the sides are the same size we can use 'size' to represent all the walls.
#we subtract the wall thickness and the radius of the ball so that the ball appears to bounce when it touches the side (or it would pass through the wall!
increment = 0.01
#a small increment in position: this effectively controls the apparent velocity
while True: # an infinite loop
rate(200) #set the program to update 200 times per second
ball.pos = ball.pos + ball.direction*increment
if not (side > ball.pos.x > -side): # A logical operation
ball.direction.x = -ball.direction.x #if ball hits wall reverse direction
Things to note
Motion is acheived by incrementing the position vector of the ball.
The ball has had added an attribute which controls the velocity and direction.
In the example, the only component is in the x direction.
The program uses an infinite loop -"while True:". Since True is always true it will repeat forever.
When using infinite loops, it is important to use the 'rate()' function to limit the number of frames per second the program runs at.
Using the 'rate(frequency) function also ensures the speed appears the same on different computers with different capabilities.
Exercise 1
Copy the program above and do the following:
Make the ball bounce off of the sides, top and bottom of the box.
Optionally, add add trail to the ball by adding a 'maketrail attribute,
with a length=30, make_trail=True, retain=30.
This will emphasize the motion and test your understanding of adding extra attributes to the constuctor object.
Solution to Exercise 1
right_side = 4.0 #define user variable 4 units in the x direction for the right side of box
left_side = -4.0 #define user variable -4 units in the x direction for the left side of box
top_side = 4.0 #define user variable 4 units in the y direction for the top side of box
bottom_side = -4.0 #define user variable 4 units in the -y direction for the bottom side of box
thickness = 0.3 # define user variable to represent the 'wall' thickness
wallw = 2*right_side - thickness # use the wall thickness to generate the wall width
wallh = 2*right_side + thickness # use the wall thickness to generate the wall height
# create the walls
wallR = box (pos=vector( right_side, 0, 0), size=vector(thickness, wallw, wallh), color = color.red) # left wall
wallL = box (pos=vector(left_side, 0, 0), size=vector(thickness, wallw, wallh), color = color.red) # right wall
wallB = box (pos=vector(0, top_side, 0), size=vector(wallw, thickness, wallw), color = color.blue) # bottom wall
wallT = box (pos=vector(0, bottom_side, 0), size=vector(wallw, thickness, wallw), color = color.blue) # top wall
#create a ball using a sphere
ball = sphere (color = color.green, radius = 0.4, make_trail=True, retain=30) # leave a 30 segments trail
#create a vector attribute for direction and bind it to the ball
ball.direction = vector (1, 0.5, 0) # an 'y' component is added to the direction vector: this determines the direction the ball moves in
side = right_side - thickness*0.5 - ball.radius # since all the sides are the same size we can use 'size' to represent all the walls.
#we subtract the wall thickness and the radius of the ball so that the ball appears to bounce when it touches the side (or it would pass through the wall!
increment = 0.01
#a small increment in position: this effectively controls the apparent velocity
while True: # an infinite loop
rate(200) #set the program to update 200 times per second
ball.pos = ball.pos + ball.direction*increment
if not (side > ball.pos.x > -side): # A logical operation
ball.direction.x = -ball.direction.x #if ball hits wall reverse direction
if not (side > ball.pos.y > -side): #
ball.direction.y = -ball.direction.y #if ball hits top or bottom reverse direction
Conclusion
You should now be able to:
Understand how to move an object across the screen.
Understand how to detect obstacles and take some action, eg reflection.
Understand how to run an infinite loop and control it with the'rate()' function.
Add an attribute to an object "on-the-fly" and use it in calculations.
Add a "tail" to an object to show it's path using the make_trail attribute.