Mar 04

I've been in touch with the author of the bold pixel engine, and I'm going to be working with him to make improvements to the engine. This is especially advantageous since he has made many updates to the V1 lib and this way I'll be able to make some positive changes to the library without stepping on his toes in terms of versioning.

The new version of the library is already sounding very promising. I can't wait to go digging through it's guts :)

Cheers!

-AG Strout

Mar 04

I've been messing the last couple of days with the bold pixel engine by VortixGames.
You can find the library here:
Bold Pixel Engine Homepage

While using the engine in my first test project, I became acutely aware of both it's benefits and it's drawbacks. I would say what it does right is that it completely obfuscates some really terribly complex sprite management and MovieClip caching in order to make a very quickly executing game with less effort. I would say what's missing is more of a polish and some very handy options.

I'm currently working on the following options and plan to submit them to VortixGames at my earliest convenience:
- Updates to LayerEntityManager and EngineLayerManager to allow for the non-destructive removal and re-adding of layers and entities. This is important especially if you want to keep the graphical state of an entity while pausing a game for example.
- Sprite sheet support. While the engine is great, I think the one thing I found lacking for me was the support for sprite sheets (that is, large single images, usually PNGs, containing an entire animation, or the entire set of sprites for a character or object). In the current build you would have to write your own code to cull the sprite sheet into an animation stack. I've added this as another optional method to the TextureManager class.
- Special effects and filters is another big one. Currently the entire system is based on -only- blitting, so if you want an entity to be drawn with a filter, or to have it drawn using a specific blendmode, or scaled / rotated etc, you are SOL. I have not quite solidified my plan for how to implement a conditional "draw" based blit yet, and I understand why they aren't using it yet (draw is a lot slower than copypixels) but I think it would be a great addition to the engine.
- A Generic abstract game object which manages an entity. This class would create an entity, and hold a set (dictionary) of texture collection indexes (the animations available to that game object) indexed by friendly names for the animations (such as "stand" or "walk"). When set to visible=false this object would remove it's entity from the layer (while persisting a reference to the layer it belongs on), and would position the entity in real time relative to it's coordinates and a position mode. For example, in a lot of games (mario etc) it's often very useful to have the sprite positioned above and centered over the registration point. With bold pixel the sprites are currently placed down and to the right of the registration.
- Finally, I have run the code through the FDT validator and cleaned it up a lot. I would also like to re-format the code and add ASDoc comments so that clear understandable documentation is available in the form of more than just YouTube Videos (the youtube videos were VERY helpful!).

Cheers all!
-AG Strout

May 27

I was struck with a dissapointing blow today when I both got a better understanding of E4X, and a bit of frustrating setback in my normal way of coding thanks to FDT3 (which besides a few slight annoyances is the best IDE of all time for flash AS3 IMHO).

E4X allows you to grab XML data from an XML datasource really quickly and efficiently. I love being able to load an XML file and then just use logical groupings to loop through it like:

for each(var x:XML in xmlSource..content..items..item){

// PARSE DATA FROM EACH item NODE HERE

}

Isn't that handy now? It is indeed!

But, you see, I'm doing something here I didn't intend to. The double dot operator actually means find ALL possible matches. So, if my XML contains:

<content>

<items>

<item id="1">

</items>

<items>

<item id="2">

</items>

</content>

For example... I'm going to grab two item nodes with the code above, which is really handy most of the time, but not if you only want to focus on nodes under the specific items node you want to look at. Well, it's as simple as taking one of those dots away! Easy no?... well no it's not because I'm using FDT3, and FDT3 sees the single dot operator as an object notation reference, not an E4X reference. I'm hoping they fix this soon, because the only way not to get a horde of warnings in my code is to use the full on .child('items')..item notation which is FUGLY compared to .items..item I'm sure you'll agree.

Ah well, If we must we must!

I'll be sure to report if FDT fixes this, they should have a new release around the corner here :)

Cheers!

-AG Strout

May 22

