logo
468x60-2-495


  • Home
  • Privacy Policy
  • About
search
May 21, 2012
The Math and ActionScript of...
We see lines used in a lot of scenarios; curves are also used but perhaps not as frequently – but that doesn’t undermine their importance! In this tutorial we shall take a closer look at...
read more
May 20, 2012
Weekend Lecture: Understandi...
Interested in game design? This weekend, we feature a set of four interactive lectures: games that are about game design, by Pixelate. Play the Games Bub and Bob, two little 8-bit guys, will talk...
read more
top
Jul 5, 2011 Posted on Jul 5, 2011 in Hints and Tips | 10 comments

Create a Pinball-Style Rolling Score Counter Class

Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Activetuts+. This tutorial was first published in February, 2010.

In this tutorial you’ll create a reusable Score class that counts up to the new total when points are added (instead of jumping up to the new score). We’ll cover graphics creation as well as code.


Final Result Preview

In some games when you gain points, you’ll see your score immediately jump to the new total. I think it’s much cooler if the score counts up one by one, so the player can “rack up points”. That’s what we’ll be making here.

Here’s an example of the score class in action:

The main idea behind this tutorial is to teach you how to program the “counting up” functionality, but I’ll also show you how to create the cool LED display seen in the preview. We’ll start by designing the numbers:


Step 1: Set up Your Flash File

Create a new Flash file (ActionScript 3.0). Your movie settings will vary depending on your game. For this demo I’m setting up my movie as 500×300, black background, and 30 fps.

Flash file setup

Step 2: Create the Digit Symbol

Create a new Movie Clip symbol (Insert > New Symbol). Give this symbol the name “digit”.

TK

Step 3: Create the Digit Text Field

Inside the digit movie clip use the Text tool to add a number 0 to the symbol. I’m using a font called Digital Readout, but any LED-style font should work.

