Actionscript 3 Designer Toolkit

More design, less programming

Actionscript 3 Designer Toolkit header image 2

Prototyping the Bookshelves function

March 5th, 2010 · No Comments · AS3 Custom Classes

I originally wrote this function in 2007 in Actionscript 2 (remember createEmptyMovieClip) and recently rewrote it in as3.  The concept is to present a series of “shelves” that move together vertically as a group but move independently of each other when moving horizontally.  Instead of a grid of rows and buttons imagine shelves of books with each shelf holding a different category e.g. history, biography, art & photography…

The buttons that control the movement of the shelves automatically show/hide themselves based on the status of the uppermost shelf visible.

The code below create a main sprite which is tweened vertically while serving as a container for all the rows. The rows, in turn, are independently tweened horizontally while also serving as a container for all its buttons.  The custom ButtonPressedEvent class communicates from within each button its id and function.

import com.dtk.Button_WH;
import com.dtk.NavIconLoader;
import com.dtk.ButtonPressedEvent;
import com.dtk.HTMLText;
import caurina.transitions.*;
 
/**
 *	basic settings
 */
var rows:uint = 10;
var cols:uint = 10;
 
var maskedRows:uint = 5;
var maskedCols:uint = 5;
 
// upper left position of grid
var xStart:uint = 60;
var yStart:uint = 60;
 
var btnWidth:uint  = 30;
var btnHeight:uint = 30;
var spacing:uint   = 10;
 
// calc mask width, height
var maskWidth:uint  = maskedCols * ( btnWidth + spacing );
var maskHeight:uint = maskedRows * ( btnHeight + spacing );
 
// first button id number
var btnID:uint  =  0;
 
// init vars
var xPos:uint = xStart;
var yPos:uint = yStart;
 
// init var to define tweened movement
var movement:int;
 
// current top visible row id
var rowID:uint = 0;
 
// sprite to contain all rows
var main:Sprite = new Sprite( );
main.name = 'main';
addChild( main );
 
// loop through columns one row at a time
for ( var r:uint=0; r<rows; r++ )
{
	// reset starting postion for each row
	xPos = xStart + spacing / 2;
 
	// row spite holds buttons
	var rw:Sprite = new Sprite( );
	rw.name = 'row_' + r;
	main.addChild( rw );
 
	for ( var c:uint=0; c<cols; c++ )
	{
		// add button instance to row
		var b:Button_WH = new Button_WH( btnID, btnWidth, btnHeight, btnID.toString( ) );			
		b.x = xPos;
		b.y = yPos;
		b.name = 'btn_' + c;
		b.addEventListener( ButtonPressedEvent.BUTTON_PRESSED, onGridButtonPressed );
		rw.addChild( b );
 
		// calc next button position & increment button id
		xPos += ( btnWidth + spacing );
		btnID++;
	}
	// calc next row position
	yPos += ( btnHeight + spacing );
}
 
// draw & set mask
var ms:Sprite = new Sprite( );
ms.graphics.beginFill( 0xff0000 );
ms.graphics.drawRect( xStart, yStart, maskWidth, maskHeight );
ms.graphics.endFill( );
addChild( ms );
 
main.mask = ms;
 
/*
 *	load UP, DOWN, LEFT, RIGHT nav buttons with DOWN & RIGHT not visible
 *	set each with own event listener
 *
 */
var down:NavIconLoader = new NavIconLoader( 'DOWN', 'arrows/down.jpg', 40, 40 );
down.x = xStart + 2 * btnWidth + 2 * spacing;
down.y = 10;
down.visible = false;
down.addEventListener( ButtonPressedEvent.BUTTON_PRESSED, onNavButtonPressed );
down.name = 'down';
addChild( down );
 
var up:NavIconLoader = new NavIconLoader( 'UP', 'arrows/up.jpg', 40, 40 );
up.x = xStart + 2 * btnWidth + 2 * spacing;
up.y = yStart + 5 * ( btnHeight + spacing );
up.addEventListener( ButtonPressedEvent.BUTTON_PRESSED, onNavButtonPressed );
up.name = 'up';
addChild( up );
 