It's fairly interesting to try working with a 3D API in order to do 2D graphics but that is exactly what it looks like I'm going to be doing when it comes to developing for the iPhone if I want to build any of the typical retro games that I enjoy making. Granted, I plan to move into making 3D games a bit more now that I have a good platform for doing so, but in my search for a good library to write 2D games on the iPhone with I'm coming up a bit short. The Cocos2d engine which is based on an engine written for Python is turning out to be not so helpful in this regard. After some looking about I've learned that the use of the 3D Open GLES API for 2D on the iPhone is the way to go, however, the Cocos2D engine uses the Texture2D class which was given out as a part of the SDK. This isn't going to cut it for me really since I would much rather not bother with the whole quad rendering issue, and would prefer to work with Point Sprites which are, from my understanding, orders of magnitude faster, which is why they're used in game creation for particle effects in 3D games. So now my goal is to find a way to either update Coco2D (doubtful) or to create my own set of classes to use in this endeavor. I hope you will all wish me luck as I dive further into the Open GL ES library and try to build my very first interactive iPhone entertainment application.

Cheers All!

-AG Strout

May 15

I was pondering for a moment how the distortion map was used in my previous post to create a paint spreading effect. I realized it probably has been done before, but I've never seen it done quite this way. In Photoshop there's a very handy tool for smearing bitmap content and I find it to be very useful there. I've recreated the effect here with a smooth edged brush. The dog you see is Sadie, my great dane, and subject of some recent photography by my wife.

Without further ado, here's the example, followed by the source code. The trickiest part was to make the effect "add" to the smear, rather than just to re-apply a new smear factor. I accomplished this by using the SUBTRACT and ADD blend modes.

