Improve Your Memory With an Away3D Game

In this tutorial we’ll build a 3D memory game. Along the way we’ll look at adding variables and mouseEvents to Away3D objects. Let’s get started..

Step 1: ActionScript File

Create a new ActionScript 3.0 file.

away3d flash game

Step 2: Edit Profile

In the Properties panel press the Edit button.

away3d flash game

Step 3: Choose Flash Player Version

Choose the Flash Player 9 profile and click OK.

away3d flash game

Step 4: Get the Away3D Engine!

Save your file as "Memory Game.fla" in the Memory Game Tutorial folder. Now download the Away3D engine from Away3D Downloads. We’ll use version 2.3.3 for Flash Player 9. Unpack the archive and copy all folders into the Memory Game Tutorial folder.

Step 5: Get the Tweener!

Download Tweener from here. Unpack the class files to your Memory Game Tutorial folder so it all looks like this:

away3d flash game

Step 6: Import Textures

We’ll use 5 different cards for this game (you can find them in the source files). Import them into Flash by going File > Import > Import to Library.

away3d flash game

Step 7: Export Textures for ActionScript

To use these textures in runtime we need to attach a Class name to them. Select the images one by one and go Right-Click > Properties > Export for ActionScript. Just remove the ".png" parts of their names.

away3d flash game

Step 8: Start Coding

After all that we’re ready to start coding. Let’s fill our first lines by importing the classes:

import away3d.cameras.*;
import away3d.containers.*;
import away3d.materials.*;
import away3d.primitives.Plane
import away3d.primitives.Cube
import away3d.containers.ObjectContainer3D;
import away3d.core.math.Number3D;
import caurina.transitions.*
 

Step 9: Setup Variables

After importing our classes we should define our variables to use in the following steps.

var scene:Scene3D;
var camera:Camera3D;
var view:View3D;
var totalchildren:int=10
var cards:Array
var textures:Array = [ new texture0(0,0),
new texture1(0,0),
new texture2(0,0),
new texture3(0,0),
new texture4(0,0)]
var backtexture:BitmapData = new textureback(0,0)
var woodtexture:BitmapData = new texturewood(0,0)
var cardwidth:Number = 110
var cardheight:Number = 150
var xoffset:Number = 10
var yoffset:Number = 10
var cardsholder:ObjectContainer3D
var selectedCard1:Plane
var selectedCard2:Plane
var disableMouseEvents:Boolean=false

The textures array holds our texture images. To attach images to our stage from the library we use this method:
var imageData:BitmapData = LibraryLinkageName(0,0). We use the same approach for our table and back face of the cards. xoffset and yoffset define the distance between cards.

Step 10: Setup Away3D

First of all we need to build Away3D.

function initAway3D():void {
 scene = new Scene3D();

 camera = new Camera3D();
 camera.y = 700
 camera.z = 500
 camera.lookAt(new Number3D(0,0,0))

 view = new View3D({scene:scene, camera:camera});
 view.x = stage.stageWidth/2
 view.y = stage.stageHeight/2
 addChild(view);
 }

the first line in our function creates the 3D scene. We’ll add 3D objects into it. After that we create the camera. We’ll move it backward and upward a bit. By doing this, we’ll able to see cards better when we’re playing the game. Then we’ll center it. Finally we create the View and set it in the middle of the scene.

Step 11: Creating the Table

In this step we’ll create the table:

function createGround():void {
 var cube:Cube = new Cube({width:680,depth:400,height:20,pushback:true,ownCanvas:true,material: new BitmapMaterial(woodtexture)})
 cube.y=-20
 scene.addChild(cube)
 }

To make it look more realistic we’re using a Cube instead of a Plane. The most important point here is to use pushback properties in Cube to make it visible under the cards. The material we use for Cube is BitmapMaterial. This is the best way to use bitmaps as textures.

Step 12: Creating One Card

First we’ll create a holder. There’ll be two planes in this holder. One of these planes is the front face of the cards and the other one is the back. We’ll use the holder to rotate or move the cards.

away3d flash game
function createCard(texture:BitmapData,id:int):ObjectContainer3D {
	var card:ObjectContainer3D = new ObjectContainer3D()

	var front:Plane = new Plane({width:cardwidth,height:cardheight, material: new BitmapMaterial(texture,{smooth:true})})
	var back:Plane = new Plane({width:cardwidth,height:cardheight, material: new BitmapMaterial(backtexture,{smooth:true})})
	front.rotationY=180
	back.rotationZ=180
	back.rotationY=180

	back.extra = {}
	back.extra.id = id
	back.extra.targetCard = card
	back.addOnMouseDown(onBackClicked)

	card.rotationZ=180
	card.addChild(front)
	card.addChild(back)
	card.ownCanvas = true
	return card
}