var left:NavIconLoader = new NavIconLoader( 'LEFT', 'arrows/left.jpg', 40, 40 );
left.x = xStart + ( 5 * btnWidth ) + ( 6 * spacing );
left.y = yStart - spacing + 4;
left.addEventListener( ButtonPressedEvent.BUTTON_PRESSED, onNavButtonPressed );
left.name = 'left';
addChild( left );
 
var right:NavIconLoader = new NavIconLoader( 'RIGHT', 'arrows/right.jpg', 40, 40 );
right.x = 10;
right.y = yStart - spacing + 4;
right.visible = false;
right.addEventListener( ButtonPressedEvent.BUTTON_PRESSED, onNavButtonPressed );
right.name = 'right';
addChild( right );
 
/*
 *	function called by each button press calculates tween movement & current row
 *
 */
function onNavButtonPressed( e:ButtonPressedEvent ):void
{
 
	switch( e.buttonEvent )
	{
		// UP
		case 0:
			movement = main.y - btnHeight - spacing;
			Tweener.addTween ( main, { y: movement, time: 1, onComplete: tweenedUp } );
			rowID++;
			break;
		// DOWN
		case 1:
			movement = main.y + btnHeight + spacing;
			Tweener.addTween ( main, { y: movement, time: 1, onComplete: tweenedDown } );
			rowID--;
			break;
		// LEFT
		case 2:
			movement = main.x - 5 * ( btnWidth + spacing );
			Tweener.addTween ( main.getChildAt( rowID ), { x: movement, time: 2, onComplete: tweenedLeft } );
			break;
		// RIGHT
		case 3:
			movement = main.getChildAt( rowID ).x + 5 * ( btnWidth + spacing );
			Tweener.addTween ( main.getChildAt( rowID ), { x: movement, time: 2, onComplete: tweenedRight } );
			break;
 
	}
}
 
function tweenedUp( ):void
{
	if ( main.y + main.height <= btnHeight + ( 2 * spacing ) )
	{
		getChildByName( 'up' ).visible = false;
	}
 
	getChildByName( 'down' ).visible = true;
 
	testLeftRight( );
}
 
/*
 *	after down tween of row is completed set visibilty of up, down buttons
 *
 */ 
function tweenedDown( ):void
{
	if ( main.y >= 0 )
	{
		getChildByName( 'down' ).visible = false;
	}
 
	getChildByName( 'up' ).visible = true;
 
	// update visibility of left, right buttons
	testLeftRight( );
}
 
function tweenedLeft( ):void
{
	getChildByName( 'right' ).visible = true;
 
	if ( main.getChildAt( rowID ).x <= maskWidth )
	{
		getChildByName( 'left' ).visible = false;
	}
}
 
function tweenedRight( ):void
{
	getChildByName( 'left' ).visible = true;
 
	if ( main.getChildAt( rowID ).x == 0 )
	{
		getChildByName( 'right' ).visible = false;
	}
}
 
/*
 *	control visibility of left, right buttons as rows move up/down
 *
 */
function testLeftRight( ):void
{
	if ( main.getChildAt( rowID ).x <= maskWidth )
	{
		getChildByName( 'right' ).visible = true;
		getChildByName( 'left' ).visible  = false;
	}
 
	if ( main.getChildAt( rowID ).x == 0 )
	{
		getChildByName( 'left' ).visible  = true;
		getChildByName( 'right' ).visible = false;
	}
}
 
/*
 *	display id of button pressed
 *
 */
function onGridButtonPressed( e:ButtonPressedEvent ):void
{
	// remove previous instance of text displayed
	for ( var i:uint=0; i<numChildren; i++ )
	{
		if ( getChildAt(i).name == 'txt' )
		{
			removeChildAt(i);
		}
	}
 
	// instance of HTMLText class
	var txt:HTMLText = new HTMLText( 100, 'Verdana', 48, 0xcccccc, 'RIGHT', '<b>'+e.buttonEvent.toString( )+'</b>' );
	txt.x = xStart + 190;
	txt.y = yStart + 140;
	txt.name = 'txt';
	addChild( txt );
}

The download includes bookshelves.fla, a folder containing the nav button jpg’s and the four custom classes used.

Download files: Bookshelves.zip (41)

Post to Twitter

Tags: ····

No Comments so far ↓

There are no comments yet...Kick things off by filling out the form below.

Leave a Comment

Spam Protection by WP-SpamFree