Hopefully you completed Laser Defense (The Basic Game) and were able to add a laser to a simple code to damage an incoming drone. In this activity we are going to add code to catch the drone after it falls (explained in a moment). We are also going to add code to automate the targeting of the drone.
Airport security is really happy with what you've done. The only problem is that when the drones hit the ground they are so mangled that it is hard to figure out who owns it or where it came from. They designed a rolling platform with a net to catch the drone before it can hit the ground. That is going to be a new challenge for the game. Ideally, there would be an automated system to catch the falling drone, so that is something to think about.
The other change in this activity is that we are going to use the arrow keys to change the angle of the laser instead of the x,y position of the focus. This is a bit more realistic. This also makes the game a bit harder. Later in the activity we will add code to automatically aim the laser at the drone so it is easier to damage the drones that are encroaching on our airspace.
Step 0. Open up the code
Click here to open up the code
Go ahead and run the code to see what happens.
Step 1. Look at the code
There are a number of similarities to the earlier laser defense activity and a number of differences. Take a look and see what you notice:
x = random(250,500); y = 500; vx = random(-10,10); vy = random(-20,-5); dt = 0.1; xlaser = 375; ylaser = 0; theta = 3.141/2; focus_distance = 250; var laseron; function draw(){ // Update location x += vx*dt; y += vy*dt; if (keyIsDown(LEFT_ARROW)) { theta += 0.01; } if (keyIsDown(RIGHT_ARROW)) { theta += -0.01; } if (keyIsDown(UP_ARROW)) { focus_distance += 1; } if (keyIsDown(DOWN_ARROW)) { focus_distance += -1; } if (keyIsDown(32)) { // spacebar laseron = true; } else { laseron = false; } if ( dronehit(x,y,xlaser,ylaser,theta,focus_distance) & laseron ) { vx = 0; vy = -20; // drone is falling } // Draw axes and other stuff display(); drawText("Drone:",50,425); drawText("y = " + m + " x + " + b,50,400); drawText("Laser:",50,350); drawText("y = " + mlaser + " x + " + blaser,50,325); drawBlob(x,y,vx,vy); // Add more graphics here before the end of draw() drawLaser(xlaser, ylaser, theta, focus_distance, laseron); } // end draw() DO NOT ADD ANY CODE AFTER THIS LINE!!!
Make a list of what happens when you press different keyboard keys and how the behavior has changed compared to the earlier laser defense activity.
As mentioned earlier it is important to catch the drone before it crashes to the ground. Here is some code you can add to do that.
Step 2a. Add variables for the capture platform
At the beginning of the code where the variables are initialized add these variables for the position and width of the capture platform
xcapture = 500; ycapture = 10; capture_width = 50;
Step 2b. Show the capture platform
The capture platform is just a line that is centered on xcapture and ycapture. Inside the draw() function and after the display() function you can add this code to visualize the platform:
drawLine(xcapture-capture_width/2,ycapture,xcapture+capture_width/2,ycapture);
Step 2c. Make the A and D keys move the platform
Inside of the draw() function add this code to move the capture platform left and right
if (keyIsDown(65)) { // 'A' key xcapture += -1; } if (keyIsDown(68)) { // 'D' key xcapture += 1; }
If you add this code correctly your program should behave like this
It's not really a game until you can win or lose is it? Here is some code you can put inside the draw() function but AFTER the display() function to win or lose the game:
if (abs(x - xcapture) < capture_width/2 & y < ycapture ) { drawText('You did it!',width/2,height/2); noLoop(); } if (y < 0) { drawText('Oh, no!',width/2,height/2); noLoop(); }
Look at the code! What is it doing?
At this point your program should behave like this
To win the game now involves damaging the drone with the laser AND moving the platform to capture the falling drone which is pretty tricky to do both, especially since the platform doesn't move very fast.
In the next few steps we are going to automate the targeting of the drone to make this task easier to do. The first thing we are going to automate is focus_distance which is the distance from the laser to the drone.
Comment out or remove this code:
if (keyIsDown(UP_ARROW)) { focus_distance += 1; } if (keyIsDown(DOWN_ARROW)) { focus_distance += -1; }
Then replace it with an expression for focus_distance that depends on xlaser,ylaser (which is the x,y position of the base of the laser) and x,y which is the position of the drone.
focus_distance = ????;
Your job is to replace the ???? with an expression to automatically determine the focus distance from those variables.
Hint: A greek mathematician named Pythagoras has an interesting formula that would be useful here
Advice: In this programming language ^2 does not mean to the power of 2. Instead use **2 or just write out the expression twice like x*x
If you can find the right expression your code should behave like this
The game is definitely easier to play now that focus_distance is automatically determined. The next thing that would make it easier would be to automate the positioning of the platform to capture the drone after it is damaged by the laser.
If you look closely at the code you will notice that it gives you the lines of the laser and the drone like this:
Drone: $$ y = m x + b $$
In the code the slope is just m
and the y intercept is b
Laser: $$ y = m_{\rm laser} x + b_{\rm laser} $$
In the code the slope of the laser line is just mlaser
and the y intercept is blaser
If we can figure out the x,y intercept of the two lines we can use that to auto position the platform. This will allow us to comment out or remove this code:
if (keyIsDown(65)) { // 'A' key xcapture += -1; } if (keyIsDown(68)) { // 'D' key xcapture += 1; }
You will want to replace that code with this:
xcapture = ????;
Note: After you calculate the x,y intercept, you only really need the x intercept to position the capture platform because the capture platform is on the ground (y = ycapture). It can only move in the x direction.
After you configure the code to automatically position the capture platform your code should behave like this
You can double check that you are calculating the x,y intercept by saving the x,y values for both the laser and the drone by adding some code into your program that will let you download these numbers to a spreadsheet file. We are going to add code to the game over and win statements because we want to download this file at the end of the game (win or lose).
Here is what your code should look like:
if (abs(x - xcapture) < capture_width/2 & y < ycapture ) { drawText('You did it!',width/2,height/2); saveData(table,'table.csv'); noLoop(); } if (y < 0) { drawText('Oh, no!',width/2,height/2); saveData(table,'table.csv'); noLoop(); }
All you need to do is add this line in those two places:
saveData(table,'table.csv');
Analyze the data in a spreadsheet! Is your formula for the x,y intercept working?
As an optional step, use your trigonometry knowledge to automatically set the angle theta for the laser. This means we can remove this part of the code:
if (keyIsDown(LEFT_ARROW)) { theta += 0.01; } if (keyIsDown(RIGHT_ARROW)) { theta += -0.01; }
and we can replace it with something like this:
theta = ????;
If you can come up with the right expression for theta then your program will behave like this. Here is a reference on all the different math functions you can use in Javascript.
As you can see in the link, the laser automatically points at the correct angle for the drone, the focus_distance is at the correct distance and the platform would be in the right place to catch the drone. The only thing for the user to do would be to press spacebar to fire the laser. This is a bit like real life because we don't really want the laser to fire automatically without a human to make the decision whether to fire or not.
As an optional step you can modify the code to make the game more fun! You can change the code however you like. Here are some suggestions:
Optional Step 8a. Change the speed of the drone
An easy thing to change is the initial velocity of the drone which is this part of the code:
vx = random(-10,10); vy = random(-20,-5);
If you change these numbers you can get the drone to go a bit faster, which is more fun!
Optional: Step 8b. Change the color of the laser
It is totally optional but if you want you can change the color of the laser by following a few steps
The first thing to do is to add a variable to the beginning of the program called lasercolor like this:
lasercolor = [0,255,0];
This specifies an rgb color for the laser. The code above means zero red, zero blue, maximum green.
Second thing to do is to change the drawLaser function to include an extra argument called lasercolor like this:
drawLaser(xlaserbase,ylaserbase,xfocus,yfocus,laseron,lasercolor);
You can add ,lasercolor as the extra argument or you can just replace drawLaser with the code above. After you do this you should be able to see the new color of the laser.
To pick out your own rgb color for the laser a helpful thing to do is to go to google and search on "color picker" Pick whatever color you want. Have fun!
Optional: Step 8c. Add a cool down time for the laser
Real lasers have to wait some period of time to cool down before they can fire again so the optics inside don't melt. Modify the code so that after you press spacebar the first time, you have to wait at least a few seconds before you can fire it again.