This movie requires Flash Player 9

 
package com.agstrout.smear {
 
 import flash.display.MovieClip;
 
 import flash.display.BitmapData;
 
 import flash.display.Bitmap;
 
 import flash.filters.DisplacementMapFilter;
 
 import flash.display.Loader;
 
 import flash.events.Event;
 
 import flash.net.URLRequest;
 
 import flash.geom.Rectangle;
 
 import flash.display.BitmapDataChannel;
 
 import flash.geom.Point;
 
 import flash.display.Graphics;
 
 import flash.events.MouseEvent;
 
 import flash.display.BlendMode;	/**
 
  * com.agstrout.smear.Smear
 
  * @author Arne G Strout
 
  * Created : May 15, 2009
 
  * Re-creates the Smear tool effect from Photoshop using DistortionMapFilter
 
  */
 
 public class Smear extends MovieClip {
 
 	public var hit:MovieClip; // Click button
 
 	public var holder:Bitmap; // Result Bitmap Holder
 
 	public var bmp:BitmapData; // The source bitmap
 
 	public var output:BitmapData; // The result bitmap
 
 	public var distort:BitmapData; // The distortion map
 
 	public var filter:DisplacementMapFilter; // The distortion map filter
 
 	public var loader: Loader; // loader to load the image to be modified
 
private var _lx:Number; // The last mouse X position
 
 	private var _ly:Number; // The last mouse Y position
 
private static const MY_URL : String = "http://www.agstrout.com/images/image.jpg"; // Image to load
 
 	private var paint : MovieClip; // Paint layer
 
/**
 
 	 * Smear Constructor
 
 	 */
 
 	public function Smear() {
 
 		paint=new MovieClip(); // creates the painting layer
 
 		loader=new Loader(); // creates the loader
 
 		loader.contentLoaderInfo.addEventListener(Event.COMPLETE,_onImageLoaded); // loader listener
 
 		loader.load(new URLRequest(MY_URL)); // Load the constant URL
 
 	}
 
/**
 
 	 * Image Loaded handler
 
 	 */
 
 	private function _onImageLoaded(event : Event) : void {
 
 		// Create the output area and source
 
 		holder=new Bitmap();
 
 		bmp=Bitmap(loader.content).bitmapData; // Use the loaded Bitmap (JPG, PNG, or GIF) for the source BitmapData
 
 		var r:Rectangle=bmp.rect;// the size of the source bitmap
 
 		distort=new BitmapData(r.width,r.height,false,_argb(256,128,128,128)); // Make the distortion map the same size with 128 in the X/Y (R/B) registers on all pixels
 
 		output=bmp.clone(); // Copy the source for the output
 
 		holder.bitmapData=output; // assign the output bitmapdata to the holder
 
 		addChild(holder); // Add the holder to the stage
 
// Filter
 
 		// Use RED / BLUE registers for X/Y displacement, and 100 amplification for a nice effect, clamp so the edges are solid.
 
 		filter=new DisplacementMapFilter(distort,null,BitmapDataChannel.RED,BitmapDataChannel.BLUE,100,100,"clamp");
 
// Create the click button
 
 		hit=new MovieClip();
 
 		var g:Graphics=hit.graphics;
 
 		g.beginFill(0x000000,0); // transparent square
 
 		g.drawRect(0, 0, r.width, r.height); // same size as the source bitmapdata
 
 		g.endFill();
 
 		addChild(hit);
 
 		hit.addEventListener(MouseEvent.MOUSE_DOWN,_onMouseDown); // PRESS
 
 		stage.addEventListener(MouseEvent.MOUSE_UP,_onMouseUp); // RELEASE
 
_update(); // UPDATE
 
 	}
 
// ON MOUSE DOWN, set the lx/ly
 
 	private function _onMouseDown(event : MouseEvent) : void {
 
 		stage.addEventListener(MouseEvent.MOUSE_MOVE,_onMouseMove);
 
 		_lx=mouseX;
 
 		_ly=mouseY;
 
 	}
 
//
 
 	private function _onMouseMove(event : MouseEvent) : void {
 
 		var dx:Number=mouseX-_lx; // diff x
 
 		var dy:Number=mouseY-_ly; // diff y
 
 		var col:Number;
 
 		var mc:MovieClip=paint;
 
 		var g:Graphics=mc.graphics;
 
 		g.clear();
 
 		var i:int;
 
 		// red
 
 		for(i=0;i&lt;128;i+=4){
 
 			col=_argb(256-i*2,Math.floor(Math.abs(dx)),0,0);
 
 			g.lineStyle(64*(1-i/128),col,1,false,"normal");
 
 			g.moveTo(_lx,_ly);
 
 			g.lineTo(mouseX,mouseY);
 
 		}
 
 		if(dx&gt;0)distort.draw(mc,null,null,BlendMode.SUBTRACT);
 
 		if(dx&lt;0)distort.draw(mc,null,null,BlendMode.ADD);
 
// blue
 
 		g.clear();
 
 		for(i=0;i&lt;128;i+=4){
 
 			col=_argb(256-i*2,0,0,Math.floor(Math.abs(dy)));
 
 			g.lineStyle(64*(1-i/128),col,1,false,"normal");
 
 			g.moveTo(_lx,_ly);
 
 			g.lineTo(mouseX,mouseY);
 
 		}
 
 		if(dy&gt;0)distort.draw(mc,null,null,BlendMode.SUBTRACT);
 
 		if(dy&lt;0)distort.draw(mc,null,null,BlendMode.ADD);
 
_lx=mouseX;
 
 		_ly=mouseY;
 
 		_update();
 
 	}
 
private function _onMouseUp(event : MouseEvent) : void {
 
 		stage.removeEventListener(MouseEvent.MOUSE_MOVE,_onMouseMove);
 
 	}
 
private function _update() : void {
 
 		output.applyFilter(bmp, bmp.rect,new Point(0,0), filter);
 
 	}
 
private function _argb(a:uint,r:uint,g:uint,b:uint):uint{
 
 		return (a&lt;&lt;24 | r&lt;&lt;16 | g&lt;&lt;8 | b); // Create a color value from a,r,g,b data
 
 	}
 
 }
 
}
May 11