Set the text size to 40 pt and make it a light amber/orange color (#F4C28B). Set the Paragraph Format to centered.

TK

Step 4: Add Glows

Add two separate glow filters to your text field. Set the color to red (#FF0000) for both and set the Strength of both to 200%.

Check the Inner Glow checkbox for one and set the Blur to 2px. Leave the other at 5px Blur.

TK

You can use a different color if you want (blue or green would both look cool). The trick in getting it to look realistic is to make the text color a little washed out and set the glows to a more saturated color. This makes it look like it’s emitting light.


Step 5: Add More Numbers

Create keyframes on frames 1-10 of the digit movie clip. An easy way to do this is to select frames 1-10 (click frame 1, then Shift-click frame 10) and press F6.

You should now have 10 frames, each with a keyframe with your glowing 0 text field. Go through each frame and change the numbers so you have the digits 0-9. Frame 1 will have “0″, frame 2 will have “1″, frame 3 will have “2″, etc.

TK

Name this layer “numbers”.


Step 6: Add the LED Background

We’ll now add an “off” state for the LED numbers, so you’ll be able to see the unlit segments of the LED display.

Copy your 8 digit (in frame 9). Create a new layer named “background”. With the new layer selected use Paste in Place (Edit > Paste in Place) to paste the 8 digit in the exact position as the one we copied.

Remove the glows from the new 8 digit and change its color to dark grey (#333333). Add a blur filter with the Blur set to 3px. Move this layer underneath the “numbers” layer.

TK

Now you can scrub through the frames and see how the unlit segments of the LED show behind each number.


Step 7: Add the Stop Action

Create another new layer named “actions”. Open the Actions Panel and add a stop() action on frame 1.

TK

This will keep the display showing ’0′ until we tell it otherwise.


Step 8: Why Frames?

Why are we manually putting each digit on its own frame instead of using a dynamic text field? Good question.

The main reason is that doing so makes it more flexible for updating the graphics later. If you wanted to change the design and use bitmaps for the numbers, or have each digit displayed in a different font or color this makes it easy to do that.

Also, if designers and developers are working together on a project it’s best to create things in a way that gives designers easy access to as much of the graphics as possible.
I feel this setup does that more than using dynamic text.


Step 9: Create the Score Movie Clip

Create a new movie clip named “Score”. Check ‘Export for ActionScript’ and set the class name to “Score” also.

TK

Drag the digit movie clip from the Library into the Score movie clip. Duplicate the digit clip (Edit > Duplicate) six times (so you have seven digits) and space them evenly.

Since we only have seven digits the maximum score we’ll be able to display is 9,999,999. If your game will need to accommodate higher scores add more digits accordingly.

Add a bit more space between every third digit to allow for comma separators.

TK

Step 10: Name the Digit Clips

Select the leftmost digit movie clip and give it the instance name “digit1″. Name the next one to the right “digit2″, then “digit3″ and so on.

TK

Step 11: Add Commas

Create a new layer called “commas”.

The easiest way to get the commas to look exactly like the numbers is to go into one of the digit clips and copy one of the number text fields.
Back inside the Score movie clip, paste the text field into the commas layer, and change the number to a comma. Duplicate it and move it as many times as you need.

TK

Step 12: Add a Background

For the Score background we’ll just add a simple rounded rectangle.

Create a new layer called “background” and place it behind the numbers and commas layers. Select the Rectangle Tool and Option-click (Alt-click) the stage. Make a rectangle 200px x 40px with 3px corners (make yours longer if you have more digits). Make the fill black and the stroke 1px grey (#666666).

TK

For some reason Flash always distorts strokes on rounded rectangles. To get around this, select the stroke and choose Modify > Shape > Convert Lines to Fills. This converts the stroke from a line to a filled shape and it will no longer distort.

TK

If you think this is a total hack of a workaround for basic functionality that should have been fixed years ago, I urge you to contact Adobe and let them know.


Step 13: Add Shine

What graphic would be complete without some iPhone-esque shine?

Create a new layer above everything else called “shine”. Add a new rounded rectangle, slightly smaller than the background one. This time give it no stroke and fill it with a white gradient from 20% Alpha to 0% Alpha.

TK

Step 14: Create the Score Class

Create a new Actionscript file named “Score.as”. Save it in the same directory as your main Flash file. Since the name of this class and the Export Class name of our Score movie clip are the same, Flash will automatically link them.

Add this code to the Score.as file:

package {

	import flash.display.MovieClip;
	import flash.events.Event;

	public class Score extends MovieClip {

		// CONSTRUCTOR
		public function Score() {

		}

	}
}

This is just an empty shell of a class for now. We have to extend the MovieClip class since this class is linked to a movie clip in the library, so we also have to import the MovieClip class. We’ll be using the ENTER_FRAME event, so we import the Event class as well.


Step 15: Add Variables and Constants

Add these two lines to the Score class just above the constructor function.

private const SPEED:int = 1; // how fast to count
private const NUM_DIGITS:int = 7; // how many digits there are in the score

These are two constants – kind of like settings for the class.

  • The first, SPEED, controls how fast the score counts. I have it set to count one by one, but if your game uses higher scores this might be too slow. You can change this to 5 or 10 or 50 to count up by those increments.
  • The second constant, NUM_DIGITS, defines how many digits we have in our Score movie clip. If you added more (or less) than 7 digits you’ll need to change this.

Now let’s add a couple of variables. Put these just below the constants:

private var _totalScore:int = 0;
private var _displayScore:int= 0;

These variables will hold the two different versions of our score. “_totalScore” will be the actual score. “_displayScore” will be the number that is currently
being shown on the LED display. If I add 50 to the score, the _totalScore will immediately be 50, but the _displayScore will be 1, then 2, then 3, until it reaches 50.

If you ever need to know the actual score (like to send to your high score boards) you’ll use _totalScore since _displayScore might not be accurate.

I’m using underscores at the beginning of the variable names to denote that these are private variables.


Step 16: Add the totalScore Accessor Method

So if _totalScore is a private variable, how will we access from outside the Score class? We’ll use an “accessor” or “getter” method.

Add this method below the constructor function:

// public accessor for totalScore
public function get totalScore():int {
	return _totalScore;
}

This method simply returns the value of the _totalScore variable. It gives us a way to access that value without having to expose it as a public variable.


Step 17: Add the add Method

We’ll need a way to add points to the score. Add this method:

// add an amount to the score
public function add(amount:int):void {
	_totalScore += amount;
	addEventListener(Event.ENTER_FRAME, updateScoreDisplay); // start the display counting up
}

This method accepts an integer “amount” which it adds to the _totalScore variable. The second line starts an ENTER_FRAME event that calls a method called updateScoreDisplay every frame. We’ll add that next.


Step 18: Add the updateScoreDisplay Method

Now add a the updateScoreDisplay method. This is where all of the cool counting-up functionality will happen. It needs to accept an Event since it’s getting called from an ENTER_FRAME event.

// this runs every frame to update the score
private function updateScoreDisplay(e:Event):void {

}

Now let’s add some functionality. The first thing this method will do is to increment the _displayScore variable by the amount we set in our SPEED constant:

// increment the display score by the speed amount
_displayScore += SPEED;

There’s a potential problem here though. What if our speed is set to 10 and we try to add 5 to the score? The displayScore will be higher than the totalScore. Let’s add a couple lines to fix that:

// make sure the display score is not higher than the actual score
if(_displayScore > _totalScore){
	_displayScore = _totalScore;
}

That checks if the displayScore is higher than the totalScore and if so, sets the displayScore to be equal to the totalScore.

Next we need to add the leading zeros to the score. We’ll do this by converting the displayScore to a String and adding zeros until the length equals the number of digits defined by the NUM_DIGITS constant:

var scoreStr:String = String(_displayScore); // cast displayScore as a String

// add leading zeros
while(scoreStr.length < NUM_DIGITS){
	scoreStr = "0" + scoreStr;
}

Now to actually display the score we’re going to loop through each of our digit clips (remember we named then “digit1″, “digit2″, etc.) and use the corresponding number from the score string to set the frame number of the clip:

// loop through and update each digit
for (var i:int = 0; i < NUM_DIGITS; i++) {
	var num = int(scoreStr.charAt(i));
	this["digit"+(i+1)].gotoAndStop(num+1);// set the digit mc to the right frame
}

The charAt method retrieves the character from a String at the specified position. This lets us go character by character through the score string.

The brackets in the next line allow us to dynamically create the clip name. The code, this["digit"+(i+1)] accesses the clip with the name “digit1″ or “digit2″, etc., depending on the value of i.

We’re using “num+1″ as the frame number because the frame numbers are offset by 1 from the digits they contain (frame 1 shows 0, frame 2 shows 1, etc.)

The last thing we need to do in this method is check to see if the displayScore and the totalScore are equal. If so, we can remove the listener and stop calling this method for now.

// if the display score is equal to the total score remove the enterframe event
if(_totalScore == _displayScore){
	removeEventListener(Event.ENTER_FRAME, updateScoreDisplay);
}

If you got lost anywhere in that step you can check out the source files to see the completed class.


Step 19: The Score Class in Use

To use this class drag the Score movie clip from the Library onto the Stage and give it the instance name “myScore”. You can add points to your score by using this line in your Document Class:

myScore.add(50);

You can see an example of this in the source files. I’m adding to the score when the bumper buttons are clicked, but you’ll more likely be calling add() when events in your game occur.

If you need to know the player’s score you can get the totalScore by using:

myScore.totalScore

This will call the accessor method and return the value of _totalScore.


Conclusion

You now have a reusable counting Score class that you can use in any of your games.

I think the LED look is cool, but you should definitely alter the design to fit the look of your game. Here are a couple ideas for different designs to get you started:

TK

Thanks for reading this tutorial. Let me know what you think!



View full post on Activetuts+

Jul 2, 2011 Posted on Jul 2, 2011 in Hints and Tips | 1 comment

Weekend Presentation: GreenSock ThrowProps Plugin

Just because you missed that awesome presentation, there’s no need for you to miss out entirely! This weekend we feature a brand new plugin for the TweenMax and TweenLite libraries.

“ThrowProps” – tweens that flick, toss, and slide gracefully. Think, for example, of flicking a page on a touch-screen device..

ThrowPropsPlugin is a plugin for TweenLite and TweenMax that allows you to simply define an initial velocity for a property (or multiple properties) as well as optional maximum and/or minimum end values. It will [then] calculate the appropriate landing position and plot a smooth course based on the easing equation you define.

Note: the ThrowProps plugin is a membership benefit of Club GreenSock.


ThrowProps in Action



View full post on Activetuts+

Jul 1, 2011 Posted on Jul 1, 2011 in Hints and Tips | 0 comments

Exclusive Freebie: AS3 Image Revealer

“Pinch, punch, first of the month”, “White Rabbits” – however you like to mark the dawn of a new month, we like to bring them in with freebies :) This month, we have a great little AS3 Image Revealer from Carlos Yanez.

Image Credits:

  • http://www.flickr.com/photos/luciano_meirelles/4196173858
  • http://www.flickr.com/photos/arcticpuppy/4091521108

AS3 Image Revealer

Take a look at the usage examples:

Here is an example revealing a black and white version of an image:

This can be very useful in before and after comparisons:


Features

Using this base file you can:

  • Change the before and after (bottom-top) images
  • Use any Display Object for the effect
  • Modify the slider graphic

Usage

Open the ImageRevealer.fla and edit the MovieClip in the stage, use the Timeline to determine where to place every image and adjust the Mask size to fill the image.

Open the Main.as file and edit the highlighted lines:

package
{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;

	public final class Main extends Sprite
	{
		var frame:int = 11; //This is the middle frame

		public final function Main():void
		{
			img.gotoAndStop(11); //Change the frame to show half top, half bottom
			arrows.buttonMode = true;
			addListeners();
		}

		private final function addListeners():void
		{
			arrows.addEventListener(MouseEvent.MOUSE_DOWN, initDrag);
			arrows.addEventListener(MouseEvent.MOUSE_UP, termDrag);
			img.addEventListener(MouseEvent.MOUSE_UP, termDrag);
		}

		private final function initDrag(e:MouseEvent):void
		{
			/* Change the y value (353) to the y of your "arrows" MC
			   Change the width value (300) to the width of your image drag area */

			arrows.startDrag(true, new Rectangle(0, 353, 300));
			stage.addEventListener(MouseEvent.MOUSE_MOVE, revealImage);
		}

		private final function termDrag(e:MouseEvent):void
		{
			arrows.stopDrag();
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, revealImage);
		}

		private final function revealImage(e:MouseEvent):void
		{
			/* This is a tricky part, the default frames in the MC are 20
			   you'll need to calculate the constant according to your frames
			   and image size to reveal the image correctly */

			img.gotoAndStop(Math.floor(arrows.x * 0.07)); //0.07 is the constant here
		}
	}
}



View full post on Activetuts+

Jun 29, 2011 Posted on Jun 29, 2011 in Hints and Tips | 0 comments

Hit the Target With a Deadly Homing Missile

This tutorial will show you a way to add homing missiles to the arsenal of your game.


Final Result Preview

Let’s take a look at the final result we will be working towards:


Step 1: Set up the FLA Document

Create a new Flash document set for ActionScript 3.0. I’ll be using the dimensions of 600×400, and a frame rate of 30 FPS. Save the file with a name of your choice.

Create a .FLA document

Step 2: Create a Document Class

Besides the FLA, we also need to create a document class. Create a new Actionscript file, and add this code:

package
{
	import flash.display.Sprite;

	public class Main extends Sprite
	{
		public function Main()
		{

		}
	}

}

Save this file in the same directory as our FLA. Name it Main.as.


Step 3: Link the Main Class with the FLA

In order to compile the code from the Main class, we need to link it with the FLA. On the Properties panel of the FLA, next to Class, enter the name of the document class, in this case, Main.

Link the Main class with the FLA

Then, save the changes on the FLA.


Step 4: Draw a Missile

We need a missile graphic to be displayed when shooting. You may import a bitmap or draw a shape right there on Flash. I’ll be using a tiny shape on this example.

Draw a missile shape or import a missile bitmap.

What’s important here is that you have to make the missile point straight to the right, since that’s the origin point for the rotation. So 0° means pointing straight to the right, -90° means upwards, 90° means downwards, and 180° points to the left. Later on we’ll need to rotate the missile according to its direction.


Step 5: Create a MovieClip for the Missile

Once you have the missile graphic, select it and press F8 to create a Movie Clip. Name it "Missile", make sure the the Registration Point is at the center, and tick the "Export for ActionScript" checkbox.

Create a MovieClip out of the missile you drew.

You’ll end up with a Missile MovieClip in the Library.

Missile MovieClip in the Library.

If you have a Missile instance on the Stage, delete it. We’ll be adding the Missile MovieClip by code.


Step 6: Aim

The first thing a homing missile needs to know is where the target is located. We’re going to set the rotation of the missile according to the position of the mouse cursor first. Let’s work with the enterFrame Event for a constant rotation update.

Add a Missile instance to the stage, I’m placing it at the center (300, 200). Then calculate the distance from the missile to the mouse cursor (I’m storing it in variables targetX and targetY). Finally, the missile’s angle will be the arc tangent of both points (targetX, targetY). The result you’ll get will be in radians, but the rotation works in degrees, so you’ll need to do the conversion by multiplying by 180/Pi. (To see why, check this article.)

import flash.events.Event;

public class Main extends Sprite
{
    private var missile:Missile = new Missile();

    public function Main()
    {
        addChild(missile);
        missile.x = 300;
        missile.y = 200;
        addEventListener(Event.ENTER_FRAME, playGame);
    }

    private function playGame(event:Event):void
    {
        var targetX:int = mouseX - missile.x;
        var targetY:int = mouseY - missile.y;
        missile.rotation = Math.atan2(targetY, targetX) * 180 / Math.PI;
    }
}

(Not sure what Math.atan2() is for? Check out this article on trigonometry.

If you Publish (Ctrl + Enter) the document at this point, you should be getting something like this:

Move your mouse near the missile to see it rotate.


Step 7: Seek

We got the rotation, now we need the movement. The missile has to seek the target, no matter whether it’s a steady or a moving target. What we’ll do is calculate the movement according to the current rotation of the missile. Let’s set a value for the speed, and make the missile chase after the mouse cursor.

We’ll include a couple of new variables to calculate the velocity (vx, vy). When the missile is pointing to the right, its angle is lower than 90° and higher than -90°, so it’s always lower than the absolute value of 90°. When it’s pointing to the left, its angle has an absolute value higher than 90°. This will determine vx in accordance to speed, then vy will be the difference of speed and vx.

private var speed:int = 10;

public function Main()
{
    addChild(missile);
    missile.x = 300;
    missile.y = 200;
    addEventListener(Event.ENTER_FRAME, playGame);
}

private function playGame(event:Event):void
{
    var targetX:int = mouseX - missile.x;
    var targetY:int = mouseY - missile.y;
    missile.rotation = Math.atan2(targetY, targetX) * 180 / Math.PI;
    //Velocity in x is relative to the angle, when it's 90° or -90°, vx should be 0.
    var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
    var vy:Number;//Velocity in y is the difference of speed and vx.
    if (missile.rotation < 0)
        vy = -speed + Math.abs(vx);//Going upwards.
    else
        vy = speed - Math.abs(vx);//Going downwards.

    missile.x += vx;
    missile.y += vy;
}

You’ll get a missile chasing your cursor.

You can use a different speed if you want.


Step 8: Create a Missile Launcher

Missiles don’t come out of thin air, they are shot out of missile launchers. Let’s make a MovieClip representing a cannon (I’ll use a simple rectangle), and name it Cannon. I’m going to add a Cannon instance by code, so I’m going to keep the stage empty.

Cannon MovieClip in the Library.

Step 9: Shoot

Now, instead of adding a missile, I’m just going to add a cannon, and a missile will be added at the cannon’s position when I click on the stage. We’ll add a Boolean to check if the missile has been shot, and also a new function for shooting after the click.

import flash.events.MouseEvent;

public class Main extends Sprite
{
    private var missile:Missile = new Missile();
    private var speed:int = 10;
    private var cannon:Cannon = new Cannon();
    private var missileOut:Boolean = false;//Has the missile been shot?

    public function Main()
    {
        addChild(cannon);
        cannon.x = 50;
        cannon.y = 380;
        addEventListener(Event.ENTER_FRAME, playGame);
        stage.addEventListener(MouseEvent.CLICK, shoot);
    }

    private function playGame(event:Event):void
    {
        if (missileOut)
        {
            var targetX:int = mouseX - missile.x;
            var targetY:int = mouseY - missile.y;
            missile.rotation = Math.atan2(targetY, targetX) * 180 / Math.PI;

            var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
            var vy:Number;
            if (missile.rotation < 0)
                vy = -speed + Math.abs(vx);
            else
                vy = speed - Math.abs(vx);

            missile.x += vx;
            missile.y += vy;
        }
    }

    private function shoot(event:MouseEvent):void
    {
        if (!missileOut)
        {
            addChild(missile);
            swapChildren(missile, cannon);//missile will come out from behind cannon
            missileOut = true;
            missile.x = cannon.x;
            missile.y = cannon.y;
        }
    }

This is what you’ll get:

This doesn’t look nice. We have to either make the cannon rotate as well, or force the missile to go upwards right after being shot. Since option #1 is the easiest approach, we’ll take option #2.


Step 10: Less Precision for Better Looks

If the cannon is vertical, we would expect the missile to launch upwards and then get on track towards its target. The approach I’ll use to achieve this is to give the missile a starting angle of -90° (pointing upwards), and smoothly rotate to get on track to the mouse cursor. We’ll add an ease variable to determine the smoothness or sharpness of the rotation. Then we’ll create another variable to keep track of the actual rotation that points straight to the target, while the missile’s rotation will change according to the ease we set (ease = 1 will behave just like before, anything higher will make a smoother turn).

Since half of the rotation values are negative, in some cases we’ll need to calculate them against 360 to get the actual difference between the target angle and the missile’s rotation.

private var ease:int = 10;

public function Main()
{
    addChild(cannon);
    cannon.x = 50;
    cannon.y = 380;
    addEventListener(Event.ENTER_FRAME, playGame);
    stage.addEventListener(MouseEvent.CLICK, shoot);
}

private function playGame(event:Event):void
{
    if (missileOut)
    {
        var targetX:int = mouseX - missile.x;
        var targetY:int = mouseY - missile.y;
        var rotation:int = Math.atan2(targetY, targetX) * 180 / Math.PI;
        if (Math.abs(rotation - missile.rotation) > 180)
        {
            if (rotation > 0 && missile.rotation < 0)
                missile.rotation -= (360 - rotation + missile.rotation) / ease;
            else if (missile.rotation > 0 && rotation < 0)
                missile.rotation += (360 - rotation + missile.rotation) / ease;
        }
        else if (rotation < missile.rotation)
            missile.rotation -= Math.abs(missile.rotation - rotation) / ease;
        else
            missile.rotation += Math.abs(rotation - missile.rotation) / ease;

        var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
        var vy:Number;
        if (missile.rotation < 0)
            vy = -speed + Math.abs(vx);
        else
            vy = speed - Math.abs(vx);

        missile.x += vx;
        missile.y += vy;
    }
}

private function shoot(event:MouseEvent):void
{
    if (!missileOut)
    {
        addChild(missile);
        swapChildren(missile, cannon);//missile will come out from behind cannon
        missileOut = true;
        missile.x = cannon.x;
        missile.y = cannon.y;
        missile.rotation = -90;//missile will start pointing upwards
    }
}

Check it out:

Notice what happens when you move your mouse out of the SWF, and how this is different from the previous example.


Step 11: Missile Hits, Missile Explodes

Besides the Missile Movie Clip, we need an explosion animation. In my case, I’ll make a separate MovieClip with a simple tween of a circle that expands. I’m exporting it as Explosion. Press O to select the Oval Tool, and hold Shift while drawing the oval to get a circle.

The circle inside its own Movie Clip with a Bevel filter.

For a nicer visual effect, I’ll put the circle inside another Movie Clip of its own, and give it a Bevel filter to get a darker color at the bottom and a lighter color at the top. Next, I’ll go to frame 10 and press F6 to create a Keyframe, then right-click between frame 1 and 10 and create a Classic Tween. Back on frame 10, press Q to select the Free Transform Tool and enlarge the circle.

Enlarge the circle in a Classic Tween.

Then, create another Classic Tween to frame 20, I’ll add a Blur filter effect.

Add a Blur filter in a Classic Tween.

Finally, make it disappear in a last Classic Tween to frame 30 with an Alpha color effect going to 0.

Alpha color effect set to 0 in a Classic Tween.

Step 12: Clean Up the Stage

The explosion animation has to be removed after it finishes, or it will loop indefinitely. Add a new layer and press F6 on the last frame, then press F9 to open the Actions panel, and add this code:

stop();<br />parent.removeChild(this);

This will make the Explosion instance remove itself after the animation is done.

The Explosion instance will remove itself.

Step 13: Explode

Now when the missile meets the cursor, we’ll replace it with an Explosion instance. We just need to add a new conditional in the playGame() function.

private function playGame(event:Event):void
{
    if (missileOut)
    {
        if (missile.hitTestPoint(mouseX, mouseY))
        {
            var explosion:Explosion = new Explosion();
            addChild(explosion);
            explosion.x = missile.x;
            explosion.y = missile.y;
            removeChild(missile);
            missileOut = false;
        }
        else
        {
            var targetX:int = mouseX - missile.x;
            var targetY:int = mouseY - missile.y;
            var rotation:int = Math.atan2(targetY, targetX) * 180 / Math.PI;
            if (Math.abs(rotation - missile.rotation) > 180)
            {
                if (rotation > 0 && missile.rotation < 0)
                    missile.rotation -= (360 - rotation + missile.rotation) / ease;
                else if (missile.rotation > 0 && rotation < 0)
                    missile.rotation += (360 - rotation + missile.rotation) / ease;
            }
            else if (rotation < missile.rotation)
                missile.rotation -= Math.abs(missile.rotation - rotation) / ease;
            else
                missile.rotation += Math.abs(rotation - missile.rotation) / ease;

            var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
            var vy:Number;
            if (missile.rotation < 0)
                vy = -speed + Math.abs(vx);
            else
                vy = speed - Math.abs(vx);

            missile.x += vx;
            missile.y += vy;
        }
    }
}

Take a look:


Step 14: Something Else to Blow Up

Chasing after the mouse cursor was entertaining, but it’s pointless in a game; we need to make a target. I’m going to draw a bunch of circles to form a Target Movie Clip.

Create and export a Target Movie Clip.

Step 15: Shoot the Target

Now we’ll add a Target instance for the missile to have a more tangible objective. So we’ll replace any reference of the mouse cursor for the target’s position. Also, we won’t be testing for a hit point, but an object.

private var target:Target = new Target();

public function Main()
{
    addChild(cannon);
    cannon.x = 50;
    cannon.y = 380;
    addEventListener(Event.ENTER_FRAME, playGame);
    stage.addEventListener(MouseEvent.CLICK, shoot);addChild(target);
    target.x = 550;
    target.y = 50;
}

private function playGame(event:Event):void
{
    if (missileOut)
    {
        if (missile.hitTestObject(target))
        {
            var explosion:Explosion = new Explosion();
            addChild(explosion);
            explosion.x = missile.x;
            explosion.y = missile.y;
            removeChild(missile);
            missileOut = false;
        }
        else
        {
            var targetX:int = target.x - missile.x;
            var targetY:int = target.y - missile.y;
            var rotation:int = Math.atan2(targetY, targetX) * 180 / Math.PI;
            if (Math.abs(rotation - missile.rotation) > 180)
            {
                if (rotation > 0 && missile.rotation < 0)
                    missile.rotation -= (360 - rotation + missile.rotation) / ease;
                else if (missile.rotation > 0 && rotation < 0)
                    missile.rotation += (360 - rotation + missile.rotation) / ease;
            }
            else if (rotation < missile.rotation)
                missile.rotation -= Math.abs(missile.rotation - rotation) / ease;
            else
                missile.rotation += Math.abs(rotation - missile.rotation) / ease;

            var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
            var vy:Number;
            if (missile.rotation < 0)
                vy = -speed + Math.abs(vx);
            else
                vy = speed - Math.abs(vx);

            missile.x += vx;
            missile.y += vy;
        }
    }
}

private function shoot(event:MouseEvent):void
{
    if (!missileOut)
    {
        addChild(missile);
        swapChildren(missile, cannon); //missile will come out from behind cannon
        missileOut = true;
        missile.x = cannon.x;
        missile.y = cannon.y;
        missile.rotation = -90;//missile will start pointing upwards
    }
}

The hitTestObject() method actually only checks for an overlap between the bounding boxes of the two objects (i.e., the blue boxes that appear when you click an instance of the object in the stage), so watch out for that; it’s not pixel-perfect collision detection. However, it does the job just fine here.

You may try placing the target at different locations, as well as the cannon.


Step 16: Moving Target

We already saw that the missile will chase a moving target, such as the mouse cursor, so now let’s make the Target instance move a little.

This isn’t realistic physics, I’m just going to make the target bounce vertically. I’ll pick a reference point as the ground level, and add a gravity value to affect the target. And to make it more dynamic, I’ll increase the missile speed to 15.

private var floor:int = 385;
private var gravity:Number = 0.5;
private var targetVY:Number = 0;//Current vertical velocity of the target

public function Main()
{
    addChild(cannon);
    cannon.x = 50;
    cannon.y = 380;
    addEventListener(Event.ENTER_FRAME, playGame);
    stage.addEventListener(MouseEvent.CLICK, shoot);addChild(target);
    target.x = 550;
    target.y = 50;
}

private function playGame(event:Event):void
{
    if (missileOut)
    {
        if (missile.hitTestObject(target))
        {
            var explosion:Explosion = new Explosion();
            addChild(explosion);
            explosion.x = missile.x;
            explosion.y = missile.y;
            removeChild(missile);
            missileOut = false;
        }
        else
        {
            var targetX:int = target.x - missile.x;
            var targetY:int = target.y - missile.y;
            var rotation:int = Math.atan2(targetY, targetX) * 180 / Math.PI;
            if (Math.abs(rotation - missile.rotation) > 180)
            {
                if (rotation > 0 && missile.rotation < 0)
                    missile.rotation -= (360 - rotation + missile.rotation) / ease;
                else if (missile.rotation > 0 && rotation < 0)
                    missile.rotation += (360 - rotation + missile.rotation) / ease;
            }
            else if (rotation < missile.rotation)
                missile.rotation -= Math.abs(missile.rotation - rotation) / ease;
            else
                missile.rotation += Math.abs(rotation - missile.rotation) / ease;

            var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
            var vy:Number;
            if (missile.rotation < 0)
                vy = -speed + Math.abs(vx);
            else
                vy = speed - Math.abs(vx);

            missile.x += vx;
            missile.y += vy;
        }
    }
    targetVY += gravity;
    target.y += targetVY;
    if (target.y > floor)
    {
        target.y = floor;
        targetVY = -18;
    }
}

If you Publish this now, you should be getting a moving target.


Conclusion

Whether you want an accurate homing missile, or you’d prefer a smooth animation, you can get both results based on this example. Now you’ve got a new weapon to add in your arsenal, maybe you could try making a Worms-like game, or even use the algorithm on something other than a missile, like some weird mosquito that follows your character.

I hope you’ve found this tutorial useful. Thanks for reading!



View full post on Activetuts+

Jun 28, 2011 Posted on Jun 28, 2011 in Hints and Tips | 1 comment

Introduction to ByteArray

ByteArray is an extremely powerful Class that can be used for many things related to data manipulation, including (but not limited to) saving game data online, encrypting data, compressing data, and converting a BitmapData object to a PNG or JPG file. In this introduction, we’ll use the ByteArray class to take a native AS3 object and encode it to a string that could be saved to a server for later recovery, then decode it later.

In previous tutorials we’ve seen how to use XML and JSON to encode data in a textual (String) format. However, both XML and JSON are designed to be human-readable, and as a result they’re much longer than they need to be. It can also be tricky to convert certain types of AS3 object to either format. ByteArray has some truly advanced features, but to start with, we’ll just look at one simple one: it makes it very easy to turn an AS3 object into a String.


Final Result Preview

Let’s take a look at the final result we will be working towards:

When you paste an encoded ByteArray string into the TextField and click the Load button, it will decrypt it, and show the object properties saved in it. You can try the following encoded ByteArrays; copy-paste them into the TextField and click the Load button to see what I am talking about:

//This ByteArray will show my data (This is the default ByteArray loaded)
CgsBFW9jY3VwYXRpb24GB0NUTw93ZWJzaXRlBiFodHRwOi8vaWt0LmNvLmlkCW5hbWUGDVRhdWZpawE=
//This ByteArray will show my current thought
CgsBIWZvb2RfZm9yX3Rob3VnaHQGgnVJIGFtIHRoaW5raW5nIG9uIHNoYXJpbmcgdGhlIHRlY2huaXF1ZSBpIHVzZWQgdG8gbWFrZSBhIEZ1bGwgRmxhc2ggRHluYW1pYyBXZWJzaXRlIFNFTyBGcmllbmRseSBmb3IgbXkgbmV4dCBUdXRvcmlhbCBpbiBBY3RpdmVUdXRzKy4uLiA8dT5XaGF0IGRvIHlvdSB0aGluaz88L3U+IDxiPmlzIGl0IGEgZ29vZCBpZGVhPC9iPj8B
//This ByteArray will talk about Flash and SEO and my experience with them
CgsBEXF1ZXN0aW9uBoEDPGI+PHU+Q2FuIGEgZnVsbHkgZHluYW1pYyBGbGFzaCBXZWJzaXRlIGJlIFNFTyBmcmllbmRseTwvdT48L2I+Pz8NYW5zd2VyBoM/SXQgY2FuLCBoZXJlIGlzIHRoZSBwcm9vZiwgPGEgaHJlZj0naHR0cDovL3d3dy5nb29nbGUuY28uaWQvc2VhcmNoP3E9Zmxhc2grc2VvJmllPXV0Zi04Jm9lPXV0Zi04JmFxPXQnIHRhcmdldD0nX2JsYW5rJz5odHRwOi8vd3d3Lmdvb2dsZS5jby5pZC9zZWFyY2g/cT1mbGFzaCtzZW8maWU9dXRmLTgmb2U9dXRmLTgmYXE9dDwvYT4sIGlrdC5jby5pZCBpcyByYW5rZWQgIzYgb3ZlciB0aGVyZQE=

Step 1: Create New ActionScript Project

Create New ActionScript Project

Within the ‘Flash Builder’ window :

  1. Open Flash Builder 4
  2. Click the File Menu
  3. Hover to New
  4. Click ActionScript Project

Step 2: New ActonScript Project Setup

ActionScript Project Setup

Within the ‘New ActionScript Project’ window :

  1. Type ‘TUTORIAL_ByteArray’ into Project name field
  2. Please remember where you save your project
  3. Click ‘Finish’ button

Step 3: Base64.as

Copy Base64.as into your project ‘com’ directory.

Copy Base64.as file into 'com' directory
  1. Create a new ‘com’ directory inside your source directory.
  2. Download the Base64.as file from the source download.
  3. Put the file into the newly created ‘com’ directory.

Base64.as will come in useful later. It’s by Steve Webster, who used to reside at dynamicflash.com (he left the Flash community a couple of years ago).


Step 4: Necessary Classes

Import all Classes used in this project

In TUTORIAL_ByteArray class (which is the main class), please import the following Classes for this tutorial:

package
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.events.MouseEvent;
	import flash.utils.ByteArray;
	import com.Base64;

	public class TUTORIAL_ByteArray extends Sprite
	{
		public function TUTORIAL_ByteArray()
		{

		}
	}
}

Step 5: Getting used to Flash Builder I

Trace the 'Hello World' message

Add the following code inside TUTORIAL_ByteArray Constructor for a very simple test.

public function TUTORIAL_ByteArray()
{
	var _test:String = "Hello world!";
	trace(_test);
}

Press F11 key to run this project, you should get the message inside the Console Window.


Step 6: Getting used to Flash Builder II

Local variable only available inside the function it is created

Now let’s try to trace the message inside _test variable, but this time we will do it from another function:

public function TUTORIAL_ByteArray()
{
	var _test:String = "Hello world!";
	TestFunction();
}
private function TestFunction():void{
	trace(_test);
}

Press CTRL+S to save your project. An error detected after you saved your project; this is because a variable which has been declared inside a function will not be available for any other function. So for this case, we need to declare the _test variable outside:

public function TUTORIAL_ByteArray()
{
	TestFunction();
}
private function TestFunction():void{
	trace(_test);
}
private var _test:String = "Hello world!";
Private variables are available to all function inside the same class

Step 7: Necessary Private Variables

Create all private variables for this project

Please add the following private variables for this project:

public function TUTORIAL_ByteArray()
{
	TestFunction();
}
private function TestFunction():void{
	trace(_test);
}
private var _test:String = "Hello World!";
private var _loadButton:TextField;
private var _inputField:TextField;
private var _testObject:Object;
private var _testByteArray:ByteArray;

Step 8: UI

Let’s create a simple user interface for this project.

a Simple user interface

Now that we need to display something into our project, we need to declare our stage sizes (Check Line 13).

Rename our TestFunction into InitUI function, and put the following line of codes inside. Please read the explanation commented inside the code.

[SWF(width="550", height="400", frameRate="60", pageTitle="Tutorial ByteArray")]
public class TUTORIAL_ByteArray extends Sprite
{
	public function TUTORIAL_ByteArray()
	{
		InitUI();
	}
	private function InitUI():void{
		//Initialize our TextFields so that we can use them
		_loadButton = new TextField();
		_inputField = new TextField();

		//Give a defaultTextFormat for both of them (Tahoma at 11pt, colored 0x777777)
		_loadButton.defaultTextFormat = _inputField.defaultTextFormat = new TextFormat("Tahoma", 11, 0x777777);

		//Give both of them a border
		_loadButton.border = _inputField.border = true;

		//Set the autosize for our Load Button , so that it will automatically shrink / grow to fit the text inside
		_loadButton.autoSize = TextFieldAutoSize.LEFT;

		//Set the selectable of our Load Button to false, so that user cannot select the text in it
		_loadButton.selectable = false;

		//Set the multiline and wordWrap of our Input Field to true, so that a long text will automatically wrapped to the next line
		_inputField.multiline = _inputField.wordWrap = true;

		//Enable user to type something into our Input Field, by setting this type property
		_inputField.type = TextFieldType.INPUT;

		//Put some text into Both of them
		_loadButton.text = "Load";
		_inputField.text = "";

		//Add both of them into stage, so that they are visible to our visitors
		addChild(_inputField);
		addChild(_loadButton);

		//Position our Input Field and make it bigger
		_inputField.x = 25;
		_inputField.y = 25;
		_inputField.width = 200;
		_inputField.height = 150;

		//There is a reason why i did this, so that the Load Button is located directly below our Input Field
		//So you can position the Input Field anywhere you like, as long as there is this code, the Load Button will stick below the Input Field
		_loadButton.y = _inputField.y + _inputField.height;
		_loadButton.x = _inputField.x;
	}

Press F11 to run this project and see the simple user interface we have created.


Step 9: Enable Interactivity

Type into the field and click the load button

Please read the explanation commented inside the code

	_loadButton.y = _inputField.y + _inputField.height;
	_loadButton.x = _inputField.x;

	//Add an Event Listener for our _loadButton, so whenever the user clicks this button,
	//Flash will call _loadButton_CLICK() Method
	_loadButton.addEventListener(MouseEvent.CLICK, _loadButton_CLICK, false, 0, true);
}
//This method will be called whenever user click the _loadButton
private function _loadButton_CLICK(Events:MouseEvent = null):void{
	//Get anything that the user input and save them into our _test variable
	_test = _inputField.text;

	//Trace the _test variable
	trace("User input the following message : " + _test);
}

Press F11 to run this project; try typing something into the _inputField and then click the _loadButton. This is the most basic technique of getting a variable from our user and storing it into our private variable.


Food for Thought

We have finally reach our most important steps in this project, but before we continue let me provides a mental stimulus for thinking. Currently in our project, we are capable of getting a String and storing it in our private variable. But it is only a string; how about if I want a user to type in something inside _inputField so that I can get an Object from it? What should the user type? The answer is an ‘Encoded Base64 ByteArray’


Step 10: Introduction to ByteArray

Output from our ByteArray

We will proceed slowly this time, so that you will understand the ByteArray class and be able to create your own data manipulation and apply it to your own projects. Please read the explanation commented inside the code:

public function TUTORIAL_ByteArray()
{
	InitUI();
	CreateByteArray();
}
private function CreateByteArray():void{
	//Initialize our _testObject variable, so that we can populate many dynamic properties and store String data in it (we will load them later whenever user clicked the _loadButton)
	_testObject = new Object();
	_testObject.name = "Taufik";
	_testObject.website = "<a href='http://ikt.co.id'>http://ikt.co.id</a>";
	_testObject.occupation = "CTO";

	//Initialize our _byteArray variable, so that we can start converting object into a ByteArray
	_testByteArray = new ByteArray();

	//Convert the Object into Byte Array, This is how you do it, to convert an Object into a ByteArray, IT IS SIMPLE isnt it? :) )
	_testByteArray.writeObject(_testObject);

	//Lets see if everything works properly
	trace("Our first ByteArray created :: " + _testByteArray.toString());
}

Press F11 to run this project. See how simple it is, this ByteArray is an extremely powerful class and yet it is not hard at all. We’ve taken a native AS3 Object and converted it to Action Message Format.

Before sending the data to our PHP Script using the GET method, we should convert it into a Base64 String. This is because Base64 can be carried by XML (and by HTML).


Step 11: Encoding ByteArray into Base64 String

a Base64 String representation of our Byte data

Please read the explanation commented within the code.

private function CreateByteArray():void{
	//Initialize our _testObject variable, so that we can populate many dynamic properties and store String data in it
	//(we will load them later whenever user clicks the _loadButton)
	_testObject = new Object();
	_testObject.name = "Taufik";
	_testObject.website = "<a href='http://ikt.co.id'>http://ikt.co.id</a>";
	_testObject.occupation = "CTO";

	//Initialize our _byteArray variable, so that we can start converting object into a ByteArray
	_testByteArray = new ByteArray();

	//Convert the Object into Byte Array, This is how you do it, to convert an Object into a ByteArray, IT IS SIMPLE isnt it? :) )
	_testByteArray.writeObject(_testObject);

	//Encode the ByteArray into Base64 String (so that we can send them via PHP or copy the text to notepad), again IT IS VERY SIMPLE!
	var encoded:String = Base64.encodeByteArray(_testByteArray);

	//Put the encoded Base64 String into our _inputField (so that we can copy them into notepad)
	_inputField.text = encoded;
}

Press F11 to run this project. If converting an Object into a ByteArray is simple, converting the Byte value of our data into Base64 String is as simple, thanks to Base64.as.


Step 12: Converting Encoded Base64 String into Object

Converting a Base64 String into Object and displaying its properties and values

We will try to decode the entered Base64 String into an Object whenever the user clicks the _loadButton, change our _loadButton_CLICK function. Please read the explanation commented inside the code:

private function _loadButton_CLICK(Events:MouseEvent = null):void{
	//We have to catch any Errors
	try{
		//We decode our encoded Base64 String into a ByteArray, so that we can retrieve our Object back
		var DecodedByteArray:ByteArray = Base64.decodeToByteArray(_inputField.text);

		//If converting an Object into ByteArray is simple, retrieving an Object from ByteArray is as simple as this
		var LoadedObject:Object = DecodedByteArray.readObject();

		//Prepare to output all properties and their values inside the LoadedObject
		var Output:String = "";
		for (var VarName:String in LoadedObject){
			Output += VarName + " : " + LoadedObject[VarName] + "<br>";
		} 

		//Output them into our _inputField
		_inputField.htmlText = Output;
	}catch(err:Error){
		_inputField.text = "Please input an Encoded ByteArray into this TextField before clicking the 'Load' Button. Error message :: " + err.message;
	}
}

Press F11 to run this project. We get our encoded Base64 String of our _testObject inside our _inputField; click the _loadButton to see our project convert this Base64 String back and display all of its properties and values. You can try to copy and paste the Base64 Strings at the beginning of this tutorial and read all of my messages.


Conclusion

The ByteArray Class is an extremely powerful Class, and yet it is very simple to use. I have seen many great Flash apps out there utilizing this ByteArray to perform so many mind blowing data manipulation, such as those kinds I mentioned at the beginning of this tutorial. I have heard many Flash game programmers utilize XML to save their visitors’ ‘Save Game Data’, but as we all already know, XML is one hell of a very complicated class; with ByteArray I can save something like this EASILY.

private function CreateByteArray():void{
	_testObject = new Object();
	_testObject.name = "Taufik";
	_testObject.website = "<a href='http://ikt.co.id'>http://ikt.co.id</a>";
	_testObject.occupation = "CTO";
	_testObject.level = 99;

	//Get the state of this Game Character Inventory
	var _inventory:Array = new Array({item_id:5, amount:1}, {item_id:85, amount:1}, {item_id:42, amount:5});
	_testObject.inventory = _inventory;

	//Get what is the skill they already level up
	var _skill:Array = new Array({skill_id:1, level:0}, {skill_id:2, level:1});
	_testObject.skill = _skill;

	//Initialize our _byteArray variable, so that we can start converting object into a ByteArray
	_testByteArray = new ByteArray();

	//Convert the Object into Byte Array, This is how you do it, to convert an Object into a ByteArray, IT IS SIMPLE isnt it? :) )
	_testByteArray.writeObject(_testObject);

	//Encode the ByteArray into Base64 String (so that we can send them via PHP or copy the text to notepad), again IT IS VERY SIMPLE!
	var encoded:String = Base64.encodeByteArray(_testByteArray);

	//Put the encoded Base64 String into our _inputField (so that we can copy them into notepad)
	_inputField.text = encoded;
}

Yeah, something this complicated only takes a couple line of codes, imagine the horror of saving this data using XML and retrieving them back for further use. All in all I have to say that with Byte data manipulation you can achieve a lot of things, and some might be the solution you have been looking for all this time.

I hope you have found this tutorial useful. Thanks for reading!



View full post on Activetuts+

Page 50 of 253« First«...102030...4849505152...607080...»Last »
search search search search search
Find an Article
Categories
  • Flash Video Training
  • Hints and Tips
  • Recommended
Please Support Our Sponsors
Recent Posts
  • The Math and ActionScript of Curves: Drawing Quadratic and Cubic Curves
  • Weekend Lecture: Understanding Games, a Flash Game About Game Design
  • Weekend Lecture: Understanding Games, a Flash Game About Game Design
  • Workshop Coding Challenge: Fix This Breakout Game
  • Enable the Latest AIR SDK in Flash Professional CS5.5+
Tag Cloud
2011 ActionScript Active Activetuts+ Adobe animation Basic Basix Best Build Button Character Create Creating Critique Custom design Effect Effects Files Flash from Game Guide HTML5 Introduction Macromedia Motion Muzzle part Player Premium Professional Quick Silverlight Simple Text Tool Tutorial Tuts+ Tween Using Video website Workshop
About Our Site:

Hey there and welcome to "Flash Video Training Source", a resource for anybody interested in learning more about Adobe's great tool. We feature educational videos, which will help you master Adobe Flash and help you get to know all of its features. We at "Flash Video Training Source" believe that video training and video... more

Why don't you follow us on Twitter and get the latest video tutorials twitted to your account. Just click on the floating twitter bar to your right!

Go Back In Time
May 2012
M T W T F S S
« Apr    
 123456
78910111213
14151617181920
21222324252627
28293031  
Pretty Blank Box
top

Blogroll

  • Development Blog
  • Documentation
  • Plugins
  • Suggest Ideas
  • Support Forum
  • Themes
  • WordPress Planet

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org

Archives

  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
Powered by WordPress  |  Designed by Elegant Themes  |  Lightning Fast Hosting by Site 5 Hosting