In this function we are recreating what the diagram illustrates. We should use rotation to place the cards face down. We aren’t adding an event to the holder, because we only click the back face of the card. For this reason we add a mouseDown event to the back Plane only.

Every 3D object in Away3D can have extra variables and every color in our game has a unique id. We’ll add this id variable to the "extra" propertie of back Plane. We’ll use ids to check if the selected two cards are the same color or not.

Step 13: Creating All Cards

After the card creating function, we’re ready to create all of them.

function initCards():void {
 cards = new Array()
 for(var i:int = 0; i<textures.length; i++ ) {

 var card1:ObjectContainer3D = createCard(textures[i],i)
 var card2:ObjectContainer3D = createCard(textures[i],i)

 cards.push( card1 )
 cards.push( card2 )

 }
 }

We’ll push all our cards to a cards array. There’ll be two cards of each color (two blue, two red and two green). Because of this we create two cards with the same color then push them to the array.

Step 14: Randomize Cards

Next step is to randomize the cards array.

function randomizeCards():void{
 var newArray:Array = new Array();
 while(cards.length > 0){
 newArray.push(cards.splice(Math.floor(Math.random()*cards.length), 1)[0]);
 }
 cards = newArray
 }

It’s all so simple. First we are creating a new array. Then we are picking a random item from the cards array, pushing it to the new array and removing it from cards array. After the while loop has completed we equalize the cards array to our new array. Now we have a randomized array.

Step 15: Adding Cards to the Scene

Now, we’ve randomized our cards, so we can add them to the scene. We’ll use a grid system for their positions

function addCardsToScene():void {
	cardsholder = new ObjectContainer3D()
	var currentindex:int = 0

	for(var i:int=0; i<2; i++) {
		for(var b:int=0; b<5; b++) {
			cards[currentindex].x=b*(cardwidth+xoffset)+cardwidth/2
			cards[currentindex].z=i*(cardheight+yoffset)+cardheight/2
			cardsholder.addChild(cards[currentindex])
			currentindex++
		}
	}

	var cardswidth:Number = (5*cardwidth) + (4*xoffset)
	var cardsheight:Number = (2*cardheight) + (1*yoffset)

	cardsholder.x=-cardswidth/2
	cardsholder.z=-cardsheight/2

	scene.addChild(cardsholder)
}

The first “for” loop is for the x axis and the second one is for the y axis. We’re adding cards to a new main holder, so when we want to rotate or move the cards we can only use the main holder. Then we set the cards by using the grid system. For that we are using cardwidth, cardheight, xoffset and yoffset variables. The cards need to be in the middle of table. To do this we need to get width and height values of the main cards holder. This diagram shows the way we are getting them.

away3d flash game

After we get them we move the main holder into the middle of the table.

Step 16: Mouse Down Event

We’ve added cards to scene. Our next step will be creating the mouseDown event function.

function onBackClicked(e:Event) {
	if(disableMouseEvents==false) {
		if(selectedCard1==null) {
			selectedCard1 = e.currentTarget as Plane
		}else {
			if(selectedCard2==null) {
				selectedCard2 = e.currentTarget as Plane
				waitForDecision()
				disableMouseEvents = true
			}
		}
		Tweener.addTween(e.currentTarget.extra.targetCard,{y:50,rotationZ:0,time:1})
	}
}

First we check disableMouseEvents. That means if we have permission to click cards we continue but if we don’t nothing happens. If the first card isn’t selected, clicked card is our first card. If first card isn’t null then this clicked card is our second card.

Our game must make a desicion after we select the two cards as to whether they’re same or not. For this reason our “waitForDecision” function is running and we set disableMouseEvents to true. So while the game is waiting for a decision, nothing will happen if we click a card.

The rotationZ property of our clicked card will be 180 degree with Tweener, so we can see the color of the card.

Step 17: Wait for a Decision

When the two cards are selected, the game waits a little (this is just for fun).

function waitForDecision():void {
	var timer:Timer = new Timer(1000,1)
	timer.addEventListener(TimerEvent.TIMER,makeDecision)
	timer.start()
}

As you can see, this is a simple Timer usege. It waits 1000 miliseconds (1 second). After that, TimerEvent triggers the makeDecision function to run.

Step 18: Make a Decision

We waited 1 second so now it’s time to make a decision. If the id values of the cards are the same they will disappear, if not they will turn face down again

function makeDecision(e:Event):void {
	if(selectedCard1.extra.id == selectedCard2.extra.id) {
		Tweener.addTween(selectedCard1.extra.targetCard,{alpha:0,time:0.2,onComplete:removeCard,onCompleteParams:[selectedCard1.extra.targetCard]})
		Tweener.addTween(selectedCard2.extra.targetCard,{alpha:0,time:0.2,onComplete:removeCard,onCompleteParams:[selectedCard2.extra.targetCard]})
	}else {
		Tweener.addTween(selectedCard1.extra.targetCard,{y:0,rotationZ:180,time:1})
		Tweener.addTween(selectedCard2.extra.targetCard,{y:0,rotationZ:180,time:1})
	}
	disableMouseEvents = false
	selectedCard1 = null
	selectedCard2 = null
}

