Apr 12 2009

AS3.0 TutBits #01: Getter and Setter

AS3.0 TutBits is a series of small Actionscript mini tutorials. Their purpose is to point out certain differences of the actionscript 3.0 language compared to other programming languages. Each tutorial just concentrates on a tiny technical issue. The AS3.0 TutBits are not tutorials that teaches you how to programm in actionscript.

Ok, enough introductional text - let’s start:

First topic is Getter and Setter. Well, I do no want to start the discussion again if they are useful or not - here it is how they are supported in Actionscript3.0:

package
{
	public class GetterSetter
	{
		private var hiddenName:String = "OLD: Joshua";
 
		public function get name():String
		{
			return this.hiddenName;
		}		
 
		public function set name(newName:String):void
		{
			this.hiddenName = "NEW: " + newName;
		}
	}
 
}

On line #05, we have the class property called hidden name we want to make accessible via getter and setters. Therefore, we create two methods one line #07 and line #12 which are identified by the keyword get and set followed by the same methodname name(). With this construct you create a faked public class property called name of the class GetterSetter. You access it like a normal property using the following syntax:

var gs:GetterSetter = new GetterSetter();
trace(gs.name);
gs.name = "Joshua";
trace(gs.name);

The output of that would be:

OLD: Joshua
NEW: Joshua

That means that when you access the faked class property you actually call the respective get- or set- method. So you have the easiness of simulating direct access of a property value but still have the chance to keep control of it.

Nevertheless, this technique has some drawbacks. First, it is not possible that the property has the same name as the get/set methodname. So, if we would have named our property “name” instead of “hiddenName” it would resulted in a compile-time error. In addition, whenever you call the set method - the get method is called automatically as the result of the set method call. This hidden “feature” could also causes some confusion if you do not know that.

In the end it is up to your personal taste if you want to use this feature of actionscript or not. Of course you could implement getters and setters in the standard way writing methods like getHiddenName() and setHiddenName().


Mar 27 2009

Experimental PV3D clock

Here is a little experimental 3D-Clock realized with Papervision3D. It is my entry to the DBF Democode TIME CHALLENGE. The little effect shows seconds (purple box) and minutes (greenish box). The seconds clock hand moves every 5 seconds and the minutes clock hand every five minutes. The hour clock hand is missing.

Screenshot of PV3D clock

Well, as always I ran out of time (deadline is today). That’s why the following features I actually wanted to implement are missing:

  • shadow casting
  • hour clock hand
  • moving camera
  • correct some 3D issues

The experiment requires flash 9 and uses Papervision3D and the Tweener.


Feb 1 2009

Beta version of a simple physics game

In the last two days I played around with Box2D. Box2D is an open source 2D physics engine for games. In addition there exists an actionscript port for the Flash platform. Studying various examples on the internet and the wonderful tutorials of Emanuele Feronato I came up with the following little game. It is still in beta phase and there are plenty of things which needs to be added and polished.

scr-tblocks

Note: Link to the game is deactivated. The final game is in progress. Beta is closed.

Anyway, maybe you want to have a try on it. The logic is very easy. The aim of the game is to drop as many blocks as possible on the green bar. Move your mouse to determine the x-position of the block to drop. Press left button to drop it. On the upper right you see the percentage of wind and the direction in which the wind is blowing. That wind effects the following blocks.

Here is a little list of things that are still to do:

  • Highscore system
  • Start screen
  • Polish score and wind system
  • Fixing bugs

Please let me know if you have any more ideas or if you find any bugs. By the way, my current highscore is 22 blocks ;-)


Dec 26 2008

ActionScript CountTelexTF class

Some years ago I coded a promotional intro for the democode forum called DBF+GVY Interactive. This tiny intro called A shameless plug uses a certain typer/text effect to show its messages. The text effect isn’t new at all - if you know the 80’s movie called “Wargames” you probably remember it. It was used when the supercomputer called W.O.P.R. was searching for the right missle launch code.

Well, the following C++ code is nearly two years old.

