AS3 - How can objects that appear randomly never touch each other? - actionscript-3

I have two objects that appear randomly on stage, but i want them to never touch each other when they appear.
object1.x = Math.random() * stage.stageWidth;
object1.y = Math.random() * stage.stageHeight;
object2.x = Math.random() * stage.stageWidth;
object2.y = Math.random() * stage.stageHeight;

As #DodgerThud has mentioned; the way to go about this problem is to repeatedly attempt to place the next object until it meets your criteria (not colliding with another object). This is a perfect example of what a while loop can be used for, something like:
while (!object1.hitTestObject(object2))
{
object1.x = Math.random() * stage.stageWidth;
object1.y = Math.random() * stage.stageHeight;
}

If you have only 2 objects that appears on the stage, then is easy. In EnterFrame event you just put an if condition
if(!obj1.hitTestObject(obj2)) {
obj1.x = Math.random() * stage.stageWidth;
obj1.y = Math.random() * stage.stageHeight;
}
but if you have many objects, then you have to loop through all the objects and check the same condition.
for(var i:int=0; i<yourObjNumber; i++) {
var hits:boolean = false;
if(!obj1.hitTestObject(getChildAt(i))) {
hits = true;
}
if(hits) {
obj1.x = Math.random() * stage.stageWidth;
obj1.y = Math.random() * stage.stageHeight;
}
}
Hope this helps!
Have a great day!

Related

AS3 animate dynamically created movie clips with ENTER_FRAME

I have some code which loads a movie clip from the library, reproduces it and spreads it around the stage in different sizes, positions and rotations. What I can't figure out is how to then animate each one with an ENTER_FRAME event listener - So maybe I can also animate the scale, position and rotations? Any help greatly appreciated. Thanks.
for (var i = 0; i < 20; i++ )
{
//Generate Item from library
var MovieClip_mc:mcMovieClip = new mcMovieClip();
addChild(MovieClip_mc);
//Size
var RandomSize = (Math.random() * 0.5) + 0.5;
MovieClip_mc.scaleX = RandomSize;
MovieClip_mc.scaleY = RandomSize;
//Rotation
var RandomRotation:Number = Math.floor(Math.random()*360);
MovieClip_mc.rotation = RandomRotation;
//Position
MovieClip_mc.x = Math.floor(Math.random() * CanvasWidth);
MovieClip_mc.y = Math.floor(Math.random() * CanvasHeight);
}
For performance benefits, it is better to do it using one ENTER_FRAME handler. The handler can be located in your main class and update each mcMovieClip's properties by calling certain methods declared in the mcMovieClip class. Below is a simple example.
Main class
var mcs:Array = [];
for(var i:int = 0; i < 1; i++)
{
mcs.push(new mcMovieClip());
addChild(mcs[i]);
}
addEventListener(Event.ENTER_FRAME, updateTime);
function updateTime(e:Event):void
{
for(var j:int = 0; j < mcs.length; j++)
{
mcs[j].updatePosition(Math.random() * stage.stageWidth,
Math.random() * stage.stageHeight);
mcs[j].updateRotation(Math.random() * 360);
mcs[j].updateSize(Math.random());
}
}
mcMovieClip class
function updateSize(size:Number):void
{
this.scaleX = this.scaleY = size;
}
function updateRotation(rot:Number):void
{
this.rotation = rot;
}
function updatePosition(newX:Number, newY:Number):void
{
this.x = newX;
this.y = newY;
}
You don't actually need to do that from the outside. You can animate it with its own script in the first frame, so each instance will be animated:
addEventListener(Event.ENTER_FRAME, onFrame);
function onFrame(e:Event):void
{
// Math.random() - 0.5 will produce a random value from -0.5 to 0.5
x += Math.random() - 0.5;
y += Math.random() - 0.5;
scaleX += (Math.random() - 0.5) / 10;
scaleY = scaleX;
rotation += (Math.random() - 0.5) * 5;
}

how to stop particles from moving off stage, Actionscript random particle generator