We are doing exactly that in this function. We are checking the id values of two selected cards. If they are same, the alpha values of them will change 0 with Tweener (we make them disappear). When this tween is finished , the removeCard function is called. The parameter of the removeCard function is the cards themselves. We do this to the two cards at the same time. If they are not the same, we send them to their old positions and make them face down. Whatever the desicion is, selectedCard1 and selectedCard2 will be set to null.

Step 19: Removing Cards

We need to remove the two cards from our main cards holder when they disappear, because we don’t need them anymore.

function removeCard(e:ObjectContainer3D):void {
	cardsholder.removeChild(e)
	totalchildren--
	if(totalchildren==0) {
		trace("WIN")
	}

}

After they are kicked out of the scene, the value of totalchildren decreases one by one. When it reaches 0 this means you’ve won the game!

Step 20: Rendering

The final step is to write a loop function to render Away3D in runtime.

function startToRender():void {
   addEventListener(Event.ENTER_FRAME, render);
   }
function render( e:Event ):void{
   view.render();
}

Step 21: Call All Functions

We’re ready to call all the functions we’ve written.

initAway3D()
createGround()
initCards()
randomizeCards()
addCardsToScene()
startToRender()

Now test it and play your game :)

Conclusion

In this lesson we learned how to add variables and mouseEvents to Away3D objects. With these skills we made a game and as you can see it wasn’t so hard :)

I hope you liked this tutorial, thanks for reading!

Tags: Away3D
Add Comment

Discussion 20 Comments

  1. Kevin says:

    Sweet, I did the same with papervision 3D a few months back for a project but i used boxes instead of planes.

    Nice to see away3d getting some love!

  2. André says:

    Great tutorial, really nice, this could be done with some 3D of flash CS4, but nice the explanation here… i use papervision 3D and Alternativa plataform wich i think is the better 3D engine for flash

  3. Franky says:

    Totally Legit!

    I love it.
    It would be great to work on this and build a score keeper, and some game ui!

    Awesome tutorial!

  4. Stunt says:

    Explain why you use older version of flash player ?

    • Karl Macklin says:

      Probably because it is possible.

      Not everyone has updated to FP10, so it’s useful (if possible) to target FP9 instead.

      He’s using away3d instead of FP10′s 3D handling so it’s all good.

  5. Web 2.0 says:

    I liked this one, pretty cool…

  6. viaria says:

    great tutorial.. keep coming..
    teşekürler

  7. Selam,

    Kutlarım Yağız ben adobeokulu’ndan kabare08 (demir alkanlar)
    Çok şık tutorial olmuş.

    Dışarıdaki sitelerde çalışmalarının devamı dileğiyle..

    İyi çalışmalar

    • Ian Yates says:
      Staff

      Thanks Demir (and for those of you who don’t speak Turkish, here’s what translate.google kindly threw out for me:)

      Hallo,

      Congratulations my Yağız adobeokulu’ndan kabare08 (iron alkanes)
      Tutorial was very stylish.

      Wishing you more of the sites out of work ..

      Good work

      • Unfortunately translation above is not correct. It should be like that:
        —-
        Hello,

        Congratulations Yağız, I am kabare08 (Demir Alkanlar) from AdobeOkulu community forum. This tutorial is elegant.

        I hope to see your works on other websites…

        Keep the good work! (actually this sentence not exists in english)
        —–

  8. Luiz Carlos says:

    Muito bom amigo!!!!

  9. Janet says:

    Really nice looking game – Thanks a lot!

  10. ROROR says:

    HEY GILBERT GUERREROROORORORROROROROR

  11. Richard says:

    Nice game but it doesn’t have a PLAY AGAIN or RESTART new game option after the game is over

  12. Jose Campos says:

    Great tut a built a game just like this but not using away i used the built in Flash 3D API, you can check it out here: http://www.mochimedia.com/games/memory_v13/

  13. Rob says:

    Nice, this is one of the best tutorials I ever saw,
    well explained, clean, lots of images, etc…
    Keep on doing the good work!!!

  14. Mehk says:

    Hey there, I am using the memory script above and its working great!
    I just have one question about it though. I am trying to get the script to work and insert new frames, with other content the only problem there (since its dynamically) loaded, the cards appear on the other frames aswell if you didnt finish the game before going to the next frame, is there anyway to remove the childs properly so they do not appear on the other frames aswell? Because removing View3D only makes more error messages.

    I am asking this because the structure is pretty large.

  15. spartydawg says:

    How do I go about change the amount of cards? Say I wanted four rows of 6?

  16. I love seeing new, clever away3d content! Very cool example.

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.