I was contacted by a colleague of mine  from a previous employer who asked if I still had the source code for an effect I had created for one of our projects. The effect was built to mimic the look of pouring paint onto glass which is being sprayed by a high pressure air nozzle. This effect is a simple use of math combined with a displacement map filter. I've got a few ideas how this could be made more interesting, such as adding a "spin" to the air by altering the angle just slightly on each pixel using the distance to set the amount.

This movie requires Flash Player 9

SOURCE FILE:

http://www.agstrout.com/files/Spreader.as

SOURCE CODE:

 
package com.agstrout.spread {
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.filters.DisplacementMapFilter;
import flash.geom.Point;
import flash.events.Event;
import flash.display.BitmapDataChannel;
import flash.display.Graphics;
import flash.utils.setInterval;
/**
* com.agstrout.spread.Spreader&lt;br/&gt;
* @author Arne G Strout
* Created : May 11, 2009&lt;br/&gt;
* A paint spreading effect which simulates paing being poored onto glass with a high pressure air hose applied to the glass.
*/
public class Spreader extends MovieClip {
public static const EFFECT_WIDTH:Number=320; // Movie Width
public static const EFFECT_HEIGHT:Number=240; // Movie Height
public static const EFFECT_FORCE:Number=.4; // Force of the "wind"
public var bmp:Bitmap; // The bitmap container for display
public var lmouseX:Number; // last mouse x , for line drawing
public var lmouseY:Number; // last mouse y , for line drawing
private var _bd:BitmapData; // the bitmap data the effect will be applied to
private var _filterbd:BitmapData; // the filter data for the effect
private var _f:DisplacementMapFilter; // the actual filter
private var _paint:MovieClip; // paint layer for drawing paint strokes to _bd
private var _col:Number; // the current paint color
 
/**
* constructor
*/
public function Spreader() {
_paint=new MovieClip(); // This MC will be used for the paint line drawing
 
// sets initial values for the "last mouse X" and "last mouse Y" values
lmouseX=mouseX;
lmouseY=mouseY;
 
// Create the bitmaps, with the effect W/H constants
bmp=new Bitmap();
_bd=new BitmapData(EFFECT_WIDTH,EFFECT_HEIGHT,true,0x00000000);
_filterbd=new BitmapData(EFFECT_WIDTH,EFFECT_HEIGHT,true,0x00000000);
 
// Creates the filter bitmap, using math to determine the angle to store for each pixel.
for(var i:uint=0;i&lt;EFFECT_WIDTH;i++)
for(var u:uint=0;u&lt;EFFECT_HEIGHT;u++){
var deltaX:Number=EFFECT_WIDTH/2-i; // The distance on the X axis between the center and this pixel
var deltaY:Number=EFFECT_HEIGHT/2-u; // The distance on the Y axist between the center and this pixel
var angle:Number=Math.atan2(deltaX,-deltaY); // angle in radians from the center to this pixel
var d:Number=Math.sqrt(deltaX*deltaX+deltaY*deltaY); // distance in pixels from the center
var dx:uint=Math.sin(angle)*(128-d/3)+128; // displacement (0 to 256) on the X axis, 128 for none
var dy:uint=-Math.cos(angle)*(128-d/3)+128; // displacement (0 to 256) on the Y axis, 128 for none
_filterbd.setPixel32(i,u,_argb(1,dx,dy,1)); // set the pixel value, using the _argb method to convert displacements to a color value
}
 
// Create the displacement map using the red and green channels and the EFFECT_FORCE constant
_f=new DisplacementMapFilter(_filterbd,new Point(0,0),BitmapDataChannel.RED,BitmapDataChannel.GREEN,EFFECT_FORCE,EFFECT_FORCE,"clamp");
addEventListener(Event.ENTER_FRAME,_onFrame); // apply the displacement map once per frame
setInterval(_shift,1000); // change paint color on a 1 sec interval
bmp.bitmapData=_bd; // Add the bitmapdata to the Bitmap container for display
addChild(bmp); // add the container to the stage.
_shift(); // set the initial color
}
 
/**
* Changes the paint color
*/
private function _shift() : void {
_col=_argb(256,                // A
128+Math.random()*128,    // R
128+Math.random()*128,    // G
128+Math.random()*128    // B
); // random color, but brighter than half luminance
}
 
private function _onFrame(event : Event) : void {
_bd.applyFilter(_bd,_bd.rect,new Point(0,0),_f); // Applies the "wind" effect
var g:Graphics=_paint.graphics; // gets the graphics context to draw the lines
g.clear(); // clears previous lines
g.moveTo(mouseX+(mouseX==lmouseX &amp;&amp; mouseY==lmouseY?2:0),mouseY); // sets start point of stroke at current X/Y pos (shift two pixels if no movement
g.lineStyle(16,_col);// sets the current color and brush size
g.lineTo(lmouseX,lmouseY); // draws the stroke to the previous X/Y pos
_bd.draw(_paint); // draws the paint layer onto the effect bitmap
lmouseX=mouseX; // record current X/Y pos for next frame
lmouseY=mouseY;
}
 
private function _argb(a:uint,r:uint,g:uint,b:uint):uint{
return (a&lt;&lt;24 | r&lt;&lt;16 | g&lt;&lt;8 | b); // Create a color value from a,r,g,b data
}
}
}
May 07

