Showing posts with label as3. Show all posts
Showing posts with label as3. Show all posts
Monday, February 2, 2015
AS3 Sound
Exercise Files:
Sound.fla
CheerfulSong.mp3
In this lesson, were going to learn how to control sound in Flash using ActionScript 3. Were going to learn:
Exercise files accompany this article - we have a Flash document named Sound.fla and an mp3 document named CheerfulSong.mp3. Please make sure to save them both inside the same folder. In the first part of this tutorial, well learn how to load CheerfulSong.mp3 into our Flash movie using ActionScript. Instead of importing CheerfulSong.mp3 into Sound.flas library, both files will remain separate from each other, but we will use ActionScript so that we will be able to play the sound from within the Flash movie.
Lets begin.
Loading and Controlling an External Sound File
How do you control sound using ActionScript 3?
To control sound in your Flash movie using code, create a Sound object using the the AS3 Sound class to control the sound .
A Sound object can be used to do the ff:
STEP 1
Open the Sound.fla file. Youll see that there are two buttons on the stage - play_btn and stop_btn. But lets ignore those buttons for now. First, lets write some code that will load and play the sound right away. Select frame 1 of the Actions layer, then go to the Actions Panel and type in the following lines:
The second line (var myURL:URLRequest = new URLRequest("CheerfulSong.mp3");) creates a URLRequest object. This is used to specify the path to the external file that we want to load.
STEP 2
So now that weve created those two objects, we can now load the external sound file. Use the load() method of the Sound class and pass to it the URLRequest object:
So in our example, we would write:
This instructs our mySound object to load the file specified in myURL (which is CheerfulSong.mp3). So go back to the code and add the following line highlighted in bold:
STEP 3
If you test the movie at this point, you wont hear the sound just yet. Thats because we just told Flash to load the sound. We havent given the instruction to start playing the sound yet. To make the sound start playing, we use the play() method of the Sound class:
The play() method of the Sound class has 2 optional parameters:
The first value refers to the startTime parameter. Here, weve specified a value of 25000 milliseconds (or 25 seconds). This means that when the sound begins playing, it will start playing at the sounds 25-second mark, instead of starting at the beginning. So it will skip the first 24 seconds of the song when the playback starts.
The second value refers to the loops parameter. Weve specified a value of 2. This means that the sound will play 2 times. When it plays the first time and then reaches the end, it will loop back to the startTime and play one more time.
Test the movie in order to verify, and then change the play statement back to mySound.play(); (without any parameters), and lets continue.
STEP 4
If we want the sound to play only after the play button (named play_btn) has been clicked, then well have to create a mouse click event listener for the play button, and well transfer the play sound statement inside that event listener:
STEP 5
So now that we can play the sound, how do we stop it?
You can NOT stop the sound using the Sound class (e.g. Sound.stop() will not work). Another class is used for that - the SoundChannel class - which has a stop() method that will let you stop a sounds playback.
Lets go ahead and create an instance of the SoundChannel class. Im going to name it mySoundChannel.
STEP 6
Think of the SoundChannel as the object that houses or contains your sound. In order to place a sound inside a SoundChannel, you assign the play sound statement to a SoundChannel like so:
So in our example, we would write:
This assigns mySound.play() to mySoundChannel, so that the sound is going to play inside mySoundChannel. Lets go ahead and assign mySound.play() to mySoundChannel in our code:
STEP 7
So weve now assigned our sound to a channel. In order to stop the sound, then well have to stop the SoundChannel that contains the sound. We will use the stop() method of the SoundChannel class like so:
This will stop whatever sound that is playing inside the mySoundChannel object.
Lets put this stop statement inside a mouse click event handler for the stop button (stop_btn) so that our sound will stop playing when the user clicks on the stop button:
And that concludes the first part of this tutorial. But dont close your Sound.fla document just yet. In the next part, well learn how to write some code that will enable Flash to detect when the sound has reached the end. This is useful if you want your Flash movie to do something once a sound clip has completed playback.
Detecting when a Sound has Reached the End
In some cases, you might want to enable Flash to detect when a sound clip has reached the end. Lets say, for example, you have a song thats playing in the background, and youd like Flash to display an image or a message only when the song has completed playing. To be able to detect when a sound file has reached the end, you can use the Event.SOUND_COMPLETE event of the SoundChannel class. This event gets dispatched once a sound file completes playback.
STEP 1
Lets go ahead and add an Event.SOUND_COMPLETE listener to our code. Im first going to create the event listener function, which I will name endOfSound.
STEP 2
Now that we have this event listener function, we then need to add the event listener to our SoundChannel object. When youre adding an Event.SOUND_COMPLETE listener, the event listener must only be added AFTER the line where the play sound statement has been assigned to the SoundChannel (i.e. after the SoundChannel = Sound.play() statement). In our example, this line would be:
And in our code, this line can be found inside the playSound event listener function. So we must add the event listener for Event.SOUND_COMPLETE right AFTER that line:
Lastly, lets learn how to stop playing multiple sound clips all at once.
Stopping All Sounds at Once
In our example, were only playing one sound file. But what if you have multiple sound clips playing all at the same time and youd like to stop all of them at once? You can do that by using the stopAll() method of the SoundMixer class. In the example below, we have some code that stops all the sound clips that are currently playing, when a button is clicked:
And those are the basics of how you can use the AS3 Sound class and the AS3 SoundChannel class in order to work with sound in Flash. And with that, this tutorial is now concluded.
Read more »
Sound.fla
CheerfulSong.mp3
In this lesson, were going to learn how to control sound in Flash using ActionScript 3. Were going to learn:
- how to load an external sound file into a Flash movie
- how to play and stop the sound
- how to detect when the sound clip has reached the end
Exercise files accompany this article - we have a Flash document named Sound.fla and an mp3 document named CheerfulSong.mp3. Please make sure to save them both inside the same folder. In the first part of this tutorial, well learn how to load CheerfulSong.mp3 into our Flash movie using ActionScript. Instead of importing CheerfulSong.mp3 into Sound.flas library, both files will remain separate from each other, but we will use ActionScript so that we will be able to play the sound from within the Flash movie.
Lets begin.
Loading and Controlling an External Sound File
How do you control sound using ActionScript 3?
To control sound in your Flash movie using code, create a Sound object using the the AS3 Sound class to control the sound .
A Sound object can be used to do the ff:
- load an external sound file into a Flash movie
- start the playback of that loaded sound file
NOTE: You can NOT use a Sound object to stop playing sound. The Sound class does not have a method for that. If you want to stop a sound clips playback, youll have to use a different class - the AS3 SoundChannel class - which we will talk about later.
STEP 1
Open the Sound.fla file. Youll see that there are two buttons on the stage - play_btn and stop_btn. But lets ignore those buttons for now. First, lets write some code that will load and play the sound right away. Select frame 1 of the Actions layer, then go to the Actions Panel and type in the following lines:
var mySound:Sound = new Sound();
var myURL:URLRequest = new URLRequest("CheerfulSong.mp3");The first line (var mySound:Sound = new Sound();) creates an instance of the Sound class. Ive named it mySound. We will use this to load and play the external sound file named CheerfulSong.mp3.The second line (var myURL:URLRequest = new URLRequest("CheerfulSong.mp3");) creates a URLRequest object. This is used to specify the path to the external file that we want to load.
STEP 2
So now that weve created those two objects, we can now load the external sound file. Use the load() method of the Sound class and pass to it the URLRequest object:
Sound.load(URLRequest);
So in our example, we would write:
mySound.load(myURL);
This instructs our mySound object to load the file specified in myURL (which is CheerfulSong.mp3). So go back to the code and add the following line highlighted in bold:
var mySound:Sound = new Sound();
var myURL:URLRequest = new URLRequest("CheerfulSong.mp3");
mySound.load(myURL);NOTE: When using the load() method of the Sound class, the external sound file must be in the mp3 format. And if you want to load more than one sound file, then create another Sound object for each succeeding sound file that youd like to load, even if youre reloading the same sound file.
STEP 3
If you test the movie at this point, you wont hear the sound just yet. Thats because we just told Flash to load the sound. We havent given the instruction to start playing the sound yet. To make the sound start playing, we use the play() method of the Sound class:
var mySound:Sound = new Sound();
var myURL:URLRequest = new URLRequest("CheerfulSong.mp3");
mySound.load(myURL);
mySound.play();So if you test the movie now, you should hear the sound playing.The play() method of the Sound class has 2 optional parameters:
- startTime - this lets you specify the point (in milliseconds) where the sound playback should start
- loops - this lets you specify how many times the sound should repeat playback
mySound.play(25000, 2);
The first value refers to the startTime parameter. Here, weve specified a value of 25000 milliseconds (or 25 seconds). This means that when the sound begins playing, it will start playing at the sounds 25-second mark, instead of starting at the beginning. So it will skip the first 24 seconds of the song when the playback starts.
The second value refers to the loops parameter. Weve specified a value of 2. This means that the sound will play 2 times. When it plays the first time and then reaches the end, it will loop back to the startTime and play one more time.
Test the movie in order to verify, and then change the play statement back to mySound.play(); (without any parameters), and lets continue.
STEP 4
If we want the sound to play only after the play button (named play_btn) has been clicked, then well have to create a mouse click event listener for the play button, and well transfer the play sound statement inside that event listener:
var mySound:Sound = new Sound();
var myURL:URLRequest = new URLRequest("CheerfulSong.mp3");
mySound.load(myURL);
// Make sure that you remove the play sound statement
// that was here, and transfer it into the mouse click
// event listener function
play_btn.addEventListener(MouseEvent.CLICK, playSound);
function playSound(e:MouseEvent):void
{
mySound.play();
}Here, weve created a mouse click event listener function named playSound, and weve transferred the mySound.play() statement into that event listener function. So now, when we test the movie, the sound is only going to play when the play button is clicked.STEP 5
So now that we can play the sound, how do we stop it?
You can NOT stop the sound using the Sound class (e.g. Sound.stop() will not work). Another class is used for that - the SoundChannel class - which has a stop() method that will let you stop a sounds playback.
Lets go ahead and create an instance of the SoundChannel class. Im going to name it mySoundChannel.
var mySound:Sound = new Sound();
var myURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var mySoundChannel:SoundChannel = new SoundChannel();
mySound.load(myURL);We now have a SoundChannel object named mySoundChannel.STEP 6
Think of the SoundChannel as the object that houses or contains your sound. In order to place a sound inside a SoundChannel, you assign the play sound statement to a SoundChannel like so:
SoundChannel = Sound.play();
So in our example, we would write:
mySoundChannel = mySound.play();
This assigns mySound.play() to mySoundChannel, so that the sound is going to play inside mySoundChannel. Lets go ahead and assign mySound.play() to mySoundChannel in our code:
var mySound:Sound = new Sound();
var myURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var mySoundChannel:SoundChannel = new SoundChannel();
mySound.load(myURL);
play_btn.addEventListener(MouseEvent.CLICK, playSound);
function playSound(e:MouseEvent):void
{
mySoundChannel = mySound.play();
}STEP 7
So weve now assigned our sound to a channel. In order to stop the sound, then well have to stop the SoundChannel that contains the sound. We will use the stop() method of the SoundChannel class like so:
mySoundChannel.stop();
This will stop whatever sound that is playing inside the mySoundChannel object.
Lets put this stop statement inside a mouse click event handler for the stop button (stop_btn) so that our sound will stop playing when the user clicks on the stop button:
play_btn.addEventListener(MouseEvent.CLICK, playSound);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound);
function playSound(e:MouseEvent):void
{
mySoundChannel = mySound.play();
}
function stopSound(e:MouseEvent):void
{
mySoundChannel.stop();
}Here, weve created a mouse click event listener function named stopSound() for the stop button. This event listener function contains the mySoundChannel.stop(); statement. So now, the user can click on the stop button in order to stop the sounds playback.NOTE: If you want to be able to play multiple sounds simultaneously and still be able to individually stop each sound, then you will need to create one SoundChannel for each sound.
And that concludes the first part of this tutorial. But dont close your Sound.fla document just yet. In the next part, well learn how to write some code that will enable Flash to detect when the sound has reached the end. This is useful if you want your Flash movie to do something once a sound clip has completed playback.
Detecting when a Sound has Reached the End
In some cases, you might want to enable Flash to detect when a sound clip has reached the end. Lets say, for example, you have a song thats playing in the background, and youd like Flash to display an image or a message only when the song has completed playing. To be able to detect when a sound file has reached the end, you can use the Event.SOUND_COMPLETE event of the SoundChannel class. This event gets dispatched once a sound file completes playback.
STEP 1
Lets go ahead and add an Event.SOUND_COMPLETE listener to our code. Im first going to create the event listener function, which I will name endOfSound.
function playSound(e:MouseEvent):void
{
mySoundChannel = mySound.play();
}
function stopSound(e:MouseEvent):void
{
mySoundChannel.stop();
}
function endOfSound(e:Event):void
{
trace("Sound playback is complete.")
}Here, we have an event listener function named endOfSound. When this function gets called, its going to trace a message to the Output window.STEP 2
Now that we have this event listener function, we then need to add the event listener to our SoundChannel object. When youre adding an Event.SOUND_COMPLETE listener, the event listener must only be added AFTER the line where the play sound statement has been assigned to the SoundChannel (i.e. after the SoundChannel = Sound.play() statement). In our example, this line would be:
mySoundChannel = mySound.play();
And in our code, this line can be found inside the playSound event listener function. So we must add the event listener for Event.SOUND_COMPLETE right AFTER that line:
function playSound(e:MouseEvent):void
{
mySoundChannel = mySound.play();
mySoundChannel.addEventListener(Event.SOUND_COMPLETE, endOfSound);
}
function stopSound(e:MouseEvent):void
{
mySoundChannel.stop();
}
function endOfSound(e:Event):void
{
trace("Sound playback is complete.")
}Now that the event listener has been added, Flash can now detect when the sound has reached the end. If you test the movie now and play the song, the trace statement will output the message once the song reaches the end. So whatever other instructions youd like to tell Flash to do once the song has reached the end (e.g. play another song, stop the animation, go to the next frame, display an image) should be placed inside the Event.SOUND_COMPLETE event listener function.Lastly, lets learn how to stop playing multiple sound clips all at once.
Stopping All Sounds at Once
In our example, were only playing one sound file. But what if you have multiple sound clips playing all at the same time and youd like to stop all of them at once? You can do that by using the stopAll() method of the SoundMixer class. In the example below, we have some code that stops all the sound clips that are currently playing, when a button is clicked:
// Assume that stopAll_btn is a button
// that already exists on the stage
stopAll_btn.addEventListener(MouseEvent.CLICK, beQuiet);
function beQuiet(e:MouseEvent):void
{
SoundMixer.stopAll();
}Here, weve created a mouse click event handler that will enable the user to stop all sound clips that are currently playing by clicking on the button.And those are the basics of how you can use the AS3 Sound class and the AS3 SoundChannel class in order to work with sound in Flash. And with that, this tutorial is now concluded.
Saturday, January 31, 2015
Creating a Pentomino game using AS3 Part 15
In this tutorial well add the ability to set canvas size in the level editor.
Go to your Flash project and create a new MovieClip based on win_screen. Give the new MC a class path of new_edit_screen. Inside of it we need to include 4 objects at least - two text field inputs tWidth and tHeight (max chars - 2), a button btn_continue and an error message turned into a movie clip with id "incorrect".
Delete it from stage and just keep it in the library. Now return to pentomino_editor.as script file. Inside the constructor, delete all the lines that declare and create the map. Add a listener for btn_reset button and set its click event handler to a function that calls newLevel(). Call newLevel() from the constructor too.
Now create the newLevel() function.
First thing we do here is add an instance of new_edit_screen to the stage.
Add lines that only allow numeric values in tWidth and tHeight, also set their default values:
Set incorrects alpha to 0 (since there was no error yet):
Add a click event listener to btn_continue, set its handler to an internal function editContinue:
Create the editContinue() function inside newLevel(). First thing we do is check if the specified width and height is correct:
If it is correct, we delete the newScreen object from stage, set mapGrid to an empty array and declare width and height variables:
Add two loops that add values to mapGrid based on width and height:
Then calculate grid values and draw the grid:
Full newLevel() function:
Full code so far:
Thanks for reading!
Results:
Read more »
Go to your Flash project and create a new MovieClip based on win_screen. Give the new MC a class path of new_edit_screen. Inside of it we need to include 4 objects at least - two text field inputs tWidth and tHeight (max chars - 2), a button btn_continue and an error message turned into a movie clip with id "incorrect".
Delete it from stage and just keep it in the library. Now return to pentomino_editor.as script file. Inside the constructor, delete all the lines that declare and create the map. Add a listener for btn_reset button and set its click event handler to a function that calls newLevel(). Call newLevel() from the constructor too.
public function pentomino_editor()
{
// add shape buttons
for (var i:int = 0; i < 4; i++) {
for (var u:int = 0; u < 3; u++) {
var shapeButton:MovieClip = new edit_shape();
shapeButton.x = 528 + u * 62;
shapeButton.y = 15 + i * 84;
addChild(shapeButton);
shapeButton.bg.alpha = 0.3;
shapeButton.shape.gotoAndStop(3 * i + u + 1);
shapeButtons.push(shapeButton);
shapeButton.addEventListener(MouseEvent.ROLL_OVER, buttonOver);
shapeButton.addEventListener(MouseEvent.ROLL_OUT, buttonOut);
}
}
// buttons
btn_mainmenu.addEventListener(MouseEvent.CLICK, doMainmenu);
btn_reset.addEventListener(MouseEvent.CLICK, function():void{newLevel()});
// new level
newLevel();
}
Now create the newLevel() function.
First thing we do here is add an instance of new_edit_screen to the stage.
var newScreen:MovieClip = new new_edit_screen();
addChild(newScreen);
Add lines that only allow numeric values in tWidth and tHeight, also set their default values:
newScreen.tWidth.restrict = "0-9";
newScreen.tHeight.restrict = "0-9";
newScreen.tWidth.text = 10;
newScreen.tHeight.text = 6;
Set incorrects alpha to 0 (since there was no error yet):
newScreen.incorrect.alpha = 0;
Add a click event listener to btn_continue, set its handler to an internal function editContinue:
newScreen.btn_continue.addEventListener(MouseEvent.CLICK, editContinue);
Create the editContinue() function inside newLevel(). First thing we do is check if the specified width and height is correct:
if (newScreen.tWidth.text == "" || newScreen.tHeight.text == "" || newScreen.tWidth.text == "0" || newScreen.tHeight.text == "0") {
newScreen.incorrect.alpha = 1;
return;
}
If it is correct, we delete the newScreen object from stage, set mapGrid to an empty array and declare width and height variables:
newScreen.parent.removeChild(newScreen);
mapGrid = [];
var width:int = newScreen.tWidth.text;
var height:int = newScreen.tHeight.text;
Add two loops that add values to mapGrid based on width and height:
for (var i:int = 0; i < height; i++) {
mapGrid[i] = [];
for (var u:int = 0; u < width; u++) {
mapGrid[i][u] = 1;
}
}
Then calculate grid values and draw the grid:
// grid settings
calculateGrid();
addChild(gridShape);
gridShape.x = gridStartX;
gridShape.y = gridStartY;
// draw tiles
drawGrid();
Full newLevel() function:
private function newLevel():void {
var newScreen:MovieClip = new new_edit_screen();
addChild(newScreen);
newScreen.tWidth.restrict = "0-9";
newScreen.tHeight.restrict = "0-9";
newScreen.tWidth.text = 10;
newScreen.tHeight.text = 6;
newScreen.incorrect.alpha = 0;
newScreen.btn_continue.addEventListener(MouseEvent.CLICK, editContinue);
function editContinue(evt:MouseEvent):void {
if (newScreen.tWidth.text == "" || newScreen.tHeight.text == "" || newScreen.tWidth.text == "0" || newScreen.tHeight.text == "0") {
newScreen.incorrect.alpha = 1;
return;
}
newScreen.parent.removeChild(newScreen);
mapGrid = [];
var width:int = newScreen.tWidth.text;
var height:int = newScreen.tHeight.text;
for (var i:int = 0; i < height; i++) {
mapGrid[i] = [];
for (var u:int = 0; u < width; u++) {
mapGrid[i][u] = 1;
}
}
// grid settings
calculateGrid();
addChild(gridShape);
gridShape.x = gridStartX;
gridShape.y = gridStartY;
// draw tiles
drawGrid();
}
}
Full code so far:
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.sampler.NewObjectSample;
import flash.utils.ByteArray;
/**
* Open-source pentomino game engine
* @author Kirill Poletaev
*/
public class pentomino_editor extends MovieClip
{
private var mapGrid:Array = [];
private var shapeButtons:Array = [];
private var gridShape:Sprite = new Sprite();
private var canPutShape:Sprite = new Sprite();
private var gridStartX:int;
private var gridStartY:int;
private var gridCellWidth:int;
public function pentomino_editor()
{
// add shape buttons
for (var i:int = 0; i < 4; i++) {
for (var u:int = 0; u < 3; u++) {
var shapeButton:MovieClip = new edit_shape();
shapeButton.x = 528 + u * 62;
shapeButton.y = 15 + i * 84;
addChild(shapeButton);
shapeButton.bg.alpha = 0.3;
shapeButton.shape.gotoAndStop(3 * i + u + 1);
shapeButtons.push(shapeButton);
shapeButton.addEventListener(MouseEvent.ROLL_OVER, buttonOver);
shapeButton.addEventListener(MouseEvent.ROLL_OUT, buttonOut);
}
}
// buttons
btn_mainmenu.addEventListener(MouseEvent.CLICK, doMainmenu);
btn_reset.addEventListener(MouseEvent.CLICK, function():void{newLevel()});
// new level
newLevel();
}
private function newLevel():void {
var newScreen:MovieClip = new new_edit_screen();
addChild(newScreen);
newScreen.tWidth.restrict = "0-9";
newScreen.tHeight.restrict = "0-9";
newScreen.tWidth.text = 10;
newScreen.tHeight.text = 6;
newScreen.incorrect.alpha = 0;
newScreen.btn_continue.addEventListener(MouseEvent.CLICK, editContinue);
function editContinue(evt:MouseEvent):void {
if (newScreen.tWidth.text == "" || newScreen.tHeight.text == "" || newScreen.tWidth.text == "0" || newScreen.tHeight.text == "0") {
newScreen.incorrect.alpha = 1;
return;
}
newScreen.parent.removeChild(newScreen);
mapGrid = [];
var width:int = newScreen.tWidth.text;
var height:int = newScreen.tHeight.text;
for (var i:int = 0; i < height; i++) {
mapGrid[i] = [];
for (var u:int = 0; u < width; u++) {
mapGrid[i][u] = 1;
}
}
// grid settings
calculateGrid();
addChild(gridShape);
gridShape.x = gridStartX;
gridShape.y = gridStartY;
// draw tiles
drawGrid();
}
}
private function calculateGrid():void {
var columns:int = mapGrid[0].length;
var rows:int = mapGrid.length;
// free size: 520x460
// fit in: 510x450
// calculate width of a cell:
gridCellWidth = Math.round(510 / columns);
var width:int = columns * gridCellWidth;
var height:int = rows * gridCellWidth;
// calculate side margin
gridStartX = (520 - width) / 2;
if (height < 450) {
gridStartY = (450 - height) / 2;
}
if (height >= 450) {
gridCellWidth = Math.round(450 / rows);
height = rows * gridCellWidth;
width = columns * gridCellWidth;
gridStartY = (460 - height) / 2;
gridStartX = (520 - width) / 2;
}
}
private function drawGrid():void {
gridShape.graphics.clear();
var width:int = mapGrid[0].length;
var height:int = mapGrid.length;
var i:int;
var u:int;
// draw background
for (i = 0; i < height; i++) {
for (u = 0; u < width; u++) {
if (mapGrid[i][u] == 1) drawCell(u, i, 0xffffff, 1, 0x999999);
}
}
}
private function drawCell(width:int, height:int, fill:uint, thick:Number, line:uint):void {
gridShape.graphics.beginFill(fill);
gridShape.graphics.lineStyle(thick, line);
gridShape.graphics.drawRect(width * gridCellWidth, height * gridCellWidth, gridCellWidth, gridCellWidth);
}
private function buttonOver(evt:MouseEvent):void {
evt.currentTarget.bg.alpha = 1;
}
private function buttonOut(evt:MouseEvent):void {
evt.currentTarget.bg.alpha = 0.3;
}
private function doMainmenu(evt:MouseEvent):void {
(root as MovieClip).gotoAndStop(1);
}
}
}
Thanks for reading!
Results:
Wednesday, January 28, 2015
The Flash AS3 Tween Class
In this tutorial, were going to learn how to use the Flash AS3 Tween Class. The tween class lets you create tween animation using code.
Step 1
Lets first create a movie clip that we will use with our ActionScript 3 tween.
Draw a small circle and convert it into a movie clip symbol. Dont forget to give this circle an instance name. Lets name it circle_mc.
Step 2
Create a new layer for the ActionScript. Select the first frame of this layer, and then open up the Actions panel.
Step 3
We first need to import the Flash AS3 Tween class so that we will be able to use it. On the first line, type:
Aside from the tween class, we also need to import the easing classes. So in the next line, type:
The easing classes allow us to specify different kinds of tween effects. There are 6 easing classes in the AS3 easing package. These are:
Each easing type will apply a different effect to your tween animation.
And now that weve imported the necessary classes, lets create a tween using code.
Step 4
To create an AS3 tween object, type new Tween() and assign in to a variable. Lets name this tween tweenX. After the import statements, type:
This creates a new tween object named tweenX. Lets use this tween object to make our circle on the stage move from the left to the right. To do that, well need to pass a few arguments to the Tween() constructor.
The Tween() constructor needs 7 arguments. First, we need to specify the object that we want to tween. In this case, that would be circle_mc. So type in circle_mc inside the parentheses of the Tween() constructor.
After that, we need to specify the name of the property of the object that we would like to tween. If you wanted to create a fading animation, then you can specify the alpha property. If you wanted to create a scaling animation then you can specify the width, height, scaleX or scaleY properties. But since we want to make the circle move horizontally, then we can use the x property. So lets pass that to the Tween() constructor as well:
The property name is a string so it should be in quotation marks.
The third argument we need to pass is the easing type that we want to use. The easing type will apply an effect to the movement in the tween. Lets try using Bounce.easeOut for this tween. This will create a bouncing effect when the circle reaches the end of the animation.
The fourth argument we need to pass is for the starting value of the objects property that we are tweening. So since we are using the x property, this next argument that we pass will be for the starting x position of the circle. Lets specify a value of 100.
So when the tween starts, circle_mc will have a starting x position of 100.
The fifth argument we need to pass is for the ending value of the objects property. Lets specify a value of 400.
So this means that at the end of the tween, our circle will be positioned at x = 400.
The sixth argument we need to pass is for the duration of the tween. You can specify the duration in frames or in seconds. Lets specify a duration of 3 seconds.
The seventh and last argument we need to specify is a boolean - true or false. If we specify true, then this means that the duration will be in seconds. If we specify false, then the duration will be in frames. Since we want our tween to play over a period of 3 seconds, then we should specify a value of true.
And now our tween is complete. Test the movie to preview the animation.
Step 5
Here is a list of all the other easing functions that you can use. Try them out to see how they look like. Simply replace the third argument in the Tween() constructor with a new easing function of your choice.
Step 6
If you want to tween other movie clips, then youll have to create new tween objects for each movie clip that you want to tween. Even if you want to tween different properties of the same movie clip instance, youll still need new tween objects for each. So if we also wanted to tween the scaleX and scaleY properties of circle_mc, then well need to create two more tween objects for each property.
Here, aside from moving horizontally, the circle will also grow. Were starting out with a scaleX and scaleY of 1, and moving up to a value of 2 within 3 seconds. This means that the circle will grow from 100% to 200% both horizontally and vertically within that period.
We dont need to use the same easing functions, starting values, ending values, and durations for all our tweens. Try playing around with different values, and see what you can come up with.
And that concludes this Flash AS3 Tween Class tutorial.
Read more »
Step 1
Lets first create a movie clip that we will use with our ActionScript 3 tween.
Draw a small circle and convert it into a movie clip symbol. Dont forget to give this circle an instance name. Lets name it circle_mc.
Step 2
Create a new layer for the ActionScript. Select the first frame of this layer, and then open up the Actions panel.
Step 3
We first need to import the Flash AS3 Tween class so that we will be able to use it. On the first line, type:
import fl.transitions.Tween;Aside from the tween class, we also need to import the easing classes. So in the next line, type:
import fl.transitions.easing.*;The easing classes allow us to specify different kinds of tween effects. There are 6 easing classes in the AS3 easing package. These are:
- Back
- Bounce
- Elastic
- None
- Regular
- Strong
Each easing type will apply a different effect to your tween animation.
And now that weve imported the necessary classes, lets create a tween using code.
Step 4
To create an AS3 tween object, type new Tween() and assign in to a variable. Lets name this tween tweenX. After the import statements, type:
var tweenX:Tween = new Tween();This creates a new tween object named tweenX. Lets use this tween object to make our circle on the stage move from the left to the right. To do that, well need to pass a few arguments to the Tween() constructor.
The Tween() constructor needs 7 arguments. First, we need to specify the object that we want to tween. In this case, that would be circle_mc. So type in circle_mc inside the parentheses of the Tween() constructor.
var tweenX:Tween = new Tween(circle_mc);After that, we need to specify the name of the property of the object that we would like to tween. If you wanted to create a fading animation, then you can specify the alpha property. If you wanted to create a scaling animation then you can specify the width, height, scaleX or scaleY properties. But since we want to make the circle move horizontally, then we can use the x property. So lets pass that to the Tween() constructor as well:
var tweenX:Tween = new Tween(circle_mc, "x");The property name is a string so it should be in quotation marks.
The third argument we need to pass is the easing type that we want to use. The easing type will apply an effect to the movement in the tween. Lets try using Bounce.easeOut for this tween. This will create a bouncing effect when the circle reaches the end of the animation.
var tweenX:Tween = new Tween(circle_mc, "x", Bounce.easeOut);The fourth argument we need to pass is for the starting value of the objects property that we are tweening. So since we are using the x property, this next argument that we pass will be for the starting x position of the circle. Lets specify a value of 100.
var tweenX:Tween = new Tween(circle_mc, "x", Bounce.easeOut, 100);So when the tween starts, circle_mc will have a starting x position of 100.
The fifth argument we need to pass is for the ending value of the objects property. Lets specify a value of 400.
var tweenX:Tween = new Tween(circle_mc, "x", Bounce.easeOut, 100, 400);So this means that at the end of the tween, our circle will be positioned at x = 400.
The sixth argument we need to pass is for the duration of the tween. You can specify the duration in frames or in seconds. Lets specify a duration of 3 seconds.
var tweenX:Tween = new Tween(circle_mc, "x", Bounce.easeOut, 100, 400, 3);The seventh and last argument we need to specify is a boolean - true or false. If we specify true, then this means that the duration will be in seconds. If we specify false, then the duration will be in frames. Since we want our tween to play over a period of 3 seconds, then we should specify a value of true.
var tweenX:Tween = new Tween(circle_mc, "x", Bounce.easeOut, 100, 400, 3, true);And now our tween is complete. Test the movie to preview the animation.
Step 5
Here is a list of all the other easing functions that you can use. Try them out to see how they look like. Simply replace the third argument in the Tween() constructor with a new easing function of your choice.
| Back | Bounce | Elastic |
| Back.easeIn Back.easeOut Back.easeInOut | Bounce.easeIn Bounce.easeOut Bounce.easeInOut | Elastic.easeIn Elastic.easeOut Elastic.easeInOut |
| None | Regular | Strong |
| None.easeNone | Regular.easeIn Regular.easeOut Regular.easeInOut | Strong.easeIn Strong.easeOut Strong.easeInOut |
Step 6
If you want to tween other movie clips, then youll have to create new tween objects for each movie clip that you want to tween. Even if you want to tween different properties of the same movie clip instance, youll still need new tween objects for each. So if we also wanted to tween the scaleX and scaleY properties of circle_mc, then well need to create two more tween objects for each property.
import fl.transitions.Tween;
import fl.transitions.easing.*;
var tweenX:Tween = new Tween(circle_mc, "x", Bounce.easeOut, 100, 400, 3, true);
var tweenScaleX:Tween = new Tween(circle_mc, "scaleX", Bounce.easeOut, 1, 2, 3, true);
var tweenScaleY:Tween = new Tween(circle_mc, "scaleY", Bounce.easeOut, 1, 2, 3, true);Here, aside from moving horizontally, the circle will also grow. Were starting out with a scaleX and scaleY of 1, and moving up to a value of 2 within 3 seconds. This means that the circle will grow from 100% to 200% both horizontally and vertically within that period.
We dont need to use the same easing functions, starting values, ending values, and durations for all our tweens. Try playing around with different values, and see what you can come up with.
And that concludes this Flash AS3 Tween Class tutorial.
Tuesday, January 27, 2015
AS3 Random Numbers Generator
Heres an AS3 random numbers generator that I wrote a while back, and I thought Id share it. I explain how to use it after the code.
var allNumbers:Array = new Array();
var randomNumbers:Array = new Array();
var highest:int = 55;
var pick:int = 6;
for (var i:int = 1; i <= highest; i++)
{
allNumbers[i] = i;
if (i == highest)
{
getRandomNumbers();
}
}
function getRandomNumbers():void
{
for (var i:int = 0; i < pick; i++)
{
var rand:int = Math.ceil(Math.random() * (allNumbers.length - 1));
randomNumbers[i] = allNumbers.splice(rand,1);
if (i == pick - 1)
{
trace(randomNumbers.sort(Array.NUMERIC));
}
}
}
// For more ActionScript 3 tutorials, visit http://www.trainingtutorials101.com
Heres how it works:
Read more »
var allNumbers:Array = new Array();
var randomNumbers:Array = new Array();
var highest:int = 55;
var pick:int = 6;
for (var i:int = 1; i <= highest; i++)
{
allNumbers[i] = i;
if (i == highest)
{
getRandomNumbers();
}
}
function getRandomNumbers():void
{
for (var i:int = 0; i < pick; i++)
{
var rand:int = Math.ceil(Math.random() * (allNumbers.length - 1));
randomNumbers[i] = allNumbers.splice(rand,1);
if (i == pick - 1)
{
trace(randomNumbers.sort(Array.NUMERIC));
}
}
}
// For more ActionScript 3 tutorials, visit http://www.trainingtutorials101.com
Heres how it works:
- The highest variable allows to to specify the highest random number that can be chosen. So for example, if you assign a value of 55, then the highest random number you can get will be 55.
- The pick variable lets you specify how many random numbers to choose. So for example, if you assign a value of 6, then 6 random numbers will be chosen.
- The code is set so that the lowest random number you can get is 1, and that each number only appears once.
Thursday, January 22, 2015
Creating a Pentomino game using AS3 Part 29
In this tutorial we will add the ability to edit saved levels.
Firstly go to saved_levels.as constructor and add click event handlers for btn_edit objects of item1, item2 and item3. Set their handlers to anonymous inline functions that call editLevel() method of the root class. Pass the current levels data object from the SharedObject as the only parameter:
Open your project in Flash and go to the thrid frame (where the pentomino_edit instance is located). Give the pentomino_edit instance an id of "edit".
Then go to main.as class and declare a new public variable alreadyExists, set its default value to false.
Create a function called editLevel(). Here we receive levelItem object, set alreadyExists to true, go to the third frame, set levelName and mapGrid variables of the "edit" object to levelItem.name nad levelItem.edit and call that objects calculateAndDraw() and setShapes() methods as shown below:
The alreadyExists variable is used to tell pentomino_edit whether or not it should display the "Create new level" window in the beginning. The levelName variable sets the default name for the level thats being saved. Since we are editing an existing level, we want to use the same name, but still give the user the ability to change the name if they wish. The mapGrid variable is used to draw and manage the grid, we just apply our existing grid array to this variable. The calculateAndDraw() and setShapes() methods are new, I will explain them as I add them to pentomino_editor.as. For now, jsut rememebr to pass levelItem.shapes as parameter for setShapes().
Go to pentomino_editor.as, set mapGrid to public and declare a new public varaible levelName:
In the constructor find the line that calls newLevel(). Here we check if Pentominos alreadyExists value is false before calling the method. If it is true, dont call newLevel() and reset alreadyExists to false.
Now go to newLevel() function. In its internal editContinue() function, right after mapGrid values are set, call a function calculateAndDraw() instead of all the rest code:
Now declare this public function:
You can see the code is all the same, but because we turned it all into a public function it is now reusable.
Finally, add a function setShapes() that receives an array and applies its values to shapeButtons count values:
Now we can load the saved levels in the editor and save them. However, overwriting isnt possible right now, and nor is deleting saved levels, but well work on that in the future tutorials.
Heres full pentomino_editor.as code so far:
Thanks for reading!
Read more »
Firstly go to saved_levels.as constructor and add click event handlers for btn_edit objects of item1, item2 and item3. Set their handlers to anonymous inline functions that call editLevel() method of the root class. Pass the current levels data object from the SharedObject as the only parameter:
public function saved_levels()
{
savedLevels = SharedObject.getLocal("myLevels");
btn_back.addEventListener(MouseEvent.CLICK, doBack);
if (savedLevels.data.levels != null) levels = savedLevels.data.levels;
tInfo.text = levels.length + " levels (" + savedLevels.size + "B)";
pages = Math.floor(levels.length / 3) + 1;
goPage(1);
btn_previous.addEventListener(MouseEvent.CLICK, function() { goPage(currentPage - 1) } );
btn_next.addEventListener(MouseEvent.CLICK, function() { goPage(currentPage + 1) } );
item1.btn_play.addEventListener(MouseEvent.CLICK, function () { (root as MovieClip).playLevel(levels[3 * (currentPage-1)].grid, levels[3 * (currentPage-1)].shapes); savedLevels.data.levels[3 * (currentPage-1)].played++ } );
item2.btn_play.addEventListener(MouseEvent.CLICK, function () { (root as MovieClip).playLevel(levels[3 * (currentPage-1) + 1].grid, levels[3 * (currentPage-1) + 1].shapes); savedLevels.data.levels[3 * (currentPage-1)+1].played++} );
item3.btn_play.addEventListener(MouseEvent.CLICK, function () { (root as MovieClip).playLevel(levels[3 * (currentPage-1) + 2].grid, levels[3 * (currentPage-1) + 2].shapes); savedLevels.data.levels[3 * (currentPage-1) + 2].played++ } );
item1.btn_edit.addEventListener(MouseEvent.CLICK, function () { (root as MovieClip).editLevel(levels[3 * (currentPage-1)])} );
item2.btn_edit.addEventListener(MouseEvent.CLICK, function () { (root as MovieClip).editLevel(levels[3 * (currentPage-1) + 1])} );
item3.btn_edit.addEventListener(MouseEvent.CLICK, function () { (root as MovieClip).editLevel(levels[3 * (currentPage-1) + 2])} );
}
Open your project in Flash and go to the thrid frame (where the pentomino_edit instance is located). Give the pentomino_edit instance an id of "edit".
Then go to main.as class and declare a new public variable alreadyExists, set its default value to false.
Create a function called editLevel(). Here we receive levelItem object, set alreadyExists to true, go to the third frame, set levelName and mapGrid variables of the "edit" object to levelItem.name nad levelItem.edit and call that objects calculateAndDraw() and setShapes() methods as shown below:
package
{
import flash.display.MovieClip;
import flash.net.SharedObject;
/**
* Open-source pentomino game engine
* @author Kirill Poletaev
*/
public class main extends MovieClip
{
public var alreadyExists:Boolean = false;
public function main()
{
}
public function playLevel(grid:Array, shapes:Array):void {
gotoAndStop(2);
game.playLevel(grid, shapes);
}
public function editLevel(levelItem:Object):void {
alreadyExists = true;
gotoAndStop(3);
edit.levelName = levelItem.name;
edit.mapGrid = levelItem.grid;
edit.calculateAndDraw();
edit.setShapes(levelItem.shapes);
}
public function saveLevelLocal(grid:Array, shapes:Array, levelName:String):void {
var sharedObject:SharedObject = SharedObject.getLocal("myLevels");
if (sharedObject.data.levels == null) sharedObject.data.levels = [];
var levelObject:Object = new Object;
levelObject.grid = grid;
levelObject.shapes = shapes;
levelObject.name = levelName;
levelObject.played = 0;
sharedObject.data.levels.push(levelObject);
sharedObject.flush();
}
}
}
The alreadyExists variable is used to tell pentomino_edit whether or not it should display the "Create new level" window in the beginning. The levelName variable sets the default name for the level thats being saved. Since we are editing an existing level, we want to use the same name, but still give the user the ability to change the name if they wish. The mapGrid variable is used to draw and manage the grid, we just apply our existing grid array to this variable. The calculateAndDraw() and setShapes() methods are new, I will explain them as I add them to pentomino_editor.as. For now, jsut rememebr to pass levelItem.shapes as parameter for setShapes().
Go to pentomino_editor.as, set mapGrid to public and declare a new public varaible levelName:
public var mapGrid:Array = [];
public var levelName:String = "My Level"
In the constructor find the line that calls newLevel(). Here we check if Pentominos alreadyExists value is false before calling the method. If it is true, dont call newLevel() and reset alreadyExists to false.
// new level
if (!Pentomino.alreadyExists) {
newLevel();
}
if (Pentomino.alreadyExists) {
Pentomino.alreadyExists = false;
}
Now go to newLevel() function. In its internal editContinue() function, right after mapGrid values are set, call a function calculateAndDraw() instead of all the rest code:
private function newLevel():void {
canDraw = false;
var newScreen:MovieClip = new new_edit_screen();
addChild(newScreen);
newScreen.tWidth.restrict = "0-9";
newScreen.tHeight.restrict = "0-9";
newScreen.tWidth.text = 10;
newScreen.tHeight.text = 6;
newScreen.incorrect.alpha = 0;
newScreen.btn_continue.addEventListener(MouseEvent.CLICK, editContinue);
function editContinue(evt:MouseEvent):void {
if (newScreen.tWidth.text == "" || newScreen.tHeight.text == "" || newScreen.tWidth.text == "0" || newScreen.tHeight.text == "0") {
newScreen.incorrect.alpha = 1;
return;
}
newScreen.parent.removeChild(newScreen);
mapGrid = [];
var height:int = newScreen.tHeight.text;
var width:int = newScreen.tWidth.text;
for (var i:int = 0; i < height; i++) {
mapGrid[i] = [];
for (var u:int = 0; u < width; u++) {
mapGrid[i][u] = 1;
}
}
calculateAndDraw();
}
}
Now declare this public function:
public function calculateAndDraw():void {
// grid settings
calculateGrid();
gridShape.x = gridStartX;
gridShape.y = gridStartY;
// draw tiles
drawGrid();
// canPutShape settings
canPutShape.graphics.clear();
canPutShape.graphics.lineStyle(2, 0xff0000);
canPutShape.graphics.drawRect(0, 0, gridCellWidth, gridCellWidth);
canPutShape.alpha = 0;
canDraw = true;
}
You can see the code is all the same, but because we turned it all into a public function it is now reusable.
Finally, add a function setShapes() that receives an array and applies its values to shapeButtons count values:
public function setShapes(sh:Array):void {
for (var i:int = 0; i < shapeButtons.length; i++) {
shapeButtons[i].count.value = sh[i];
}
}
Now we can load the saved levels in the editor and save them. However, overwriting isnt possible right now, and nor is deleting saved levels, but well work on that in the future tutorials.
Heres full pentomino_editor.as code so far:
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.sampler.NewObjectSample;
import flash.utils.ByteArray;
/**
* Open-source pentomino game engine
* @author Kirill Poletaev
*/
public class pentomino_editor extends MovieClip
{
public var mapGrid:Array = [];
public var levelName:String = "My Level"
private var shapeButtons:Array = [];
private var gridShape:Sprite = new Sprite();
private var canPutShape:Sprite = new Sprite();
private var gridStartX:int;
private var gridStartY:int;
private var gridCellWidth:int;
private var canDraw:Boolean = false;
private var mouseDown:Boolean = false;
private var currentCell:Point = new Point( -1, -1);
private static var Pentomino:MovieClip;
public function pentomino_editor()
{
Pentomino = (root as MovieClip);
addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
// add shape buttons
for (var i:int = 0; i < 4; i++) {
for (var u:int = 0; u < 3; u++) {
var shapeButton:MovieClip = new edit_shape();
shapeButton.x = 528 + u * 62;
shapeButton.y = 15 + i * 84;
addChild(shapeButton);
shapeButton.bg.alpha = 0.3;
shapeButton.shape.gotoAndStop(3 * i + u + 1);
shapeButton.count.minimum = 0;
shapeButton.count.maximum = 100;
shapeButtons.push(shapeButton);
shapeButton.addEventListener(MouseEvent.ROLL_OVER, buttonOver);
shapeButton.addEventListener(MouseEvent.ROLL_OUT, buttonOut);
}
}
// buttons
btn_mainmenu.addEventListener(MouseEvent.CLICK, doMainmenu);
btn_reset.addEventListener(MouseEvent.CLICK, function():void { newLevel() } );
btn_save.addEventListener(MouseEvent.CLICK, doSave);
stat_display.addEventListener(MouseEvent.MOUSE_OVER, function() { stat_display.alpha = 0 } );
stat_display.addEventListener(MouseEvent.MOUSE_OUT, function() { stat_display.alpha = 1 } );
// new level
if (!Pentomino.alreadyExists) {
newLevel();
}
if (Pentomino.alreadyExists) {
Pentomino.alreadyExists = false;
}
addChild(gridShape);
addChild(canPutShape);
stat_display.parent.setChildIndex(stat_display, stat_display.parent.numChildren - 1);
canPutShape.mouseEnabled = false;
canPutShape.mouseChildren = false;
}
private function onMouseMove(evt:MouseEvent):void {
if(mapGrid.length>0){
var mousePos:Point = new Point(Math.floor((mouseX - gridStartX) / gridCellWidth), Math.floor((mouseY - gridStartY) / gridCellWidth));
canPutShape.x = mousePos.x * gridCellWidth + gridStartX;
canPutShape.y = mousePos.y * gridCellWidth + gridStartY;
if (mousePos.x < mapGrid[0].length && mousePos.y < mapGrid.length && mousePos.x >= 0 && mousePos.y >= 0) {
canPutShape.alpha = 1;
}else {
canPutShape.alpha = 0;
}
}
}
private function newLevel():void {
canDraw = false;
var newScreen:MovieClip = new new_edit_screen();
addChild(newScreen);
newScreen.tWidth.restrict = "0-9";
newScreen.tHeight.restrict = "0-9";
newScreen.tWidth.text = 10;
newScreen.tHeight.text = 6;
newScreen.incorrect.alpha = 0;
newScreen.btn_continue.addEventListener(MouseEvent.CLICK, editContinue);
function editContinue(evt:MouseEvent):void {
if (newScreen.tWidth.text == "" || newScreen.tHeight.text == "" || newScreen.tWidth.text == "0" || newScreen.tHeight.text == "0") {
newScreen.incorrect.alpha = 1;
return;
}
newScreen.parent.removeChild(newScreen);
mapGrid = [];
var height:int = newScreen.tHeight.text;
var width:int = newScreen.tWidth.text;
for (var i:int = 0; i < height; i++) {
mapGrid[i] = [];
for (var u:int = 0; u < width; u++) {
mapGrid[i][u] = 1;
}
}
calculateAndDraw();
}
}
public function calculateAndDraw():void {
// grid settings
calculateGrid();
gridShape.x = gridStartX;
gridShape.y = gridStartY;
// draw tiles
drawGrid();
// canPutShape settings
canPutShape.graphics.clear();
canPutShape.graphics.lineStyle(2, 0xff0000);
canPutShape.graphics.drawRect(0, 0, gridCellWidth, gridCellWidth);
canPutShape.alpha = 0;
canDraw = true;
}
private function calculateGrid():void {
var columns:int = mapGrid[0].length;
var rows:int = mapGrid.length;
// free size: 520x460
// fit in: 510x450
// calculate width of a cell:
gridCellWidth = Math.round(510 / columns);
var width:int = columns * gridCellWidth;
var height:int = rows * gridCellWidth;
// calculate side margin
gridStartX = (520 - width) / 2;
if (height < 450) {
gridStartY = (450 - height) / 2;
}
if (height >= 450) {
gridCellWidth = Math.round(450 / rows);
height = rows * gridCellWidth;
width = columns * gridCellWidth;
gridStartY = (460 - height) / 2;
gridStartX = (520 - width) / 2;
}
}
private function drawGrid():void {
gridShape.graphics.clear();
var width:int = mapGrid[0].length;
var height:int = mapGrid.length;
var i:int;
var u:int;
// draw background
for (i = 0; i < height; i++) {
for (u = 0; u < width; u++) {
if (mapGrid[i][u] == 1) drawCell(u, i, 0xffffff, 1, 0x999999);
}
}
displayTotalCells();
}
private function drawCell(width:int, height:int, fill:uint, thick:Number, line:uint):void {
gridShape.graphics.beginFill(fill);
gridShape.graphics.lineStyle(thick, line);
gridShape.graphics.drawRect(width * gridCellWidth, height * gridCellWidth, gridCellWidth, gridCellWidth);
}
private function buttonOver(evt:MouseEvent):void {
evt.currentTarget.bg.alpha = 1;
}
private function buttonOut(evt:MouseEvent):void {
evt.currentTarget.bg.alpha = 0.3;
}
private function doMainmenu(evt:MouseEvent):void {
Pentomino.gotoAndStop(1);
}
private function onMouseDown(evt:MouseEvent):void {
mouseDown = true;
}
private function onMouseUp(evt:MouseEvent):void {
mouseDown = false;
currentCell = new Point(-1, -1)
}
private function onEnterFrame(evt:Event):void {
// if drawing is allowed and mouse is down
if (canDraw && mouseDown) {
var mousePos:Point = new Point(Math.floor((mouseX - gridStartX) / gridCellWidth), Math.floor((mouseY - gridStartY) / gridCellWidth));
// if valid coordinates
if (mousePos.x < mapGrid[0].length && mousePos.y < mapGrid.length && mousePos.x >= 0 && mousePos.y >= 0) {
// if the cell is not "current cell"
if (mousePos.x != currentCell.x || mousePos.y != currentCell.y) {
currentCell.x = mousePos.x;
currentCell.y = mousePos.y;
if (mapGrid[mousePos.y][mousePos.x] == 1) {
mapGrid[mousePos.y][mousePos.x] = 0;
}else {
mapGrid[mousePos.y][mousePos.x] = 1;
}
drawGrid();
}
}
}
}
public function setShapes(sh:Array):void {
for (var i:int = 0; i < shapeButtons.length; i++) {
shapeButtons[i].count.value = sh[i];
}
}
private function doSave(evt:MouseEvent):void {
if (checkSave()) {
var shapes:Array = [];
for (var i:int = 0; i < shapeButtons.length; i++) {
shapes.push(shapeButtons[i].count.value);
}
var saveScreen:MovieClip = new save_screen(Pentomino, mapGrid, shapes, alertClose);
addChild(saveScreen);
canDraw = false;
}
}
private function displayTotalCells():void {
var totalCells:int = 0;
var i:int;
var u:int;
var width:int = mapGrid[0].length;
var height:int = mapGrid.length;
for (i = 0; i < height; i++) {
for (u = 0; u < width; u++) {
if (mapGrid[i][u] == 1) totalCells++;
}
}
stat_display.tCells.text = totalCells;
if (totalCells / 5 != Math.round(totalCells / 5)) {
stat_display.tCells.textColor = 0xFF0000;
}else {
stat_display.tCells.textColor = 0x009900;
}
}
private function checkSave():Boolean {
// count total cells
var totalCells:int = 0;
var i:int;
var u:int;
var width:int = mapGrid[0].length;
var height:int = mapGrid.length;
for (i = 0; i < height; i++) {
for (u = 0; u < width; u++) {
if (mapGrid[i][u] == 1) totalCells++;
}
}
// check if total cells can be divided by 5
if (totalCells / 5 != Math.round(totalCells / 5)) {
alert("Error!
Incorrect cell count: " + totalCells + ", number must be divideable by 5.");
return false;
}
// count total available shape count
var totalShapes:int = 0;
for (i = 0; i < shapeButtons.length; i++) {
totalShapes += shapeButtons[i].count.value;
}
// check if there are enough shapes available
if (totalCells > totalShapes * 5) {
alert("Error!
Not enough shapes available: " + totalShapes + " out of " + totalCells/5);
return false;
}
return true;
}
private function alert(message:String):void {
var alertWindow:MovieClip = new alert_screen(message, alertClose);
addChild(alertWindow);
canDraw = false;
}
private function alertClose():void {
canDraw = true;
}
}
}
Thanks for reading!
Subscribe to:
Posts (Atom)