Thursday, June 21, 2012

Alice Game Daily Project Instructions



*********************************************************************************
BEGIN GAME
*********************************************************************************
Day 5 (Tuesday): (1.5 hours)
events, collision detection

We’ll be building a game that’s pretty much a penguin playing racquetball.

Events:
Open Alice and click on whichever template you want, then go to Add Objects     

Local gallery → Animals → penguin
Local gallery → Sports → tennisRacket
Local gallery → Shapes → sphere
Local gallery → Shapes → square
Local gallery → Buildings → Factory

Drag the sphere, tennisRacket, factory, and square away from the penguin, we’ll work with him first.
Shrink down the factory until you can’t see it.

Click ‘DONE’ button



Penguin arrangement:
Right click penguin to situate stuff:

  • Penguin-->orient to-->camera
  • Penguin-->turn left-->.5 revolutions
  • Penguin-->rightWing-->roll left--> 1/4 revolutions
  • Penguin-->rightWing-->turn right--> .3 revolutions

tennisRacket arrangement:

  • TennisRacket-->orient to-->camera
  • TennisRacket-->move to-->Penguin-->rightWing
  • TennisRacket-->move left-->.6 meters
  • TennisRacket-->roll left-->1/4 revolution
  • TennisRacket-->set vehicle to-->Penguin-->rightWing

Now the racket will follow everything we tell the rightWing to do.

**********************************************

Penguin:

Click on the penguin in the object tree, then in “penguin’s details” click on the methods tab.
Create a new method called swingRight.

swingRight method:
  • Expand the view of the penguin in the object tree and select the rightWing
  • In the rightWing’s methods tab, drag rightWing-->roll into the swingRight method and set it to roll right--> ¼ revolutions. Because the right wing is oriented weirdly now, it just took trial-and-error to figure out which way to turn/roll it.
  • right-click that instruction and make a copy, then change the copy to ‘roll left’

Make a call to penguin.swingRight in world.my first method to make sure that it is the motion we want. Play your world.

The swing is a bit slow, so set the duration of each of those to .5 seconds.

swingRight event:
Now we’re going to make an event! It’s not useful to have the penguin swing once at the beginning of running the program, we want to be able to swing at a ball. In the top right portion of Alice, you’ll see the Events screen. We want to:
  • create new event-->when a key is typed
  • set the ‘any key’ to F, and the ‘do’ to penguin.swingRight
  • Go back to world.my first method and delete the call to penguin.swingRight.
  • Play your world, hit the F key, and see what happens

****************
Really quick, right-click the penguin and have him turn left ½ revolution so that he’ll face where the wall will be later.
****************

Go to the penguin methods tab and create a new method, swingLeft.

swingLeft Method/Event:
  • First we need to turn the penguin around and get the wing situated to swing backwards. Put a Do together in the method
  • Inside it drop a penguin-->turn right--> ½ revolution, duration .5 seconds
  • Expand the penguin in the object tree and click on the right wing, then the methods tab
  • In the Do together drop a rightWing-->turn left-->.1 revolutions, duration .5 seconds
  • After the Do together, drop a rightWing-->roll left .25 revolutions, duration .5 seconds, then copy it and change it to roll right. This is the same motion we had in the swingRight.
  • Now make a copy of the Do together at the top and stick it at the bottom, then switch the penguin.turn right to a turn left and the rightWing.turn left to a turn right. This resets the penguin.

  • Create a new event that says when A is typed, do Penguin.swingLeft
  • Play the project so far and see what happens with the swingLeft method. Does it behave how we want it to?

It works good, but the penguin just kinda stares at us while he swings backwards, so we should turn his head so it looks like he is watching the ball.
  • Expand the penguin in the object tree again and click on the head, then methods tab
  • Inside the first do together put head-->turn right-->.3 revolutions, duration .5 seconds
  • Copy it and stick it in the last do together, but turn left instead.