Below is some code for a random particle generator. I want to change it so the particles only move a small distance before stopping and not disappearing. As it is now, they keep moving until they go off stage. I'm new to Actionscript so any help would be appreciated, thanks.
var particleArray:Array = new Array();
var maxParticles:Number = 50000;
function addParticle(e:Event)
{
var Symbol:Symbol3 = new Symbol3();
Symbol.alpha = Math.random() * .8 + .2;
Symbol.scaleX = Symbol.scaleY = Math.random() * .8 + .2;
Symbol.xMovement = Math.random() * 10 - 5;
Symbol.yMovement = Math.random() * 10 - 5;
Symbol.x = mouseX;
Symbol.y = mouseY;
particleArray.push(Symbol);
addChild(Symbol);
Symbol.cacheAsBitmap = true;
if (particleArray.length >= maxParticles)
{
removeChild(particleArray.shift());
}
Symbol.addEventListener(Event.ENTER_FRAME,moveParticle);
}
function moveParticle(e:Event)
{
e.currentTarget.x += e.currentTarget.xMovement;
e.currentTarget.y += e.currentTarget.yMovement;
}
var myTimer:Timer = new Timer(50);
myTimer.addEventListener(TimerEvent.TIMER, addParticle);
myTimer.start();
One way to do this would be to remove the event listener after a number executions:
function addParticle(e:Event)
{
var Symbol:Symbol3 = new Symbol3();
Symbol.alpha = Math.random() * .8 + .2;
Symbol.scaleX = Symbol.scaleY = Math.random() * .8 + .2;
Symbol.xMovement = Math.random() * 10 - 5;
Symbol.yMovement = Math.random() * 10 - 5;
// set the number of times this instance can move.
// Using a randomly generated number here
Symbol.movementCount = int(Math.random() * 10);
Symbol.x = mouseX;
Symbol.y = mouseY;
particleArray.push(Symbol);
addChild(Symbol);
Symbol.cacheAsBitmap = true;
if (particleArray.length >= maxParticles)
{
removeChild(particleArray.shift());
}
Symbol.addEventListener(Event.ENTER_FRAME,moveParticle);
}
function moveParticle(e:Event)
{
e.currentTarget.x += e.currentTarget.xMovement;
e.currentTarget.y += e.currentTarget.yMovement;
// decrement your move count, and then check to see if it's hit zero
e.currentTarget.movementCount--;
if(e.currentTarget.movementCount <=0)
{
// if so, remove the event listener
e.currentTarget.removeEventListener(Event.ENTER_FRAME, moveParticle);
}
}

how do i stop or remove an addEventListener in flash cs6

Hi guys I need some help, I'm a total AS3 novice.
I have a flash project with 4 scenes in a loop, and the last scene has a snowflake falling script applied.
I found this snow script to use in my project. Works great but I have no idea of how to limit the animation only to the particular scene it starts on. the scenes keep looping and the snow doesn't stop.
Scene it starts on goes for 300 frames, if that help at all.
Here is the code:
addEventListener(Event.ENTER_FRAME, snow);
function snow(event: Event): void {
var scale: Number = Math.random() * 0.6;
var _sf: snowflake = new snowflake();
_sf.x = Math.random() * 640;
_sf.scaleX = scale;
_sf.scaleY = scale;
var speed: Number = Math.random() * 2;
var RA: Array = new Array(-1, 1);
var lf: int = RA[Math.round(Math.random())];
stage.addChild(_sf);
_sf.addEventListener(Event.ENTER_FRAME, snowfall);
function snowfall(event: Event): void {
_sf.y += speed;
_sf.rotation += Math.random() * 20;
_sf.x += (Math.random() * 2) * lf;
}
}
Any help would be greatly appreciated. thanks Rick
I end up finding a better script for the snow animation, that plays for the duration of the scene.
here it is - for reference.
import flash.events.Event;
var snowflakes:Array = new Array();
addEventListener(Event.ENTER_FRAME, loop);
function loop(e:Event) {
for (var i=0; i<4; i++) {
var scale: Number = Math.random() * 0.6;
var s = new flake();
s.x=Math.random()*550;
s.scaleX = scale;
s.scaleY = scale;
s.y=-10;
s.speedY=1+Math.random()*2;
s.speedX=2-Math.random()*3;
addChild(s);
snowflakes.push(s);
}
for (i=snowflakes.length-1; i>0; i--) {
snowflakes[i].y+=snowflakes[i].speedY;
snowflakes[i].x+=snowflakes[i].speedX;
if (snowflakes[i].y>600) {
removeChild(snowflakes[i]);
snowflakes.splice(i, 1);
}
}
}
I then added this on the last frame of the scene, and it worked.
removeEventListener(Event.ENTER_FRAME, loop);
removeEventListener(Event.ENTER_FRAME, snow);
Something like that:
removeEventListener(Event.ENTER_FRAME, snowfall);

