TGB/Behaviors/Snap to Grid

From TDN

Behaviour:



if (!isObject(SnapToGridBehaviour)) {
   %template = new BehaviorTemplate(SnapToGridBehaviour);
   
   %template.friendlyName = "Snap to Tile";
   %template.behaviorType = "GUI";
   %template.description  = "Snap this object to specified tilemap";

   %template.addBehaviorField(tileName, "The tilemap object to snap this object to", object, "", t2dSceneObject);
}

$heldObject = 0;

function SnapToGridBehaviour::onBehaviorAdd(%this) {
   %this.owner.setUseMouseEvents(true);
}

function SnapToGridBehaviour::onMouseDown(%this, %modifier, %worldPos) {
		$heldObject = %this.owner;
		$heldObject.setPosition(%worldPos);
		$tileName = %this.tileName;
}


//SNAP OBJECT TO TILE POSITION
function snapToTile(%obj,%tilepos) {
	%tilex = getWord(%tilepos,0);
	%tiley = getWord(%tilepos,1);
	%tilewp = getTileWorldPosition(%tilex, %tiley);
	%obj.setPosition(%tilewp);
}

//GET WORLD POSITION FROM TILE CO-ORDINATES  (function taken from aStarDemo code)
function getTileWorldPosition(%tileXPosition, %tileYPosition) {
   // determine if we were passed a word-list or x/y coords
   
   %tileLayer = $tileName;

   if(getWordCount(%tileXPosition) > 1)
   {
      %tilex = getWord(%tileXPosition, 0);
      %tiley = getWord(%tileXPosition, 1);
   }
   else
   {
      %tilex = %tileXPosition;
      %tiley = %tileYPosition;
   }

   // %buff just stores stuff real quick -- I like 'getSize' over 'getSizeX', personal preference
   %buff = %tileLayer.getTileSize();
   %tsx = getWord(%buff, 0);
   %tsy = getWord(%buff, 1);
   
   %buff = %tileLayer.getTileCount();
   %tcx = getWord(%buff, 0);
   %tcy = getWord(%buff, 1);
   
   %p = %tileLayer.getPosition();
   %px = getWord(%p, 0);
   %py = getWord(%p, 1);
   
   // get the top-left
   %tlx = -(((%tcx * %tsx) / 2) + (%tsx / 2));
   %tly = -(((%tcy * %tsy) / 2) + (%tsy / 2));
   
   // determine tile world position
   %wx = %px + (%tlx + (%tsx * (%tilex++)));
   %wy = %py + (%tly + (%tsy * (%tiley++)));
   return %wx SPC %wy;
}

Scene Mouse Events:

function SceneWindow2D::onMouseDragged( %this, %modifier, %worldPos ) {
  if( $heldObject == 0 ) return;
	%x = getWord(%worldPos, 0);
	%y = getWord(%worldPos, 1);
    %tilePos = $tileName.pickTile(%x,%y);
    snapToTile($heldObject, %tilePos);
}

function SceneWindow2D::onMouseUp( %this, %modifier, %worldPos ) {
  if( $heldObject == 0 ) return;
	%x = getWord(%worldPos, 0);
	%y = getWord(%worldPos, 1);
	%tilePos = $tileName.pickTile(%x,%y);
	snapToTile($heldObject, %tilePos);
	$heldObject = 0;
}