Try it again!

Now movement! Create new methods for the penguin called moveLeft and moveRight.

moveLeft:
  • do together
  • penguin-->move left--> .25 meters, duration = .25 seconds, style = abruptly
  • penguin-->move up--> .1 meters, duration = .25 seconds, style = abruptly
  • then copy the do together and change the move up to a move down
  • create yet another event that says when the ←(left arrow) is typed, do penguin.moveLeft

Play the world, see if you can move the penguin left.

moveRight:
  • put a do together from moveLeft onto the clipboard, then stick it in moveRight
  • change the move right to a move left
  • make a copy of that do together and stick it underneath, then change the move up to a move down.
  • create yet another event that says when the -->  (right arrow) is typed, do penguin.moveRight

Play the world to make sure you have left/right movement and racket swinging

************************************************
START HERE: June 21, 2012
************************************************

Ball:
Now we need to actually hit the ball.
  • Go to add objects and right click the ball-->move to-->tennisRacket, then select the re-size objects, and shrink the ball down to a decent size
  • right-click sphere-->orient to-->camera
  • In the sphere properties, you can change the color if you want

Now we’ll do a simple example of collision detection: when the tennisRacket hits the sphere, we want to sphere to move forward.

Click the sphere in the object tree, then methods tab, then create new methods: “moveForward”, “moveBackward”, “hit”, and “bounce”.

hit Method: (This is for when the ball hits the racket)
  • First thing is an if/else, drag it into the method, and click true for the default setting
  • put a print statement in the if part that will print “Hit Method” so we know when we’re in it
  • Booleans variables are useful here, one for if we hit the racket last and one for if we hit the wall last. They both can’t be true at once. So in sphere--> properties make two boolean variables, hitRacket and hitWall, and set them both to false in the tab
  • In the if, set hitRacket-->true and hitWall-->false (they’ll be useful in moveForward and moveBackward)
  • If we “hit” the racket, we want the sphere to move a certain distance away from the racket, so do sphere-->move forward--> 5 meters
  • Also make a call to the moveForward method we created, we’ll need it later.
  • Create an event so that when the world starts, do sphere.hit
  • Play the project so far
  • The last thing is that we need the if part to happen based on how close the sphere is to the racket. So now we’ll do sphere-->FUNCTIONS. So looking at this list, which of the functions do we want to use to tell if the racket has “hit” the ball?
  • sphere is within “threshold” of object-->1 meter-->tennisRacket
  • Play again, the ball should still move forward!
  • We can hit the ball once at the beginning, but that event only happens when the world starts, so in order to keep checking if we’ve hit the ball, we’ll need to loop the ‘hit’ method continuously, so drag a loop into the method, click infinity times, and drop your if/else statement inside of it.

moveForward Method:
  • first do a print “moveForward Method” so that we know when the program is in it
  • in sphere-->properties, create a new number variable called angle
  • drag angle into moveForward and set the value to something.
  • In the world functions tab, find the random number function and put it as the value for angle, with a minimum of -.05 and a max of .05
  • we want to keep moving forward little bits as long as the last thing we hit was the racket. Once we hit the wall, that will change. So a while loop, then expressions-->hitRacket, then hitRacket-->logic--> ==--> true. So while (hitRacket == true), move forward.
  • Stick a do together in the while loop
  • sphere-->methods tab-->move forward-->.25 meters, duration .05 seconds, style abruptly
  • sphere-->methods tab-->move left-->angle meters, duration .05 seconds, style abruptly. Since -.05 < angle < .05, it can move right .05 meters or -.05 meters, but moving right negative meters just means move left, so it could go left or right after hitting the racket. We assign angle before the while loop so that it won’t keep changing while we should be moving in a line.

Before playing it, go back to hit and delete the move forward-->5 meters
Play the thing and see how it works so far!

This is how collision detection works! Once an object is within a certain distance of another object, we count them as having “hit” each other, so we need to either stop the moving object or have it move in another direction.