There's a tactic that I've been using successfully since AS2, which I find to be an excellent way of handling data communication.
The event driven model which is used in most programming frameworks is a bit heavy for everyday use in lighter applications, and I assume that's why Flex introduced data binding, but even data binding is a bit unwieldy and is only available in Flex.

My approach borrows from a few years of trying different strategies to create a useful mechanism for handling the communication of updates on the Model out to the many views/controllers that use it.

When implemented you can do something as simple as:

FeedMe.instance.subscribe(FEED_KEY,_onFeedKeyUpdate);
// and then later in the code
private function _onFeedKeyUpdate($data:*):void{
// Handle the update to the data feed
}

The feed key here could represent the currently selected character type in a video game, or the mouse state, just about anything really. The nice thing is that many multiple outlying classes can subscribe for updates every time, request in order to get the current value once (or be notified the first time a value is available), or "get" in order to check the existing value for that field.

In combination with Variable Objects especially this approach becomes very powerful.

For more information, see the project, now newly named FeedMe_AS3 on Google Code:

May 06

I've been pondering it and I really thing PHPBB and many other systems should start using Flash in their Captcha implementation.
One great example would be to require the user to perform some simple action within a flash environment, such as dragging a golf ball into a hole. Pretty much anything that a spambot would not be able to do. This would be MUCH less annoying than the current captcha methods, and what with Flash becoming so ubiquitous you'd only really be risking losing users who exclusively use their iPhone to register on forums, cuz that happens so often :).

Thoughts?

May 06

So, I just spent about an hour cleaning spam out of my PHPBB3 install on www.stroutsink.com.

Apparently the Captcha on PHPBB 3.0.4 (the code that creates those annoying images on registration pages) was cracked recently.

As a result I had ~1700  spammer accounts created in a week. At first I was deleting them one by one, but then just switched over to the more logical approach and used SQL to delete all users created after the first spammers showed up (sorry if anyone REAL got caught up in there!)

The next step was to install a random image mod which adds a random image behind the captcha text and those images can be customized. I'm using the defaults right now, but will swap them out as soon as I see that they are no longer working.

Cheers!

-Arne

May 06

I just finished a redesign on the homepage for www.agstrout.com as well as an update to www.stroutsink.com which will add some much needed positive space to the sites. The previous sites were rather cluttered looking and especially on www.stroutsink.com the scrolling wasn't working out for the games and photos. Splitting the photos onto their own page and giving the games list two rows has helped alot. Also, April created some great new button art for the games list. I especially like the Chompy The Great, Chompy's Winter Rescue, and Connect-A-Mals buttons.

Cheers All!

Let me know what you think of the new designs. Any ideas for further improvements?