divillysausages.com

Colony tech update 1: Creating a game camera, part 7, selecting objects

The penultimate entry in this series is a short one, dealing simply with selecting different objects. Most games use selecting in one form or another, so how does this tie into the camera that we've been making?

The basic idea is that our CameraClickControls object registers some mouse listeners with the Stage. When we get a click, we pass it to the camera, which notifies all of the layers. I chose the pass the local click coordinates rather than the global stage coordinates, as they're more useful, but you can modify it as you see fit.

Working with the CameraMouseControls

There is a quick note to keep in mind when using the CameraClickControls with the CameraMouseControls class. As the latter controls the camera by dragging it around with the mouse, whenever you mouse up, it would trigger a CLICK event. To stop this registering with the CameraClickControls, we add an additional MOUSE_DOWN listener, that keeps track of the original click position. If the MOUSE_UP event is within X pixels of the MOUSE_DOWN event, we count it as a click, otherwise we ignore it.

Working with the GUI

If you have a GUI in your game, you obviously won't want to trigger the CameraClickControls when you click on a button. This is the same nature of problem as we saw with the CameraMouseEdgeControls class, and the solutions are roughly the same:

Picking or selecting

The actual code behind picking, or selecting your objects isn't covered here - it's an in-depth subject that would need it's own update, especially if we enter the realm of pixel-perfect picking. For the example below, I used a simple hitTestPoint(), but for a rough idea, depending on your rendering etc, you can:

The code

As always, make sure and add it to your update loop. You can also download it below. Keep scrolling for an example

package
{
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	/**
	 * Lets us select objects through the camera by clicking on them
	 * @author Damian Connolly
	 */
	public class CameraClickControls extends CameraControls 
	{
		
		/*******************************************************************************************/
		
		private var m_mouseDownPos:Point = null; // the point where we've moused down (for clicking)
		
		/*******************************************************************************************/
		
		/**
		 * Creates a new click controller for the camera
		 * @param camera The camera that this is for
		 * @param stage The main stage
		 */
		public function CameraClickControls( camera:Camera, stage:Stage ) 
		{
			super( camera, stage );
			this.m_mouseDownPos = new Point;
			
			// add our listeners for our click
			this.m_stage.addEventListener( MouseEvent.MOUSE_DOWN, this._onMouseDown );
			this.m_stage.addEventListener( MouseEvent.CLICK, this._onClick );
		}
		
		/**
		 * Destroys the CameraClickControls and clears it for garbage collection
		 */
		override public function destroy():void 
		{
			super.destroy();
			
			// remove our listeners for our click
			this.m_stage.removeEventListener( MouseEvent.MOUSE_DOWN, this._onMouseDown );
			this.m_stage.removeEventListener( MouseEvent.CLICK, this._onClick );
			
			// null our properties
			this.m_mouseDownPos = null;
		}
		
		/*******************************************************************************************/
		
		// called when we mouse down on the stage
		protected function _onMouseDown( e:MouseEvent ):void
		{
			// we can only click if we're active
			if ( this.active )
				this.m_mouseDownPos.setTo( e.stageX, e.stageY );
		}
		
		// called when we click on the stage - if we haven't moved much, then it's a click
		protected function _onClick( e:MouseEvent ):void
		{
			// if we're not active, then we can't click
			if ( !this.active )
				return;
				
			// check our dist and tell our camera, if it's good
			if ( MathHelper.dist( e.stageX, e.stageY, this.m_mouseDownPos.x, this.m_mouseDownPos.y ) < CameraControls.CLICK_DIST )
			{
				this.m_camera.onClick( e.stageX, e.stageY );
				return;
			}
		}
		
	}

}

Example

The click controller code in action; click on the stage to give it focus, then click to select/deselect the ships. Once a ship is selected, you can click again on the stage to move the ship there.

An example of clicking and the camera

Colony mailing list

Plug for the Colony mailing list:

* indicates required

Files

Comments

Submit a comment

* indicates required