Tutorial: Coin Toss Using Actionscript 3
Total Page:16
File Type:pdf, Size:1020Kb
Tutorial: Bouncing Ball using ActionScript 3.0.
Open Flash and under Create New select Flash file (ActionScript 3.0).
This will open up the Flash development environment. It should look something like this:
Repeating what has been said in the other tutorials: Flash has many windows/panels, so you spend some time clicking on Window and selecting the ones you want at the moment. What the screen shot shows in the center is the Flash Stage. At the top, with the name Layer 1, the first (and only) frame is highlighted. This is the Timeline. On the right, below the panel with the rainbow, is the empty Library. On the left, is the Toolbox. You, the developer, will create symbols (movie clips, graphics and buttons) in the Library. Note: movie clips can consist of just one frame and no code or can be quite complex. You will bring instances of these to the Stage at particular frames. You also may draw directly on the Stage and create text fields (static, dynamic, or input) on the Stage. You will write code, ActionScript, in the frames.
With that general introduction, here is how you create a Flash application that shows a bouncing ball. This could be the start for a more elaborate game. The application starts with a ball in motion. A screen shot looks like this: The ball bounces off the walls: no walls actually exist. Instead, code determines that the ball is to change direction. The player can stop and (re-) start the ball. When this happens, the label on the button changes (toggles) between Stop and Start. The player also can adjust the speed by typing in a different amount. The requirements for this application are A way to produce animation, that is, to produce a sequence of pictures showing the ball in different positions Detection of the ball colliding with the walls Calculation of the new directions A way to allow the player to enter in a new speed A way to change the label on a button
I will describe each of these and then go through the implementation of this particular application.
It is possible in ActionScript 3.0 as in the earlier versions, to do animation by writing frame code in multiple frames. In my older bouncing ball and cannonball, I set up 3 frames: the first frame had the function definition and variable declarations. The second frame had free-standing code that moved the ball(s) and the third frame returned control to the second frame if the ball still was in flight. It also is possible to use the Enter_Frame event. Doing these approaches can be efficient in terms of the size of code and the performance of an application, because they use coding and structures already present. However, I decided to try something different for these new projects. ActionScript 3.0 has a new class called Timer. This means that you (your code) can create Timer objects. Timer objects can be used to set up timing events and handlers for those events. var mytimer:Timer = new Timer(50);
Note: when you type in any code using Timer, Flash will insert a statement importing definitions relating to that into your program.
The var statement sets up mytimer as a Timer object, with the timing event occurring every 50 milliseconds. This is pretty fast / often. It is possible to add a second parameter to the Timer constructor to indicate how many events you want to happen. For example, var timer2: Timer: new Timer(2000, 5); will set up timing intervals every 2 seconds (1000 milliseconds in a second) and do this 5 times. NOT having a second parameter means that the timing events will keep happening until the code stops them. Actually, the var statement does not start the timing. This will come later. The next statement to explain is the set up of the event handling: mytimer.addEventListener(TimerEvent.TIMER, moveball);
This statement "says": when the TimerEvent called TIMER happens, invoke the function moveball. This is similar to what is done for buttons (see the coin toss or rock paper scissors tutorials).
The next statement is needed to start the timing: mytimer.start();
To stop timing (assuming it has been set up in the var statement to last indefinitely), use mytime.stop();
So now I have explained how to invoke a function every so often. The main task of the event handler, designated as moveball in the code shown, will be to re-position the ball. This is done by modifying the horizontal (x) and the vertical (y) positions. Very briefly, in Flash, and many other computer applications, positions on the screen are indicated by 2 numbers (coordinates). The horizontal position is from the left and often designated as x and the vertical position is from the top and designated as y. This is NOT the standard analytical geometry you may remember.
In Flash, the horizontal position of movie clip instances is designated using dot notation: the name of the instance followed by a dot followed by x. Similarly, the vertical position of movie clip instances is designated by the name of the instance followed by a dot followed by a y. The code will re-position the ball by assigning values to ball.x and ball.y.
Before going into the specifics of ActionScript 3.0, please appreciate the fact that the animation is produced by generating snapshots in rapid succession. This is discrete simulation of motion. The ball is here and then it is there. It does not move smoothly from place to place. The collision detection is done at each interval of time. This means that the ball may appear to penetrate a wall because the collision calculation is done a quantum amount of time later. One way to see this is to experiment with the numbers. You can make the ball jump out of the box.
Flash provides a method to detect when a point, indicated by an x,y pair, designates a pixel that is occupied by material in a movie clip instance. The start of an if test shown next checks of the x and y values designating the registration point of the ball movie clip instance overlaps any occupied pixel of the movie clip instance named rightwall.
if (rightwall.hitTestPoint(ball.x,ball.y, true)) {
The true parameter specifies that the check is against actual material. If this parameter was false or omitted, the test would be against the bounding rectangle of rightwall. You can guess that the bounding rectangle test can be done quicker than the actual material test. It could be that you could develop a game in which you may be concerned with performance and may need to think about this.
The bouncing ball is re-positioned making use of variables that hold the x and y directions: xd and yd. The application contains 4 walls. Depending on which wall is hit, the values of xd and yd are set to 1 or -1. There are 4 cases and all will be shown later. The important thing to realize is that when the ball hits a particular wall, say the right wall (conveniently named rightwall), then the horizontal direction as held by the variable xd is changed to -1. The vertical direction is not changed. So if the ball was heading down the screen towards the right, xd was positive and yd was positive. After hitting the right wall, xd changes to negative and yd stays positive. The ball moves downward but now towards the left.
Flash has 3 types of text fields: fields set at creation time that do not change, fields changeable by code and fields that can be changed by the user/player. In Adobe CS5, the terminology, but not the functionality changed for text fields. The old terminology was static, dynamic and input. The new is read only, selectable and editable.
Static/Read Only fields are used to label parts of the screen. Once they are set during development time, they do not change. Dynamic/selectable text fields can be set at development time and also by code. They were used in the coin toss and in rock paper scissors. Input/editable text fields can be set at development time and by code AND by the player (user). These fields contain text, so the code must convert the text to number data type before using as the speed in bouncing ball. Flash provides the facility to use all the fonts available on the creating/development computer. It also provides the facility to store (embed) a font or portions of a font in the Flash published program to make sure it will run on the player's computer. You will need to follow directions and use help for more information on these features.
This explains the basic features of this application. Now to actually build it, do the following:
For this application, name the first layer board and add 2 more layers by clicking on the small icon below the timeline that looks like a tablet with the bottom left corner turned up. Name each layer by clicking on the name, making these board, actions and interface.
Layers are used to force graphics to be on top of other graphics and for organization. Here I use it for both. The interface layer will hold the button and the text box. The actions layer will hold just the code, no material. The board layer will hold the ball and the walls.
Select the board layer, 1st and only frame.
Insert/New Symbol (movie clip), name it ball and draw a circle. Make sure the registration point is at the center. Then drag an instance to the Stage, name the instance ball.
Insert/New Symbol (movie clip), name it wall and draw a horizontal rectangle. Now bring 4 instances of this symbol to the Stage. Use Modify/Transform/ Rotate 90 degrees CW and Rotate 90 degrees CCW on two of them to create the vertical (right and left) walls. Name each wall: rightwall, leftwall, topwall, and bottomwall as appropriate. If you get these wrong, the coding will do funny things!
Now select the interface layer, first and only frame. Use the T tool to create a text field. Specify it to be an Input text field and give it the instance name speed. Type in 10 as the initial value. Click on Window/Components, then double click on Button. This will place a Button along with other stuff in the Library and place a button on the Stage. The parameters panel probably is displayed. If not, click on the tab to display it. Change the Label to Stop. This is the initial setting of the label. The code will change it. Click to display the Properties panel and set the Instance name of the Button to be togglebtn.
To implement the button used to switch between stopping and starting I used one of what Flash provides under the classification Components. Click on Window/Components. [NOTE: this is different than using a button from the Common Library.]
Button components have labels and the label is what my code changes. I clicked on Window/Components/User Interface/Button and dragged the button to the Stage. I gave it a name: togglebtn using Properties, change the instance name. This particular Component has a built-in property called label. In CS5, this is set using the COMPONENT PARAMETERS panel within the Properties panel. Change the label OR use the code: togglebtn.label="Stop";
By the way, something that switches back and forth like this is called a toggle.
Notice that because the interface layer is above the board layer, these two things: the button and the text field are on top of the walls.
Select the right wall. The screen show shows what the Stage should look like now. Notice also that the wall in the Library is horizontal. With the Stage set, it is time to write the code! Click on the actions layer, 1st and only frame and use Window/Actions to open the Actions window. Note: you could do this at any time and you also do not have to put actions in a different layer. This use of layering is done just for organization. In more complex projects, it is recommended to use multiple layers for the coding, just to spread it out and make it easier to find things.
The code consists of 4 var statements, two function definitions and 3 standalone statements. The 4 var statements set up the mytimer, a variable that will hold the speed, and the variables for the directions: var mytimer:Timer = new Timer(50); var sp:Number = parseInt(speed.text); var xd:Number = 1; var yd:Number = 1;
The sp variable is initialized to be the value (converted from text to an integer) that you put in the Input text field. The xd and yd variables are each set to 1. This means that the ball will start off moving right and down. Experiment by changing these values and see what happens.
The moveball function will be what happens at each time interval as indicated previously. I just choose to show the definition of the function first. Following the practice in ActionScript 3.0, the function header contains the definition of a parameter named ev of type TimerEvent. It will not be referenced in this function. The void indicates that this function does not return a value.
The += operator takes the current value of the variable on the left and adds to it the result of the expression on the right. In this case, the value of ball.x changes to whatever ball.x + xd*sp is. This effectively moves the ball. The next set of statements are 4 if statements checking for collisions between the ball and each of the walls. As I indicated earlier, if any particular collision occurs, this means a re-setting of either xd or yd. Now you may wonder why I don't try to save computation by not checking on the right wall if the left wall has been hit. The answer is that that would make the coding more complex than it needs to be. If it turns out that there was a performance problem, I would re-consider. function moveball(ev:TimerEvent):void { ball.x += xd*sp; ball.y += yd*sp; if (rightwall.hitTestPoint(ball.x,ball.y, true)) { xd=-1; } if (leftwall.hitTestPoint(ball.x,ball.y, true)) { xd=1; } if (topwall.hitTestPoint(ball.x,ball.y, true)) { yd=1; } if (bottomwall.hitTestPoint(ball.x,ball.y, true)) { yd=-1; } }
The stopstart function is what will be invoked when the button is clicked. This is similar to the coin toss or rock paper scissors applications. In this application, the code uses the running property of mytimer to see if timing is going on. This essentially checks if the ball is in motion. In this case, the code stops the timing and changes the label of the button. If it is not the case that timing is going on, the code changes the directions, picks up the speed (converts to a number) and sets the internal sp variable, starts timing and changes the label. function stopstart(ev:MouseEvent):void { if (mytimer.running) { mytimer.stop(); togglebtn.label = "Start"; } else { xd=-xd; yd=-yd; sp = parseInt(speed.text); mytimer.start(); togglebtn.label="Stop"; } }
The last part of the coding is 3 statements not inside any function. The first two statements could be separated and could be anywhere. The first two shown below set up the event handling. The third starts the timing, which, in turn, starts the ball. It needs to be after the mytimer.addEventListener statement. mytimer.addEventListener(TimerEvent.TIMER, moveball); togglebtn.addEventListener(MouseEvent.CLICK, stopstart); mytimer.start();
After entering in this code (into the actions layer), you can test the program: Control/Test Movie. Experiment by changing the amount of time interval, the directions, and so on.
To produce a finished version of the program suitable for uploading to the Web, Click on File / Publish. This produces two files: an .html and a .swf . You need to upload both of these files along with a file named AC_RunActiveContent.js to the file folder, if that is not already present. This file is created by the Flash environment and will be in the folder with the other files. When setting up a link to your game, make the href be to the .html file.
ActionScript 2.0 to ActionScript 3.0 to CS5
Only read this if you are familiar with previous versions of Flash and want to reflect on the differences.
First of all, consider that much is the same: you still bring material to the Stage; give things names; write a function that performs calculations and tests; and set up a connection between an event involving the button and the function.
I could have implemented the timing part of bouncing ball using frames. Instead, I made use of the new Timer class.
The Input text field needed to have an instance name. Notice that avoiding multiple frames made this easier than the ActionScript implementation because the fields did not need to be reset in each frame.
In CS5, text fields are created using TLF designations or Classic Text designations.
The Component properties can be modified in the Properties panel. You don’t need to use the Components inspector.