Feb 2 2012

Game Map

I have another preview for my newest game, it’s a small view of a single map. This isn’t an actual game map, but rather a mockup using actual art assets. This is, however, how an actual map will look when finished.


Feb 2 2012

Game Characters

It’s been awhile since I’ve updated last. The as3isolib tutorials were a primer for a game engine I have been writing. I won’t be releasing the engine here, at least not yet, but I will still be updating the progress of the game. The game is a strategy RPG in a tile based world. I just finished all of the character renders and animations. I currently have a few walk cycles to show and a preview of a few of the characters you’ll see. Below is the player character, the goblin boss, and troll.

                    


Jun 28 2010

Using as3isolib, Part 3

Next up in my as3isolib tutorials is drag and drop. I won’t be using drag and drop in my game, but it is such a common feature in isometric games that I’ve gone ahead and created an example for those who may need it. Lets get started. Below is the full class code.

package
{

	import as3isolib.core.ClassFactory;
	import as3isolib.display.IsoView;
	import as3isolib.display.primitive.IsoBox;
	import as3isolib.display.renderers.DefaultShadowRenderer;
	import as3isolib.display.scene.IsoGrid;
	import as3isolib.display.scene.IsoScene;
	import as3isolib.geom.Pt;
	import caurina.transitions.Tweener;
	import eDpLib.events.ProxyEvent;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.Point;

	public class IsoDragExample extends Sprite
	{

		private var _view:IsoView;
		private var _scene:IsoScene;
		private var _box:IsoBox;
		private var _grid:IsoGrid;
		private var _dragObject:IsoBox;
		private var _dragPt:Pt;
		private var _glow:GlowFilter;

		public function IsoDragExample():void
		{
			_view = new IsoView();
			_view.setSize( stage.stageWidth, stage.stageHeight );
			addChild( _view );

			_scene = new IsoScene();
			_scene.hostContainer = this;
			_scene.styleRenderers = [ new ClassFactory( DefaultShadowRenderer ) ];
			_view.addScene( _scene );

			_glow = new GlowFilter( 0xFF8000, 1, 6, 6, 64 );

			_box = new IsoBox
			_box.setSize( 50, 50, 50 );
			_box.addEventListener( MouseEvent.ROLL_OVER, onRollOverHandler, false, 0, true );
			_box.addEventListener( MouseEvent.ROLL_OUT, onRollOutHandler, false, 0, true );
			_box.addEventListener( MouseEvent.MOUSE_DOWN, onPickup, false, 0, true );
			_scene.addChild( _box );

			_grid = new IsoGrid();
			_grid.cellSize = 50;
			_scene.addChild( _grid );

			addEventListener( Event.ENTER_FRAME, onRender, false, 0, true );
		}

		private function onPickup( e:ProxyEvent ):void
		{
			_dragObject = e.target as IsoBox;
			_dragPt = _view.localToIso( new Point( stage.mouseX, stage.mouseY ) );
			_dragPt.x -= _dragObject.x;
			_dragPt.y -= _dragObject.y;

			_dragObject.removeEventListener( MouseEvent.MOUSE_DOWN, onPickup );

			_dragObject.addEventListener( MouseEvent.MOUSE_UP, onDrop, false, 0, true );
			stage.addEventListener( MouseEvent.MOUSE_UP, onDrop, false, 0, true );
			stage.addEventListener( MouseEvent.MOUSE_MOVE, onMoveObject, false, 0, true );

			Tweener.addTween( _dragObject, { z:25, time:0.5 } );
		}

		private function onDrop( e:Event ):void
		{
			_dragObject.removeEventListener( MouseEvent.MOUSE_UP, onDrop );
			stage.removeEventListener( MouseEvent.MOUSE_UP, onDrop );
			stage.removeEventListener( MouseEvent.MOUSE_MOVE, onMoveObject );

			_dragObject.addEventListener( MouseEvent.MOUSE_DOWN, onPickup, false, 0, true );

			Tweener.addTween( _dragObject, { z:0, time:0.5 } );
		}

		private function onMoveObject( e:MouseEvent ):void
		{
			var pt:Pt = _view.localToIso( new Point( stage.mouseX, stage.mouseY ) );

			_dragObject.moveTo( pt.x - _dragPt.x, pt.y - _dragPt.y, _dragObject.z );
		}

		private function onRollOverHandler( e:ProxyEvent ):void
		{
			( e.target as IsoBox ).container.filters = [ _glow ];
		}

		private function onRollOutHandler( e:ProxyEvent ):void
		{
			( e.target as IsoBox ).container.filters = [];
		}

		private function onRender( e:Event ):void
		{
			_scene.render();
		}

	}

}

In the constructor we do our normal setup for our view and scene. First thing you might notice is on line 38 we set a property called “styleRenderers” of the IsoScene. This is a built in feature of as3isolib that allows for certain styling elements to be drawn during render. In this case, as3isolib comes with a shadow renderer. This just draws squares at grid level for each object. I have this set because when we pick up objects, this allows you to see exactly where they are positioned in isometric space.

Next, at line 43, we create our box and we add some mouse event listeners. I have added ROLL_OVER and ROLL_OUT that triggers a glow on the box just so you can see the mouse interaction. Also, there is a listener for MOUSE_DOWN. This is the start of the dragging process which calls the method onPickup.

Line 57 is the onPickup method. Here we store a reference to the box object and on line 60 we track the current isometric point of the mouse. I use this value to calculate the space between the object and the mouse position. This is so when I drag the object around it maintains this distance instead of snapping directly to the mouse. Next I add some more listeners to track MOUSE_UP on both the object and the stage because it is entirely possible that the mouse will not be over the object when released. Finally, using Tweener, I animate the object up by 25 pixels. This is just to simulate physically pickup it up.

Jumping ahead to line 84, this is where the calculations happen to actually move the object around. First thing I do is grab the mouse’s new isometric point. Then, I move the object to that position, but I also remember to include the original distance between mouse and object.

Line 73, is where the object gets dropped. Here, I just remove old event listeners and add the previous ones. I also use Tweener to animate the box back to grid level.

NOTE: It is always good practice to remove event listeners when they are no longer needed and only add them when needed. You’ll notice that when an object is picked up I remove the MOUSE_DOWN event listener and add the MOUSE_UP and MOUSE_MOVE listeners. There are two reasons for this. First, I only care about the MOUSE_UP and MOUSE_MOVE events once the object is picked. There is no need to have those listeners there anytime before then. Second, having multiple listeners active when not needed can cause unexpected behavior.

That’s it. Now we have a box and we can drop it anywhere in the view. You’ll also notice that the box has a neat little shadow beneath it so you know when it is picked up. The current example lets you drag the box anywhere without restrictions. A tile based game might constrain the object to grid squares. In this case, you would need to do additional calculation so ensure the object is in the right place. That part is up to you though.

Cheers!