Getting a TypeError #1123: Filter operator not supported on type, MainTimeline/enterFrameHandler ()

I'm trying to take an older tutorial for a star field from AS2 and port it over to AS3. I am no longer getting any compiler errors, but I am getting a TypeError.
Here is the code:
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
import flash.display.MovieClip;
import flash.events.Event;
var stars = 100;
var maxSpeed = 16;
var minSpeed = 2;
for( var i = 0; i<stars; i++)
{
var mc:MovieClip = new MovieClip();
addChild(mc);
mc.name = "star","star"+i,i;
mc.x = Math.random() * stage.stageWidth;
mc.y = Math.random() * stage.stageHeight;
mc.speed = Math.random() * (maxSpeed-minSpeed)+minSpeed
var size = Math.random() * 2+(0.6*(Math.random() * 4));
mc.width = size;
mc.height = size;
}
function enterFrameHandler(event:Event):void
{
var target:MovieClip = MovieClip(event.target);
for (var j = 0; j<stars;j++)
{
var mc = this.("star"+j);
if (mc.y>0)
{
mc.y -= mc.speed;
}
else
{
mc.y = stage.stageHeight;
mc.speed = Math.random() * (maxSpeed-minSpeed)+minSpeed;
mc.x = Math.random() * stage.stageWidth;
}
}
};
The TypeError I am getting is this:
TypeError: Error #1123: Filter operator not supported on type
SpaceBoost_loadscreen_star_fla.MainTimeline. at
SpaceBoost_loadscreen_star_fla::MainTimeline/enterFrameHandler()
I am very new to coding in Actionscript, and am just learning as I go.
Also, any helpful suggestions on how to clean it up are also welcome!
Two issues I see after a quick glance:
Issue 1:
In your first for loop, this line: mc.name = "star","star"+i,i;
The name for each item will end up being the same ("star"), because after the comma it's just going to be a string literal command (assuming this isn't throwing an error as well).
Correct by changing this to:
mc.name = "star" + i;
Issue 2:
What is throwing the current error, var mc = this.("star"+j);
In AS3, object.(expression) is E4X filtering. To access an object via instance name, do the following instead:
var mc = getChildByName("star" + j);
I'm pretty rusty on this, so let me know if doesn't solve your issue.

Playing a random frame inside MovieClip with AS3

I have a movie clip (goalkeeper) with different positions in different frames (inside), I would like to play a random frame after executing a function to make the goalkeeper move to a determinate position, there are 6 frames with 6 different positions so I need to play 1 position randomly, this is the code that should go to the random number after ball is kicked:
function moveBall()
{
var targetX:Number = mouseX;
var targetY:Number = mouseY;
var angle = Math.atan2(targetY,targetX);
ball.x = mouseX + Math.cos(angle);
ball.y = mouseY + Math.sin(angle) ;
ballRotation = true;
if (ballRotation==true)
{
goalkeeper_mc.gotoAndStop( Random Frame);//Here is when I need to go and play the random frame everytime function is executed
}
Thanks a lot for your help guys, sorry for bothering again, I searched the web for some examples but I found many of them really complicated for a newbie like me.
refer a following code.
you must randomize from 1 frame to last Frame.
Math.random () of the range is greater than 0 and less than 1(floating-value). by use it implements available.
function moveBall()
{
var targetX:Number = mouseX;
var targetY:Number = mouseY;
var angle = Math.atan2(targetY,targetX);
ball.x = mouseX + Math.cos(angle);
ball.y = mouseY + Math.sin(angle) ;
ballRotation = true;
if (ballRotation==true)
{
goalkeeper_mc.gotoAndStop(int(Math.random * (goalkeeper_mc.totalFrames)+1));
}
}
goalkeeper_mc.gotoAndStop(1 + Math.floor(Math.random() * goalkeeper_mc.totalFrames));