//
// the basic algorithm/idea behind the text effect used
// in the dbfinteractive promo intro downloadable at :
// http://dbfinteractive.com/index.php?action=tpmod;dl=item53
//
// (c) 2oo7 by benny!weltenkonstrukteur.de
//
 
#include 
#include 
 
int telexTyper ( char *pMsg, char *pTelexText ) {
 
// telexTyper returns 1 when message equals telexText
// else 0. It is assumed that MSG and TELEXTEXT are of
// the same length !!!
 
	int ret = 1;
 
	// loop the the telex text
	for ( int i=0; i < strlen(pTelexText); i++ ) {
		int ascii_Msg = (int)*pMsg;			// get ascii value of char (scrollText)
		int ascii_Tex = (int)pTelexText[i];		// get ascii value of char (telexText)
		if ( ascii_Msg < ascii_Tex ){			// substract ascii value by 1
			ascii_Tex--;
			ret = 0;
		} else if ( ascii_Msg > ascii_Tex ) {	// or add ascii value by 1
			ascii_Tex++;
			ret = 0;
		}
		pTelexText[i] = (char)ascii_Tex;
		pMsg++;
	}
	printf ( "%s\n", pTelexText );
 
	return ret;
}
 
int main(  ) {
	// telexText holds the characters that are displayed
	char telexText[7]	= "AAAAA\0";
	// the scroller array hold the actual text
	char scroller[2][7]= { "HELLO\0",
							"WORLD\0"	};
 
	// we loop as long as telexTyper return 1
	// returning 1 means that the characters in the source array scroller
	// are equal to the characters in the destination array telexText
	while ( telexTyper ( &scroller[0][0], &telexText[0] ) == 0 );
 
	printf ( "\nFirst scrolltext successfully displayed!\n\n" );
 
	while ( telexTyper ( &scroller[1][0], &telexText[0] ) == 0 );
 
	printf ( "\nSecond scrolltext successfully displayed!\n" );
 
	// end - wait for keypress
	getchar();
    return 0;
}

However, today I thought it would be nice to write a similar effect in Flash. So, I extended the textfield class and came up with the CountTelexTF class. This class actually does all you need to realize the effect. The class file is too long to be listed here - but have a look at the following demo programm that makes use of the new class:

package
{
	import flash.events.*;
	import flash.display.Sprite;
	import flash.filters.GlowFilter;
	import flash.text.*;
	import de.weltenkonstrukteur.utils.CountTelexTF;
 
	/**
	* Demo of CountTelexTF class usage
	* @author benny!weltenkonstrukteur.de
	*/
	public class Main extends Sprite
	{
		// Specify font
		[Embed(source='Crisp.ttf', fontName='Crisp', fontWeight='normal', mimeType='application/x-font-truetype')]
		private var telexFont:Class;		
 
		// Member variables
		private var cntTf:CountTelexTF = null;
 
		/**
		 * Constructor
		 */
		public function Main()
		{
			// Register font
			Font.registerFont(telexFont);
			var tfo:TextFormat = new TextFormat('Crisp', 36, 0x00ff00);			
 
			// Create CountTelexTF instance
			cntTf = new CountTelexTF();
			cntTf.width = stage.stageWidth;
			cntTf.y = 50;
			cntTf.autoSize = TextFieldAutoSize.CENTER;
			cntTf.defaultTextFormat = tfo;
			cntTf.embedFonts = true;
 
			// Add some glow filter
			var glow:GlowFilter = new GlowFilter( 0x00CC00, 0.8, 35, 35, 4);
			cntTf.filters = [glow];
 
			// Create and set string array
			var myText:Array = new Array();
			myText[0] = "Whatever Keeps Us Longing ";
			myText[1] = "For Another Breath Of Air ";
			myText[2] = "     Is Getting Rare      ";
			myText[3] = "But Is Has To Be Somewhere";
			myText[4] = "                          ";
			cntTf.setTextArr(myText);
			addChild(cntTf);
			cntTf.start();
		}
	}
}

The result looks like this:


scr-counttelextf

