Monday, November 8, 2010

Actionscript 3 RTS game tutorial - part 4

Today we will start making the selection field.

Check this out to see what I mean - hold mouse, hold ctrl and move your mouse around. This does not select anything yet, but it will later. Our goal right now is to create this field.


Firstly, the green field you see is a movieclip that is being scaled around. So create a MovieClip, place it on stage and name it selectRect. Make sure the registration point is top left corner - aka the rectangle's coordinates inside the MC are 0:0. The size of the rectangle inside the MC doesn't matter.

Now, here's the full commented code. The part you're looking for is in the last part of the code.

// We turn all the code that handles movement and behavior of one unit
// into a function, through which we can apply the same code to
// multiple units.
function addUnit(mc):void
{
var iswalking = false;
var movespeed = 5;
var dir = "down";
var goX;
var goY;
// the selectedUnit variable is toggled when the unit is being clicked
var selectedUnit = false;

stage.addEventListener(Event.ENTER_FRAME, loop);

function loop(Event)
{
if (iswalking == true)
{
mc.w.play();
}
else
{
mc.w.gotoAndStop(1);
}

mc.gotoAndStop(dir);
if ((goY-movespeed*2)>mc.y)
{
mc.y +=  movespeed;
dir = "down";
}
else if ((goY+movespeed*2)<mc.y)
{
mc.y -=  movespeed;
dir = "up";
}
if ((goX-movespeed*2)>mc.x)
{
mc.x +=  movespeed;
dir = "right";
}
else if ((goX+movespeed*2)<mc.x)
{
mc.x -=  movespeed;
dir = "left";
}

if ((goY-movespeed*2)>mc.y || (goY+movespeed*2)<mc.y || (goX-movespeed*2)>mc.x || (goX+movespeed*2)<mc.x)
{
iswalking = true;
}
else
{
iswalking = false;
}

// Check for space key (deselect)
if (isSpace)
{
selectedUnit = false;
mc.selectedGfx.gotoAndStop(1);
}
}

// When we click the unit, toggle the selectUnit variable

mc.selectArea.addEventListener(MouseEvent.CLICK, select);

function select(MouseEvent):void
{
if (selectedUnit == true)
{
selectedUnit = false;
// mc.selectedGfx is a movieclip with a green border graphic
// it is visible on frame 2 and invisible on frame 1
mc.selectedGfx.gotoAndStop(1);
totalSelected--;
}
else
{
selectedUnit = true;
mc.selectedGfx.gotoAndStop(2);
totalSelected++;
}
}

// When we click the stage area, move there

stage.addEventListener(MouseEvent.CLICK, setposition);

function setposition(evt:MouseEvent):void
{
// The conditional checks if we click stage (not a unit) and set the position
// of the move marker

if (evt.target == stage && selectedUnit == true)
{
goX = mouseX;
goY = mouseY;
}

// Now we check if we clicked on a unit, but not this one. If we did it without holding
// CTRL, then this unit should be deselected.
// We use the selectArea movieclip (which is invisible) located in each unit to trace clicking

for (var l:int=0; l<units.length; l++)
{
if (evt.target == units[l].selectArea && evt.target != mc.selectArea && isCtrl == false && selectedUnit)
{
selectedUnit = false;
mc.selectedGfx.gotoAndStop(1);
totalSelected--;
}
}

}
}

// All units are stored in an array
// char, char2 and char3 - instance names of unit mcs on stage

var units:Array = [char,char2,char3];

for (var i:int=0; i<units.length; i++)
{
addUnit(units[i]);
}

// Here we manage depths

stage.addEventListener(Event.ENTER_FRAME, depthManager);

