Random position without overlapping - actionscript-3

How to stop MCs from overlapping each other?
private function loadWishes():void {
for (i; i<myXMLList.length(); i++) {
cBox=new MovieClip();
checkOverlap(cBox);
addChild(cBox);
commentArray.push(cBox);
}
}
private function checkOverlap(wishB:MovieClip) {
wishB.x=Math.random()*stage.stageWidth;
wishB.y=Math.random()*stage.stageHeight;
for (var i:uint=0; i<commentArray.length; i++) {
if (wishB.hitTestObject(commentArray[i])) {
checkOverlap(wishB);
return false;
}
trace(commentArray.length);
}
}
This doesn't seems to be working cause the amount of it checking whether MC is overlapping is about the amount of MC on stage. how to make it keep checking till everything's fine?

The code you have here should work in general for preventing overlapping (though you should be careful - in a worst-case scenario this code might loop infinitely if the clips are too big or the stage is too small).
However, your problem is that you're calling this code on newly-created MovieClip objects, which are empty - so they can never overlap. Presumably you're adding in some child contents to the clips later, and at that point they overlap. So the fix is, you should populate the clips first, before checking if they overlap, or alternately, if you know the size of the clips, then instead of calling hitTestObject you could manually check whether the clip's position is too close to other clips.

Related

Libgdx and Box2d / Particles are not following bodies

i'll just cut to the chase.
So i'm making this game where you should kill other objects with your spells i've created bullets and their bodies we're all good it's working.
But i wanted to make it look special and "magiclike" so i decided to use particles. I've made the particles and put and made them follow the bullet bodies with this code:
for (Bullet bullet : bullets) {
bullet.update(dt);
if (!bullet.destroyed){
fireFx.start();
fireFx.setPosition(bullet.getPosition().x, bullet.getPosition().y);
fireFx.update(dt);
}
}
but there's a problem when i fire multiple bullets particles are just dissappearing from the all of the first bullets i fired and just appears on the last one. Can someone lead me on this one please ?
-----------------EDIT-----------------
Now i've got another problem that when bullet collides with something it gets destroyed and render method stops working but i want it to keep rendering till the animation is over. Like i don't want them to disappear suddenly here is my code for this:
for(int i = 0; i<bullets.size; i++){
if(!bullets.get(i).destroyed && !bullets.get(i).fireFx.isComplete())
bullets.get(i).fireFx.draw(game.batch);
}
fireFx.isComplete() is not working correctly what is the reason ?
The issue is that you're updating a single particle to have the coordinates of all the bullets in a list, and effectively keeping the coordinates of the last bullet in the list. You could maintain a Map that maps Bullets onto Particles, but I would instantiate a fireFx object when a Bullet is created and add it to the Bullet object. Then, in the Bullet#update method you can call the particle update method:
public void update(float dt) {
[...]
if ( !this.isDestroyed()) {
[...]
this.fireFx.start();
this.fireFx.setPosition(this.getPosition().x, this.getPosition().y);
this.fireFx.update(dt);
[...]
}
[...]
}

What is this, and why is it happening?

So I have been working on my final project for the semester for my Computer Systems class, and we have been tasked to make a game using Flash and ActionScript 3.0. I've pretty much completed everything but I have come across an extremely strange occurrence of Flash CS6 being silly. I am moving a MovieClip up and down depending on a selected index, however, the image leaves 'residue of it's footprints' behind and also moves. I have tried hard to look for an answer as to why this is happening, but I don't know what it's called, or how to appropriately explain it - I'm coming from an area where one must program graphics, not just simply, drag and drop.
Below are pictures as to what I've come across, but first the code I'm using:
function updateThemeScreen():void {
button_selection.y += (selectedPositions[selectedTheme] - button_selection.y) / 2;
}
function attemptThemeChange(mxP:Number, myP:Number):void {
if(objectContains(theme_darkness, mxP, myP)) {
selectedTheme = 0;
} else if(objectContains(theme_halloween, mxP, myP)) {
selectedTheme = 1;
}
}
As you can see in the final image, it has copied half of itself and left it at the last button, which is strange, and shouldn't happen...
Link to the SWF zipped up with the required AS3 classes: Dude, RUN
So it seems that I have magically fixed this problem by hiding the buttons and showing them all in one frame. I don't know what this problem is or why it does it, but to fix it, you just need to hide and show the affected components - yes, in one frame:
function hideShow(object:MovieClip):void {
object.visible = false;
object.visible = true;
}

Make all children do something...?