Of course it is recommended to use a monospace font with this effect. Otherwise it looks a bit jerky. You can download the example and the class itself with the following link. Enjoy.

Name: ActionScript CountTelex Class
Size: 3.56 KB
Hits: 164


Dec 21 2008

Rotozoomer in Actionscript3.0

One oldschool demoscene effect I still love is the so called Rotozoomer. Rotozoomer by its name rotates and zooms an image in and out. The effect is really stunning and it is well known among oldschool amiga sceners. Reading the very good tutorial about Actionscript’s Transformation Matrix class by senocular.com inspired me to have a try to do a rotozoomer in pure ActionScript3.0.

If you cross-read to senocular’s tutorial and my source code you see how easy the pixel tranformation matrix work to come up with the effect.

The flash movie requires at least Flash Player9.0 - just press on the screenshot to run it. The fantastic “bunny” image was made by the artist called made.

Rotozoom Screenshot

Finally, here is the source code. I tried to comment it as best as I can. Have fun with it.

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.events.MouseEvent;
	import flash.net.*;
 
	/**
	  * Simple rotozoomer in actionscript3.0
	  *
	  * @author benny!weltenkonstrukteur.de
	  */
	public class RotoZoom2 extends Sprite
	{
		// Declaring class constants
		private const ZOOM_MAX:Number 		= 3;
		private const ZOOM_MIN:Number 		= -2.0;
		private const ZOOM_DELTA:Number 	= 0.015;
		private const ROTATE_DELTA:Number	= 0.05;
 
		/// Initialisate private class members
		private var angle:Number = 0, zoom:Number = ZOOM_MIN, isZoomIncreasing:Boolean = true;
		private var logo:Bitmap = null, logoBitmapData:BitmapData;
		private var sw:uint, sh:uint;
 
		// Declare embedded assets
		[Embed(source = "made-bunny.png")]
		private var LogoBitmap:Class;
 
		/**
		 * Constructor
		 */
		public function RotoZoom2()
		{
			init();
			addEventListener("enterFrame", loop);
		}
 
		/**
		 * Initialize needed sprites and bitmaps
		 */
		private function init():void
		{
			// Create logo bitmap and retrieving the bitmapData
			logo = new LogoBitmap();
			logoBitmapData = logo.bitmapData;
 
			// Setting canvas dimensions
			sw = stage.stageWidth;
			sh = stage.stageHeight;
		}
 
		/**
		 * Calcualte roto matrix and draws the scene
		 * @param	ev, onEnter event
		 */
		private function loop(ev:Event):void
		{
			// If we want to zoom in
			if ( isZoomIncreasing )
			{
				// Add increase value to zoom
				zoom = zoom + ZOOM_DELTA;
			}
			else
			{
				// Otherwise decrement value from zoom
				zoom = zoom - ZOOM_DELTA;
			}
 
			// Calculate new rotation angle
			angle = angle + ROTATE_DELTA;
 
			// If angle is greater than 360
			if ( angle > 360 )
			{
				// Reset it to zero
				angle = 0;
			}
 
			// If zoom is higher than maximum value
			if ( zoom > ZOOM_MAX )
			{
				// Change to zoom out
				isZoomIncreasing = false;
				zoom = ZOOM_MAX;
			}
			// If zoom is less than minimum value
			else if ( zoom < ZOOM_MIN )
			{
				// Change to zoom in
				isZoomIncreasing = true;
				zoom = ZOOM_MIN;
			}
 
			// Calculate matrix for rotation an zooming
			var rotoMatrix:Matrix = new Matrix(Math.cos(angle) * zoom, Math.sin(angle), -Math.sin(angle), Math.cos(angle) * zoom, 0, 0);
 
			// Fill scene with bitmap using the rotoMatrix
			graphics.clear();
			graphics.beginBitmapFill(logoBitmapData, rotoMatrix,true, true);
			graphics.drawRect(0, 0, sw, sh);
			graphics.endFill();
 
			// Set it free for gargabe collection
			rotoMatrix = null;
 
		}
	}
 
}