Reputation: 536
Hi everyone I hope I asked the correct question. So Basically I have a Movie Clip named mcLiquidWaste
that I add to the stage. There are 3 different positions on the stage that they come out of. In my main engine class I have a for loop set up that controls how many come out at a time like so:
private function addLiquidWaste():void
{
//Duplicate Tween for repeat
TweenLite.delayedCall(randomNumber(nDifficulty1, nDifficulty2), addLiquidWaste);
//determine how many come out at a time
numberOfLiquids = randomNumber(1, 3);
//iterate through for loop
for (var i = 0; i < numberOfLiquids; i++)
{
//Instantiate liquid
var liquid:mcLiquidWaste = new mcLiquidWaste();
//Add liquid to stage
stage.addChild(liquid);
//push liquid MC into array
aLiquidArray.push(liquid);
}
}
The issue I am having is that sometimes when they come out they overlap each other for instance say 3 come out at the same time well 2 of those might come out in the same position which I dont want. I want to somehow process that if they come out in the same position and not in a different slot on the stage then have them removed or have the overlapping movie clip go to a different position. That is why I was thinking of checking if 2 of the objects in the array are touching then remove those somehow.
Here is what my mcLiquidWaste
class looks like and how they are added to the stage in different positions.
private function init():void
{
nSpeed = 4;
var liquidPosition:Number = randomNumber(1, 3);
if (liquidPosition == 1) //Position Lava to the Left Hole
{
this.y = (stage.stageHeight / 2) - 200;
this.x = (stage.stageWidth / 2) - 150;
}
if (liquidPosition == 2) //Position Lava to the Middle Hole
{
this.y = (stage.stageHeight / 2) - 200;
this.x = (stage.stageWidth / 2) ;
}
if (liquidPosition == 3) //Position Lava to the Right Hole
{
this.y = (stage.stageHeight / 2) - 200;
this.x = (stage.stageWidth / 2) + 150;
}
addEventListener(Event.ENTER_FRAME, liquidHandler);
}
as you can see in my liquid waste class they are added to the left, middle, and right of the stage. Please ANY help would be appreciated thank you!
How I managed to fix it
for (var a:int = 0; a < aLiquidArray.length - 1; a++)
{
var l1:mcLiquidWaste = aLiquidArray[a];
for (var j:int = a + 1; j < aLiquidArray.length; j++)
{
var l2:mcLiquidWaste = aLiquidArray[j];
if (l1.hitTestObject(l2))
{
//do something on collision
l2.destroyLiquid();
}
}
}
Upvotes: 1
Views: 182
Reputation: 5255
The whole "try until something works" approach is not ideal. In theory, the code could run forever, but that's not very probable.
The core problem is that you give up on the deterministic behaviour of the program.
or have the overlapping movie clip go to a different position.
You have this code that makes it equally likely to spawn at either of the 3 positions:
var liquidPosition:Number = randomNumber(1, 3);
if (liquidPosition == 1) //Position Lava to the Left Hole
{
Now if you go in after the fact and change the position, this code becomes meaningless.
Let's say you have a non-equal distribution. Say for example, on the super-extreme difficulty, the mcLiquidWaste
is spawned mostly in the position that's closest to the player. So they have a shorter distance to get to the player, which would make it more difficult. Now you don't want to change the position.
I would not recommend changing the position after it is determined. It's better to spawn the mcLiquidWaste
in a way that they cannot overlap.
Here is what my
mcLiquidWaste
class looks like and how they are added to the stage in different positions.private function init():void { nSpeed = 4; var liquidPosition:Number = randomNumber(1, 3); if (liquidPosition == 1) //Position Lava to the Left Hole { this.y = (stage.stageHeight / 2) - 200; this.x = (stage.stageWidth / 2) - 150; } //etc...
The fact that each individual object determines its position on its own is the problem. The objects don't know each other. And they shouldn't know each other either.
The positioning of the objects should happen in the class that knows all the objects.
Place the objects in a pattern, so that they cannot overlap. One example is to put them all on a circle that's big enough so that they don't overlap.
Here's an example class:
package
{
public class SpawnPoint
{
private var _position:Point;
public SpawnPoint(position:Point)
{
_position = position;
}
public spawn (amount:uint):Array
{
var waste:mcLiquidWaste;
var wastes:Array = [];
// the trivial case of 1, spawn at the position
if(amount == 1)
{
waste = new mcLiquidWaste();
waste.x = _position.x;
waste.y = _position.y;
wastes.push(waste);
return wastes;
}
// if there are more than 1, distribute them on a circle around position
/* the radius depends on the size of mcLiquidWaste (and the amount)
you have to either play around with that value or determine it
from the size dynamically
*/
var radius:Number = 25;
/* the angle depends on the number of mcLiquidWaste
you have to either play around with that value or determine it
from the size dynamically
*/
var angle:Number = 2 * Math.PI / amount;
for (var i = 0; i < amount; i++)
{
waste = new mcLiquidWaste();
var posititionOnCircle:Point = Point.polar(radius, i * angle).add(_position);
waste.x = posititionOnCircle.x;
waste.y = posititionOnCircle.y;
wastes.push(waste);
}
return wastes;
}
}
}
This won't compile, but you get the idea: use a radius
and an angle
to create positions that lie on a circle. The usage would look something like this:
//create spawn point
var leftHole:SpawnPoint = new SpawnPoint(new Point((stage.stageWidth / 2) - 150, (stage.stageHeight / 2) - 200));
// creation of objects
var spawnedObjects:Array = leftHole.spawn(4);
// adding to display list
for (var i:uint = 0; i < spawnedObjects.length; ++i)
{
addChild(spawnedObjects[i]);
}
Upvotes: 2