The idea:
It all started when I showed my father a bouncing ball using VPython and how cool this was (less than 10 lines of code). That's really cool why don't we make a Ping-pong game? And that's how the idea was born.
It all started when I showed my father a bouncing ball using VPython and how cool this was (less than 10 lines of code). That's really cool why don't we make a Ping-pong game? And that's how the idea was born.
Scope: This tutorial is meant to be for illustration purpose only. The scope will include a racket hitting the ball at different speeds and directions (vectors), the ball will bounce until it reaches out of bound stopping the simulation. | |
Tools Required
Just access to the internet. Visit www.glowscript.org to see the code is free and no account is required. If you want to make your own create an account and you have to choice to use Python or Java. For more information refer to the Help section which is very helpful. Also it's helpful to know a little bit of Python to read this tutorial but it's really straight forward. The code is written in blue ink so it's easy to differentiate.
The Code
The program consists of 3 sections:
1. Drawing components (tennis table, wall, racket and ball)
2. Setting up vectors for racket and ball
3. Setting the logic for the simulation loop that considers collision, bouncing with racket, table, net and wall.
1. Drawing Components:
Let's start with the most important line of code, import VPython library by:
from visual import *
Then let's get to drawing:
First we draw the table by using the box method. A vector position for reference is required as well as the 3 dimensions and assigned colour.
table_top = box (pos=vector(0,0,0), length=27.4, height=0.2, width=15.2, color=color.green)
Then we draw the table legs at one end of the table, they are not perfectly centred and you will notice if you zoom close enough. Use the same box method. Coordinates follow x,y,z plane. It just takes a little bit of practice to get your bearings.
table_leg1 = box (pos = vector(13.7,-3.8,-7.6), length=0.5, height =7.6, width=0.5, color=color.red)
table_leg2 = box (pos = vector(13.7,-3.8,7.6), length = 0.5, height = 7.6, width=0.5, color=color.red)
The racket, net, the wall and centre line use the same box method so I am not going to display it here and you can see it in the full code. Finally we use the sphere method to draw the ping-pong ball.
ball = sphere (pos=vector(13,3,0), radius=0.2, color=color.white)
2. Setting up vectors and delta time
The velocity vectors are set by invoking the velocity property in the respective objects. Play with the settings and magnitudes and you will see how it works. Velocity vectors are not to be confused as coordinates for the position (pos method).
racket_face.velocity = vector(-0.2,0,0)
ball.velocity = vector(0,-1,0)
dt = 0.01
3. Setting up the logic for the simulation loop
It's better to read the code as a block so the comments explaining the code will be in green after the # sign. Please read through. Also if you are new to Python indentation is important so please keep that in mind.
while 1:
#Notice the rate function sets the pace of the animation, the ball position
#drops down in the vertical direction, while the racket moves faster.
#The 20 factor is optional
rate (75)
ball.pos = ball.pos + ball.velocity*dt
racket_face.pos = racket_face.pos + racket_face.velocity*dt*20
#Check for bouncing in the vertical direction or y axis and let gravity do its
#magic with the gravity constant of 9.8
if ball.pos.y < ball.radius:
ball.velocity.y = abs(ball.velocity.y)
else:
ball.velocity.y = ball.velocity.y - 9.8*dt
#if collision occurs then ball needs to move in the direction that the racket
#face is travelling
if ball.pos.x <= racket_face.pos.x:
ball.velocity.x = ball.velocity.x + racket_face.velocity.x
#ball needs to bounce if it hits the net
if (ball.pos.x < net.pos.x) and (ball.pos.y < net.pos.y):
ball.velocity.x = abs(ball.velocity.x)
#stop the racket otherwise it keeps travelling indefinitely this is done by
#setting the velocity vector to (0,0,0).
if racket_face.pos.x < 10:
racket_face.velocity = vector(0,0,0)
#if ball hits the wall then bounce by reversing direction and using absolute
#value of the direction vector.
if ball.pos.x < wall.pos.x:
ball.velocity.x = abs(ball.velocity.x)
#if ball is out of bounds then it stops. Notice we are only checking along the
#x axis as the ball will not bounce beyond the wall or will it?
if ball.pos.x > 15:
ball.velocity = vector(0,0,0)
Voilà. End of code.
Just access to the internet. Visit www.glowscript.org to see the code is free and no account is required. If you want to make your own create an account and you have to choice to use Python or Java. For more information refer to the Help section which is very helpful. Also it's helpful to know a little bit of Python to read this tutorial but it's really straight forward. The code is written in blue ink so it's easy to differentiate.
The Code
The program consists of 3 sections:
1. Drawing components (tennis table, wall, racket and ball)
2. Setting up vectors for racket and ball
3. Setting the logic for the simulation loop that considers collision, bouncing with racket, table, net and wall.
1. Drawing Components:
Let's start with the most important line of code, import VPython library by:
from visual import *
Then let's get to drawing:
First we draw the table by using the box method. A vector position for reference is required as well as the 3 dimensions and assigned colour.
table_top = box (pos=vector(0,0,0), length=27.4, height=0.2, width=15.2, color=color.green)
Then we draw the table legs at one end of the table, they are not perfectly centred and you will notice if you zoom close enough. Use the same box method. Coordinates follow x,y,z plane. It just takes a little bit of practice to get your bearings.
table_leg1 = box (pos = vector(13.7,-3.8,-7.6), length=0.5, height =7.6, width=0.5, color=color.red)
table_leg2 = box (pos = vector(13.7,-3.8,7.6), length = 0.5, height = 7.6, width=0.5, color=color.red)
The racket, net, the wall and centre line use the same box method so I am not going to display it here and you can see it in the full code. Finally we use the sphere method to draw the ping-pong ball.
ball = sphere (pos=vector(13,3,0), radius=0.2, color=color.white)
2. Setting up vectors and delta time
The velocity vectors are set by invoking the velocity property in the respective objects. Play with the settings and magnitudes and you will see how it works. Velocity vectors are not to be confused as coordinates for the position (pos method).
racket_face.velocity = vector(-0.2,0,0)
ball.velocity = vector(0,-1,0)
dt = 0.01
3. Setting up the logic for the simulation loop
It's better to read the code as a block so the comments explaining the code will be in green after the # sign. Please read through. Also if you are new to Python indentation is important so please keep that in mind.
while 1:
#Notice the rate function sets the pace of the animation, the ball position
#drops down in the vertical direction, while the racket moves faster.
#The 20 factor is optional
rate (75)
ball.pos = ball.pos + ball.velocity*dt
racket_face.pos = racket_face.pos + racket_face.velocity*dt*20
#Check for bouncing in the vertical direction or y axis and let gravity do its
#magic with the gravity constant of 9.8
if ball.pos.y < ball.radius:
ball.velocity.y = abs(ball.velocity.y)
else:
ball.velocity.y = ball.velocity.y - 9.8*dt
#if collision occurs then ball needs to move in the direction that the racket
#face is travelling
if ball.pos.x <= racket_face.pos.x:
ball.velocity.x = ball.velocity.x + racket_face.velocity.x
#ball needs to bounce if it hits the net
if (ball.pos.x < net.pos.x) and (ball.pos.y < net.pos.y):
ball.velocity.x = abs(ball.velocity.x)
#stop the racket otherwise it keeps travelling indefinitely this is done by
#setting the velocity vector to (0,0,0).
if racket_face.pos.x < 10:
racket_face.velocity = vector(0,0,0)
#if ball hits the wall then bounce by reversing direction and using absolute
#value of the direction vector.
if ball.pos.x < wall.pos.x:
ball.velocity.x = abs(ball.velocity.x)
#if ball is out of bounds then it stops. Notice we are only checking along the
#x axis as the ball will not bounce beyond the wall or will it?
if ball.pos.x > 15:
ball.velocity = vector(0,0,0)
Voilà. End of code.
Future Considerations
There are many things that are not considered in this simulation. For example as you can see there is no condition to check movement in the z direction. Also if you notice closely the ball bounces only on one side of the net. Plus there is no check for collisions of the racket with the ball again. The program also doesn't interact with the user. A cool game will be to catch the ball so it can bounce back. Why don't do we use a racket with a Wii-mote? Check this cool video for even more inspiration.
Cheers for now and happy coding.
There are many things that are not considered in this simulation. For example as you can see there is no condition to check movement in the z direction. Also if you notice closely the ball bounces only on one side of the net. Plus there is no check for collisions of the racket with the ball again. The program also doesn't interact with the user. A cool game will be to catch the ball so it can bounce back. Why don't do we use a racket with a Wii-mote? Check this cool video for even more inspiration.
Cheers for now and happy coding.