I'm wondering if there is an easy way to make all children simultaneously do something. In particular, I want everything on my stage to shake back and forth like an earthquake. It's a bit hard to single out everything on stage and add in the proper code because at a given time I don't always know the amount of children on stage.
Also, I'm not sure if it makes a difference, but sometimes when I addChild something, I don't go out of my way to add it to the stage...Like for a few buttons I'll do this.addChild(mybutton). I don't know if there's a way to access everything that has been addChilded even though I may not have added them directly to the stage? I'm pretty sure numChildren returns the value of the number of objects on screen, but I could be wrong...
I was thinking of doing something like
Inside my loop
if (numChildren >= 10 && nukeShakeTimer.currentCount == 0)
{
nukeShakeTimer.start();
}
if (nukeShakeTimer.currentCount > 0)
{
NukeShake();
}
NukeShake
public function NukeShake():void
{
numberChildren = numChildren;
trace(numberChildren);
while (numberChildren > 0)
{
var tempObject:Object = getChildAt(numberChildren)
if (nukeShakeTimer.currentCount % 2 == 1)
{
tempObject.x += 10;
}
if (nukeShakeTimer.currentCount % 2 == 0)
{
tempObject.x -= 10;
}
numberChildren -= 1;
}
if (nukeShakeTimer.currentCount > 30)
{
nukeShakeTimer.reset();
}
}
When I try this though, I get a runtime error for the line var tempObject:Object = getChildAt(numberChildren) and the error reads RangeError: Error #2006: The supplied index is out of bounds.
Also I feel like it may be possible to do this operation much faster without using a while loop, but maybe not. Help please, thanks!
If you want to address every child on the stage then you'll need to loop through them. As Cherniv says, changing your getChildAt call to use numberChildren-1 should resolve your error.
It shouldn't matter whether or not everything is directly on the stage or not. Looping through the stage children will get you whatever container you added the objects to. Moving that container will move its children too. (Though you'll have to do more work if you need to move those children independently).
But...
In your specific case, it looks like you just want to shake everything on the screen together, in the same direction at the same rate. In this case, I would probably just add all my objects to a single container Sprite on the stage. Then, when you want to do a shake effect, you only need to move that one container object and everything moves together.

AS3 setChildIndex to front

Is there a way to send a specific movieClip to the front of all other movieClips on stage?
I know about setChildIndex, but I can't figure out a way to to calculate the top position dynamically.
You can use setChildIndex() with numChildren.
setChildIndex(childClip, numChildren - 1);
You don't need to use setChildIndex.
addChild is sending child on the top of all clips.
You may be thinking that addChild will double add your MC, but it will not, the second time it will just update it's child index.
By default, flash adds the movieclip to the top of the display list, so you can just repeat adding of the child to the container.
stage.addChild(bottom);
stage.addChild(top);
// top is now on bottom.
stage.addChild(bottom);
// bottom is now on top.
The movieclip(mc) is added on the canvas,
canvas.setChildIndex(mc, 0);
The canvas is added on the stage,
stage.setChildIndex(canvas, 0);
/* Bring Any Clicked Object to the Front
Clicking on any symbol on the Stage moves it in front of all other instances.
*/
// This code makes all symbol instances on stage clickable by making them listen for the CLICK event.
for (var fl_ChildIndex:int = 0;
fl_ChildIndex < this.numChildren;
fl_ChildIndex++)
{
this.getChildAt(fl_ChildIndex).addEventListener(MouseEvent.CLICK, fl_ClickToBringToFront);
}
// This is the function that moves the clicked object to the front of the display list
function fl_ClickToBringToFront(event:MouseEvent):void
{
this.addChild(event.currentTarget as DisplayObject);
}
From Adobe Flash Professional Code Snippets.

Movieclip stacking in Actionscript

I'm building a game of which the interface is one of the first items to load on screen. Sound button, pause and all the bits -
During the game - all manor of things are dynamically added and removed to the stage. Therefore my interface goes behind my game scene.
How do I ensure the movieclip always stays on top?
Can I override the addChild of my Document Class and every time a new child is added, I restack the interface to the top?
You can use setChildIndex to rearrange objects that are already contained within a MovieClip or Sprite. For example, if you have an object called container, which contains a redBall, blueBall and many other ball objects, you can use the following to make sure redBall is behind everything else:
container.setChildIndex(redBall, 0);
Equally you can make sure that blueBall will be displayed infront of everything else using:
container.setChildIndex(blueBall, container.numChildren-1);
addChildAt will sort you out for adding children straight into their correct position, and setChildIndex will allow you to re-position objects already placed. Hope that helps.
debu
Look into addChildAt, it allows you to specify the index that the new object should be added too.
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObjectContainer.html#addChildAt%28%29
A good strategy is to keep all interface elements in one parent Sprite/MovieClip, and all game assets in another. (With the interface one on top)
With your guys suggestion I made this, apparently, if you addChild an object already on the screen, it's simply reindex'd to the top. Does this look ok?
private var topLevelChildrenArray:Array = [];
public function addTopLevelChild(child:DisplayObject):DisplayObject
{
topLevelChildrenArray.push(child)
return this.addChildAt( child, this.numChildren - 1 );
}
override public function addChild(child:DisplayObject):DisplayObject
{
this.addChildAt(child, this.numChildren);
for each(var topChild:DisplayObject in topLevelChildrenArray)
{
super.addChild(topChild);
}
return child
}