View this PageEdit this PageUploads to this PageVersions of this PageHomeRecent ChangesSearchHelp Guide

Erik's Second Project

The purpose of this project is to explore some of the more advanced topics of Squeak. We'll create the framework for a breakout style game that will use some advanced scripting techniques and siblings.

Procedure

Step 1) Create a playfield, a circle for the ball and two rectangles, one to be our default block and one to be our paddle.
Uploaded Image: erv2step1.png

Step 2) Let's start simple and describe the motion of the paddle inside our play field. Begin by embedding the paddle somewhere near the bottom of the playfield then opening up a script to describe it's motion. We're going to tie the motion of the paddle into the motion of the mouse along a horizontal axis. (Y value won't vary) Every playfield keeps the position of the mouse relative to the lower left hand corner. These values can be accessed in the playfield section of the playfield's viewer. The behaviour we'll give the paddle is that it'll be were ever the mouse is as long as it's within the playfield, so we'll set some boundries on each side, but otherwise let the paddle's x follow the mouse.

Uploaded Image: erv2step2.png

Step 3) Now we'll define the basic motion of the ball. Let's begin by giving the ball a speed variable, just in case somewhere down the way we want to work in something that changes it's speed. So setup the ball to move forward by it's speed and bounce, just in case it hits the edge of the playfield. Now let's describe the ball's behaviour when it runs into the paddle. Since a simple reflective bounce isn't interesting, let's write up an algorithm that makes the paddle act as if it were curved. The first thing we need to note, is that since the ball will be coming down to hit the paddle, it's heading will be either near positive 180 or near negative 180, so we'll need to handle those cases separately. We could do a simple reflective bounce just by subtracting the ball's current heading from 180, but we want to also add in the difference between the paddle's and ball's x value. This will cause the ball to bounce at a greater angle if it hits near the edge of the paddle. When you've written up the code, start the paddle and ball movement scripts and see how the ball behaves.

Uploaded Image: erv2step3.png

Step 4) In this step we'll setup some of the adminisitrative side of the game, starting, stopping, scoring, etc. To begin, let's add some variables to the playfield, a score and the number of balls remaining. We'll want to remove a life whenever the ball hit's the bottom of the map. We can have the ball test it's y value to determine this, if so, remove a life, if we've out of lives, stop the game, otherwise stop the ball and move it back to the starting position. We'll need to scripts to do that, one that stops all scripts and one that will move the ball to a starting location. Similarly we should have a script that sets the game up, and starts the game. The last thing we should do is create some things that tell the user what their score is and how many lives they have left. We should have an updatepoints script that gets run everytime a point is scored, and an updateballs script that gets run everytime the amount of balls changes.

Uploaded Image: erv2step4.png

Step 5) Now where's the fun in keeping score, if there is no way to score? Here we are going to define the block's behaviour and give some meaning to the game. Remember that block we created in the first step? We're going to be using that now. We're going to make our blocks take three hits before they disappear, so lets add a variable to the block to tell it how many hits are left, and create three more color variables that will represent the color of the block at each number of hits left. Now let's define what the block should do when it gets hit by the ball, since that's what we're primarily interested in. First we ought to test to see if we even overlap with the ball, if we do, then we know we've been hit, otherwise there's nothing to do. Then we should put in a test to see if the number of hits left is less than or equal to 1, if so, the block is "destroyed" (we'll tell it to hide for later reuse) and we'll add some points then update them. If it isn't less then or equal to 1 then we should reduce the number of hits the ball has left update it's color and perhaps add some points in.
Uploaded Image: erv2step5-1.png
Now let's create some siblings of this block, and drag those into the playfield. This way when the ball sees a block, we can have the base block tell all of it's siblings to run this script we just wrote and the one that overlaps the ball will act appropriately. Start the game and see how it works.
Uploaded Image: erv2step5-2.png
Now there are two problems with this. First of all as you might have noticed, the ball keeps going through the block rather than bouncing off of it. Since the ball could hit any one of four sides on the we'll need to test for all conditions and handle each one differently. Begin by creating three tests and nesting them in the no case. The first one will test if the ball is below the block, the second above, and the third if the ball is to the left or the right of the block. When trying to find formula to describe how the ball should bounce I find it helpful to draw out a picture and give some examples of how you want the ball to behave. From dealing with how the ball interacts with the paddle we should already know what to do in that case. So just copy that block of code into the yes case of the ball being above the block and remove the thing about the difference in x's. Similarly, after drawing out the diagram it appears that the ball bouncing off the bottom interacts exactly the same. So the same code can be used in that condition. The last thing is to determine the left side bounce and the right side bounce. We can see if the ball comes in at a 45 degree angle on the left side it should reflect at a -45 degree angle. This suggests we should have it's new heading be the negative of the old heading. It turns out that this is also the case for the right side of the block too.
Uploaded Image: erv2step5-3.png
Depending on the size of your ball and blocks, you might have to add in a small buffer area to the top and bottom of the block. This is to prevent the ball hitting on the sides from getting interpreted as the bottom or the top. The second problem is that once the block hides, how do we get it back when the game is over? We'll give our base block a script that sets the number of hits back to three, fixes it's color and tells it to show itself. In our reset script we'll have the block tell all the siblings to run this script we just wrote.
Uploaded Image: erv2step5-4.png

Congratulations, you're done!
See an example of the final version. ervbreakout.pr

Extensions

Here are some things that you could add to this project:
  • bonuses, have blocks random drop things when they go away that change an aspect of the game
  • multiple levels

Link to this Page