***********************************************************
Square:
Right-click the square and orient it to the camera, then move it to the entire penguin. Move the square forward 5 meters
Go to Add Objects and re-size the square to cover the sky.
Remember the factory object we dropped in earlier and shrunk down? Go to the square properties and set the texture to the factory.

The reason we did a square with a texture of factory instead of using the actual factory is that distance is measured from the very center of an object. Since the square is 2D, the distance from the ball to the square is pretty much what it looks like, so it’s easy to figure out when we should bounce the ball back. If we used the factory, it would be a huge distance and it would be hard to figure out what the threshold should be for our function.
************************************************************

bounce Method: (This is for when the ball bounces off the wall)

  • Go into the sphere’s hit method and drag the whole loop onto the clipboard, then go to the bounce method and drag the clipboard item into it.
  • We’ll use the same kind of logic, but with a couple changes. change the print to say “Bounce Method”
  • change hitWall-->true, since the wall will have just been hit, and hitRacket-->false
  • We’ll also want to do our sphere.moveBackward method, which is the opposite of the moveForward one we just made, so call moveBackward
  • The last thing is that our condition is different now. We can’t do “sphere within a certain distance of the square” because distance is measured from the center of the square, and that will change depending on where we hit on the wall (draw on board to demonstrate). But we basically need to make sure that the ball will stay on this side of the square-wall.
  • In sphere-->functions, go down to the spacial relation group and grab the function sphere is in front of, and drop that in the if condition, and set the object to sphere is in front of square. Because of the orientation weirdness, “in front” for us means the ball is behind the wall.
  • Create an event so that when the world starts, do sphere.bounce

moveBackward Method:
  • drag in a print statement that says “MoveBackward Method”
  • In moveForward, drag the angle set value onto the clipboard and stick it in moveBackward
  • In moveForward, drag the while loop onto the clipboard and stick it in moveBackward. Change the condition to hitWall == true
  • Change the sphere-->move forward to a sphere-->move backward

Try playing it, see if it all works together!

Now the problem is that if we miss the ball, it will fly backwards forever, because it never hits the racket where it is told to turn around. So we need a miss method! Go to the sphere methods tab and create a new method called “miss”

miss Method:
  • First we’ll need an if statement to determine if we’ve missed or not. So if, initially set to true. The best way to trip this is to set it to ‘if sphere is within _____ of camera’. So that’s a sphere function, set the threshold to 7 meters for now. We can change it individually if it’s not tripping it.
  • Inside the if, print “Miss Method”
  • set hitRacket-->false and hitWall-->false
  • Now we’ll do a scoring thing.
  • Go to add objects and the last thing is create 3D text. Make it say 3.0, then ok. You’ll want to move it up towards the top of your visible world. Rename it in the object tree as livesLabel
  • We’ll make one more variable, in the world properties, called lives, a number variable. Start it as 3.
  • Drag the lives variable into the miss method and select ‘decrement by 1’
  • click livesLabel in the object tree and go to the properties. drag the text property into miss and set it to the default string.
  • In world functions, drag the ‘what as a string’ into the default string area, and set the what to lives, duration 0 seconds
  • Now if we have 0 lives left, we want to stop the game, so drag an if just under the ‘set text to’ and set it to true. Drag the lives variable into the true slot and set it == 0.
  • Inside this new if, do livesLabel-->properties-->set text to-->Loser!
  • Then put in a loop and set it to infinity times. This will keep the game right here forever.
  • If Alice gets past this if statement, that means we still have lives left, so we need to get our ball back. Go to sphere-->move to-->tennisRacket, duration 0 seconds, and stick it after the entire if for lives == 0
  • Now this method is treated the same way as our hit and bounce methods, we always need to be checking for it, so stick the entire thing in an infinity times loop and create a new event that says when the world starts, do sphere.miss

No comments:

Post a Comment