PDA

View Full Version : [AS3] code for "laser beam"


quicksmack
09-30-2009, 01:10 AM
the code below is basically a code i created for a turret on stage that fires a "laser beam".
if the "laser beam" hits a wall / object / obstacle, it will stop right there and no longer progress...
it works great, except for one thing...

var radians:Number;
var begX:Number;
var begY:Number;
var endX:Number;
var endY:Number;
var maxDist:Number = 500;

var laserIsOn:Boolean = false;

stage.addEventListener(Event.ENTER_FRAME, runEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, fireGun);
stage.addEventListener(MouseEvent.MOUSE_UP, stopGun);

function runEnterFrame(event:Event):void
{
radians = Math.atan2(mouseY - turret.y, mouseX - turret.x);
var degrees:Number = radians * 180 / Math.PI;
turret.barrel.rotation = degrees;

if(laserIsOn)
{
while(laserEmptyMC.numChildren)
{
laserEmptyMC.removeChildAt(0);
}

var ld:Sprite = new Sprite();

ld.graphics.lineStyle(1, 0xFF0000);

// determine start point for laser
begX = Math.cos(radians) * 61 + turret.x;
begY = Math.sin(radians) * 61 + turret.y;

ld.graphics.moveTo(begX, begY);

// determine end point for laser
for(var i:Number = 0; i < maxDist; i++)
{
endX = Math.cos(radians) * i + turret.x;
endY = Math.sin(radians) * i + turret.y;

if(wallsMC.getChildAt(4).hitTestPoint(endX, endY))
{
break;
}
if(wallsMC.getChildAt(3).hitTestPoint(endX, endY))
{
break;
}
if(wallsMC.getChildAt(2).hitTestPoint(endX, endY))
{
break;
}
if(wallsMC.getChildAt(1).hitTestPoint(endX, endY))
{
break;
}
if(wallsMC.getChildAt(0).hitTestPoint(endX, endY))
{
break;
}
}

ld.graphics.lineTo(endX, endY);

laserEmptyMC.addChild(ld);
}

}

function fireGun(event:MouseEvent):void
{
laserIsOn = true;
}

function stopGun(event:MouseEvent):void
{
while(laserEmptyMC.numChildren)
{
laserEmptyMC.removeChildAt(0);
}

laserIsOn = false;
}

the code works great.. however, i'm trying to replace all those repetitive "if" statements into a simple "for loop".. but i'm not getting the same result..

this is the code with the "for loop" version...
var radians:Number;
var begX:Number;
var begY:Number;
var endX:Number;
var endY:Number;
var maxDist:Number = 500;

var laserIsOn:Boolean = false;

stage.addEventListener(Event.ENTER_FRAME, runEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, fireGun);
stage.addEventListener(MouseEvent.MOUSE_UP, stopGun);

function runEnterFrame(event:Event):void
{
radians = Math.atan2(mouseY - turret.y, mouseX - turret.x);
var degrees:Number = radians * 180 / Math.PI;
turret.barrel.rotation = degrees;

if(laserIsOn)
{
while(laserEmptyMC.numChildren)
{
laserEmptyMC.removeChildAt(0);
}

var ld:Sprite = new Sprite();

ld.graphics.lineStyle(1, 0xFF0000);

// determine start point for laser
begX = Math.cos(radians) * 61 + turret.x;
begY = Math.sin(radians) * 61 + turret.y;

ld.graphics.moveTo(begX, begY);

// determine end point for laser
for(var i:Number = 0; i < maxDist; i++)
{
endX = Math.cos(radians) * i + turret.x;
endY = Math.sin(radians) * i + turret.y;

for(var j:Number = 0; j < (wallsMC.numChildren - 1); j++)
{
if(wallsMC.getChildAt(j).hitTestPoint(endX, endY))
{
break;
}
}
}

ld.graphics.lineTo(endX, endY);

laserEmptyMC.addChild(ld);
}

}

function fireGun(event:MouseEvent):void
{
laserIsOn = true;
}

function stopGun(event:MouseEvent):void
{
while(laserEmptyMC.numChildren)
{
laserEmptyMC.removeChildAt(0);
}

laserIsOn = false;
}

so what the hell am i doing wrong and what is the right way of doing this?

Mazoonist
09-30-2009, 02:09 AM
If it matters, in your previous code you were checking your hitTests in reverse order: 4, 3, 2, 1, 0. Your for loop, though, as you have it now, will be going in the order 0, 1, 2, 3, 4. To make the for loop do the exact same thing your previous code did, you need to make it count down instead of up:
for (var j:Number = (wallsMC.numChildren - 1); j >=0 ; j--)
{
if (wallsMC.getChildAt(j).hitTestPoint(endX,endY))
{
break;
}
}

quicksmack
09-30-2009, 02:38 AM
thanks for the reply..
yes it is in reverse, but that wasn't the problem..
i solved it by adding a boolean.. it seems that the "break" command was just "breaking" the "for loop" it was in and not the actual "for loop" it is nested in...
did that even make sense??:)

anyway, here's the resulting code:
var radians:Number;
var begX:Number;
var begY:Number;
var endX:Number;
var endY:Number;
var stopLaser:Boolean = false;
var maxDist:Number = 500;

var laserIsOn:Boolean = false;

stage.addEventListener(Event.ENTER_FRAME, runEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, fireGun);
stage.addEventListener(MouseEvent.MOUSE_UP, stopGun);

function runEnterFrame(event:Event):void
{
radians = Math.atan2(mouseY - turret.y, mouseX - turret.x);
var degrees:Number = radians * 180 / Math.PI;
turret.barrel.rotation = degrees;

if(laserIsOn)
{
while(laserEmptyMC.numChildren)
{
laserEmptyMC.removeChildAt(0);
}

var ld:Sprite = new Sprite();

ld.graphics.lineStyle(1, 0xFF0000);

// determine start point for laser
begX = Math.cos(radians) * 61 + turret.x;
begY = Math.sin(radians) * 61 + turret.y;

ld.graphics.moveTo(begX, begY);

// determine end point for laser
for(var i:Number = 0; i < maxDist; i++)
{
endX = Math.cos(radians) * i + turret.x;
endY = Math.sin(radians) * i + turret.y;

for(var j:Number = 0; j < wallsMC.numChildren; j++)
{
if(wallsMC.getChildAt(j).hitTestPoint(endX, endY))
{
stopLaser = true;
break;
}
}

if(stopLaser)
{
break;
}
}

stopLaser = false;
ld.graphics.lineTo(endX, endY);

laserEmptyMC.addChild(ld);
}

}

function fireGun(event:MouseEvent):void
{
laserIsOn = true;
}

function stopGun(event:MouseEvent):void
{
while(laserEmptyMC.numChildren)
{
laserEmptyMC.removeChildAt(0);
}

laserIsOn = false;
}