function depthManager(Event):void
{
// Two loops for two objects (object one hits object 2)
for (var v:int=0; v<units.length; v++)
{
for (var o:int=0; o<units.length; o++)
{
// First we check if object1 and object2 aren't the same unit
// Then we check if they collide
if (v != o && units[v].hitTestObject(units[o]))
{
// Swap depths if needed
if (getChildIndex(units[v]) > getChildIndex(units[o]) && units[v].y < units[o].y)
{
swapChildren(units[v], units[o]);
}
if (getChildIndex(units[v]) < getChildIndex(units[o]) && units[v].y > units[o].y)
{
swapChildren(units[v], units[o]);
}
}
}
}
}

// Creating a keyboard manager

stage.addEventListener(KeyboardEvent.KEY_DOWN, kDown);
stage.addEventListener(KeyboardEvent.KEY_UP, kUp);

var isCtrl:Boolean = false;
var isSpace:Boolean = false;
msgText.text = "Hold CTRL to select multiple units. Space to deselect all.";

function kDown(evt:KeyboardEvent):void
{
if (evt.keyCode == 17)
{
isCtrl = true;
msgText.text = "Multiple unit select";
}
if (evt.keyCode == 32)
{
isSpace = true;
msgText.text = "Deselected all";
totalSelected = 0;
}
}

function kUp(evt:KeyboardEvent):void
{
if (evt.keyCode == 17)
{
isCtrl = false;
msgText.text = "Single unit select";
}
if (evt.keyCode == 32)
{
isSpace = false;
}
}

// Selection checker

var totalSelected:Number = 0;

stage.addEventListener(Event.ENTER_FRAME, selectionChecker);

function selectionChecker(Event):void
{
// When no units are selected, totalSelected is set to 0.
// Once a unit is clicked, this number increases by 1 and decreases when unselected.
// This var is changed through the addUnit() function and also Space key event.
msgText2.text = "Total units selected: " + totalSelected.toString();
}

// Mouse holding rectangle selection managment:

var selectStartPosX:Number;
var selectStartPosY:Number;
var selectingRectNow:Boolean = false;

// What happens when we release mouse

stage.addEventListener(MouseEvent.MOUSE_UP, selectRectangleOff);

function selectRectangleOff(MouseEvent):void
{
selectingRectNow = false;
selectRect.width = 0;
selectRect.height = 0;
}

// What happens when we press mouse

stage.addEventListener(MouseEvent.MOUSE_DOWN, selectRectangleOn);

function selectRectangleOn(MouseEvent):void
{
if (isCtrl)
{
selectRect.x = mouseX;
selectRect.y = mouseY;
selectRect.width = 0;
selectRect.height = 0;
selectingRectNow = true;
selectStartPosX = stage.mouseX;
selectStartPosY = stage.mouseY;
}
}

// What happens when we hold and move our mouse

stage.addEventListener(MouseEvent.MOUSE_MOVE, selectRectangleScale);

function selectRectangleScale(MouseEvent):void
{
if (selectingRectNow)
{
// There are many if's here to manage correct display of the selection field
// It all depends in which direction are you dragging the selection
if (selectStartPosX <= mouseX && selectStartPosY <= mouseY)
{
selectRect.width = mouseX - selectStartPosX;
selectRect.height = mouseY - selectStartPosY;
}
else if (selectStartPosX>mouseX && selectStartPosY<=mouseY)
{
selectRect.width = selectStartPosX - mouseX;
selectRect.x = mouseX;
selectRect.height = mouseY - selectStartPosY;
}
else if (selectStartPosX>mouseX && selectStartPosY>mouseY)
{
selectRect.width = selectStartPosX - mouseX;
selectRect.x = mouseX;
selectRect.y = mouseY;
selectRect.height = selectStartPosY - mouseY;
}
else if (selectStartPosX<mouseX && selectStartPosY>mouseY)
{
selectRect.width = mouseX - selectStartPosX;
selectRect.y = mouseY;
selectRect.height = selectStartPosY - mouseY;
}
}
}

Thanks for reading!

Related:

Actionscript 3 RTS game tutorial part 1
Actionscript 3 RTS game tutorial part 2
Actionscript 3 RTS game tutorial part 3
Actionscript 3 RTS game tutorial part 5

No comments:

Post a Comment