Stop and play nested MovieClip - actionscript-3

I'm trying to make a falling bomb and explosion effect. I created bomb1 with a nested motion tween and then I created bomb2 with the explosion effect nested another level deep inside bomb1. My hope was that when the bomb hit the target the motion downward will stop and at the same time there will be an explosion. The problem is that I can't make both action happened at the same time, it either stops the motion completely or having the explosion while the bomb continue going downward. I can't make both action happened at the same time. bomb1.stop(); should stop the motion down and bomb1.bomb2.gotoAndPlay(31); should make the explosion effect. Any Idea?
import flash.events.Event;
var bombPlaying: Boolean = true;
this.addEventListener(Event.ENTER_FRAME, handleCollision);
function handleCollision(evt: Event): void {
if (bomb1.hitTestObject(gLine1)) {
bomb1.stop();
bomb1.bomb2.gotoAndPlay(31);
}
}

I can't comment as to your exact particulars without seeing the project, but a possible workaround for your issue would be to try this:
import flash.events.Event;
var bombPlaying: Boolean = true;
this.addEventListener(Event.ENTER_FRAME, handleCollision);
function handleCollision(evt: Event): void {
if (bomb1.hitTestObject(gLine1)) {
bomb1.stop();
setTimeout(bomb1.bomb2.gotoAndPlay, 0, 31);
}
}
This will trigger your bomb1.bomb2.gotoAndPlay function to be called on the next frame, which may mitigate your issue.

I have find the solution. The eventListener had to be removed before bomb1.stop();bomb1.bomb2.gotoAndPlay(31);
import flash.events.Event;
bomb1.gotoAndStop(1);
myButton.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event: MouseEvent): void {
bomb1.gotoAndPlay(1);
this.addEventListener(Event.ENTER_FRAME, handleCollision);
}
function handleCollision(evt: Event): void {
if (bomb1.hitTestObject(gLine1)) {
this.removeEventListener(Event.ENTER_FRAME, handleCollision);
bomb1.stop();
bomb1.bomb2.gotoAndPlay(31);
}
}

Related

Unable to addChild on MouseCoordinations

What i am trying to do is, to place a new tower each time on MouseX and MouseY. but it seems it isn't working Any Idea guys?
or if you can create a tileMap array and add new child of PrototypeTower each time when we click on the Tower (on x=50, y=400) to select and place wherever we want. When i click the the box at x=50, y=400, the startDrag() doesn't work.
Main.as
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.ui.Mouse;
public class Main extends Sprite
{
private var pTower:PrototypeTower = new PrototypeTower;
private var zTower:PrototypeTower = new PrototypeTower;
private var fTower:PrototypeTower = new PrototypeTower;
public function Main()
{
pTower.x = 50;
pTower.y = 400;
addChild(pTower);
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
pTower.addEventListener(MouseEvent.CLICK, onClicked);
}
private function onClicked(e:Event):void
{
removeEventListener(MouseEvent.CLICK, onClicked);
zTower.x = mouseX;
zTower.y = mouseY;
addChild(zTower);
zTower.startDrag();
addEventListener(MouseEvent.CLICK, onPlaced);
}
private function onPlaced(e:Event):void
{
removeEventListener(MouseEvent.CLICK, onPlaced);
zTower.stopDrag();
fTower.x = mouseX
fTower.y = mouseY;
addChild(fTower);
}
}
}
PrototypeTower.as
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
public class PrototypeTower extends MovieClip
{
public function PrototypeTower()
{
this.graphics.beginFill(0x00FF00);
this.graphics.drawRect(this.x, this.y, 20, 20);
this.graphics.endFill();
}
}
}
Thank you, i am totally noob, wondering around from days!
Sorry this is just a schematic for now. I'll try to refine it later if you need. Hopefully this clears some things up for you though
When you click the tower, add a new tower at the x,y of the mouse and do some sort of startDrag(tower) on the new tower you just added. Then when you click on the stage, stop the drag and set the new X,y
edit
You might try getting rid of all your removeEventListener calls
I think your problem is you are removing the event listener that gets added in your main function. Keep in mind that the main function (class constructor) for the document class only gets called once, so you add an event listener for ADDED_TO_STAGE only once, and then you remove it the first time you try to add anything to the stage, and you never put it back. Just don't remove it in the first place.
You are calling zTower.startDrag() before you add it to the stage. Do addChild(zTower) and then zTower.startDrag()

making a symbol move by keyboard not showing result and when published it not reads stop(); but replays it again and again

I am new to actionscript ,
My document class is ,
package
{
//list of our imports these are classes we need in order to
//run our application.
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
public class engine extends MovieClip
{
// moved ourShip to a class variable.
private var Circle:circle = new circle()
//our constructor function. This runs when an object of
//the class is created
public function engine()
{
addFrameScript(0, frame1);
addFrameScript(1, frame2);
}
// frame 1 layer 1 --------------------------------------------------
public function frame1()
{
stop();
}
//-------------------------------------------------------------------
// frame 2 layer 1 --------------------------------------------------
public function frame2()
{
Circle.x = stage.stageWidth / 2;
Circle.y = stage.stageHeight / 2;
addChild(Circle);
}
//-------------------------------------------------------------------
}
}
i made two frames first contains button and the other circle which i want to move but it not moves and it stays in the middle on second frame
My button class is
package
{
//imports
import flash.events.MouseEvent;
import flash.display.SimpleButton;
import flash.display.MovieClip;
//-------
public class start extends SimpleButton
{
public function start()
{
addEventListener(MouseEvent.CLICK, onTopClick);
addEventListener(MouseEvent.MOUSE_OVER, onBottomOver);
}
function onTopClick(e:MouseEvent):void
{
MovieClip(root).gotoAndStop(2)
}
function onBottomOver(e:MouseEvent):void
{
}
}
}
And my as of circle movieclip is
package
{
//imports
import flash.display.MovieClip;
import flash.display.Stage;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
public class circle extends MovieClip
{
private var speed:Number = 0.5;
private var vx:Number = 0;
private var vy:Number = 0;
private var friction:Number = 0.93;
private var maxspeed:Number = 8;
public function circle()
{
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
public function loop(e:Event) : void
{
addEventListener(KeyboardEvent.KEY_DOWN, keyHit);
x+=vx;
y+=vy
}
function keyHit(event:KeyboardEvent):void {
switch (event.keyCode) {
case Keyboard.RIGHT :
vx+=speed;
break;
case Keyboard.LEFT :
vx-=speed;
break;
case Keyboard.UP :
vy-=speed;
break;
case Keyboard.DOWN :
vy+=speed;
break;
}
}
}
}
I am sorry to post so much for you guys to read but stackoverflow is the only website where anyone helps me !
You have made several major errors. First, addFrameScript() isn't a proper way to place code on frames, use Flash's editor to place code on timeline. (IIRC you will have to make a single call out of your two in order to have all the code you add to function) And, whatever code you added to a frame of a MC is executed each frame if the MC's currentFrame is the frame with code. Thus, you are adding a function "frame2()" that places the Circle in the center of the stage each frame! You should instead place it at design time (link it to a property) into the second frame, or in a constructor, or you can use one single frame and Sprite instead of MovieClip, and instead of using frames you can use container sprites, adding and removing them at will, or at an action.
The other major mistake is adding an event listener inside an enterframe listener - these accumulate, not overwrite each other, so you can have multiple functions be designated as listeners for a particular event, or even one function several times. The latter happens for you, so each frame another instance of a listening keyHit function is added as a listener. The proper way to assign listeners is either in constructor, or in any function that listens for manually triggered event (say, MouseEvent.CLICK), but then you have to take precautions about listening for more than once with each function, and listening only with those functions you need right now.
EDIT:
Okay. Your code was:
addFrameScript(0, frame1);
addFrameScript(1, frame2);
The more correct way should be:
addFrameScript(0,frame1,1,frame2);
The reason is, the call to addFrameScript replaces all the timeline code with what you supply within here. The function is undocumented, perhaps by the reason of its affects on the stage and AS3 environment. The closest thing to the documentation on addFrameScript() so far is this link.
Next: Your code is:
public function circle()
{
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
public function loop(e:Event) : void
{
addEventListener(KeyboardEvent.KEY_DOWN, keyHit);
x+=vx;
y+=vy
}
The correct way of writing this is as follows:
public function circle()
{
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE,init);
}
private function init(e:Event=null):void
{
removeEventListener(Event.ADDED_TO_STAGE,init);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHit);
}
public function loop(e:Event) : void
{
x+=vx;
y+=vy
}
The listeners should be assigned in constructor, if they are permanent or you want them to be active as soon as you create an object. The KeyboardEvent listeners are separate case, as in order for them to function you have to assign them to stage, which is not available right at the time of creating the object, so you need an intermediate layer - the init() function, that is only called when the object is added to stage. At this point stage is no longer null, and you can assign an event listener there. Note, if you want to make your circles eventually disappear, you have to remove the listener you assigned to stage at some point of your removal handling code.
Next: Your code:
public function frame2()
{
Circle.x = stage.stageWidth / 2;
Circle.y = stage.stageHeight / 2;
addChild(Circle);
}
Correct code should be:
public function frame2():void
{
if (Circle.parent) return; // we have added Circle to stage already!
Circle.x = stage.stageWidth / 2;
Circle.y = stage.stageHeight / 2;
addChild(Circle);
}
See, you are calling this every time your MC is stopped at second frame, thus you constantly reset Circle's coordinates to stage center, so you just cannot see if it moves (it doesn't, as you have assigned the keyboard listener not to stage).
Perhaps there are more mistakes, but fixing these will make your MC tick a little bit.

Actionscript 3.0, error with hitTestObject

I'm getting an error I can't seem to fix. I think I know kind of what is going on but I'm not sure enough to be able to fix it. I keep getting error
"TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display::DisplayObject/_hitTest()
at flash.display::DisplayObject/hitTestObject()"
Basically I fire an attack in my game. It hits an enemy and he is killed just fine. BUT, he has an animation as he dies that takes a couple seconds. It seems if I fire another attack during his animation, my attack IMMEDIATELY gives this error (before striking anything, that is). Once the animation is over, everything is fine again. Also, the game was working 100% fine before I put in this animation.
Here is my document class
package com.classes
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
public class DocumentClass extends MovieClip
{
// we need to keep track of our enemies.
public static var enemyList1:Array = new Array();
// moved stickobject1 to a class variable.
private var stickobject1:Stickman2;
public function DocumentClass() : void
{
//removed the var stickobject1:Stickman2 because we declared it above.
var bg1:background1 = new background1();
stage.addChild(bg1);
stickobject1 = new Stickman2(stage);
stage.addChild(stickobject1);
stickobject1.x=50;
stickobject1.y=300;
//running a loop now.... so we can keep creating enemies randomly.
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
//our loop function
private function loop(e:Event) : void
{
//run if condition is met.
if (Math.floor(Math.random() * 90) == 5)
{
//create our enemyObj1
var enemyObj1:Enemy1 = new Enemy1(stage, stickobject1);
//listen for enemyObj1 being removed from stage
enemyObj1.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemyObj1, false, 0, true);
//add our enemyObj1 to the enemyList1
enemyList1.push(enemyObj1);
stage.addChild(enemyObj1);
}
}
private function removeEnemyObj1(e:Event)
{
enemyList1.splice(enemyList1.indexOf(e.currentTarget), 1);
}
}
}
And here is my attack1 class
package com.classes {
import flash.display.MovieClip;
import flash.display.Stage;
import com.senocular.utils.KeyObject;
import flash.ui.Keyboard;
import flash.events.Event;
public class attack1 extends MovieClip {
private var stageRef:Stage;
private var bulletSpeed:Number = 16;
public function attack1 (stageRef:Stage, x:Number, y:Number) : void
{
this.stageRef = stageRef;
this.x = x;
this.y = y;
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
private function loop(e:Event) : void
{
//move bullet up
x += bulletSpeed;
if (x > stageRef.stageWidth)
removeSelf();
for (var i:int = 0; i < DocumentClass.enemyList1.length; i++)
{
if (hitTestObject(DocumentClass.enemyList1[i].hit))
{
trace("hitEnemy");
removeSelf();
DocumentClass.enemyList1[i].takeHit();
}
}
}
private function removeSelf() : void
{
removeEventListener(Event.ENTER_FRAME, loop);
if (stageRef.contains(this))
stageRef.removeChild(this);
}
}
}
Don't think you should need any other of my classes to figure out what's going on, but let me know if you do! Thanks very much =)
You don't want to do a hit test against any object that may have been removed from the scene (or from the enemyList array). The extra condition added to attack1.loop's for loop should get rid of your error. A better fix is to splice out the items you remove, so they are never tested against in the loop.
The break line will make it stop trying to hit other enemies after the bullet is removed. If the line "DocumentClass.enemyList1[i].takeHit();" removes the item from the enemyList1, you need to make sure you use "i--;" at the bottom of the loop as well, if you plan on looping through the remainder of the enemies. "i--" or "break", you will probably need one of them in that loop.
Double check the order in which you are executing your removal methods. Sometimes it's better to flag the items for removal and remove them in a separate loop than to remove an item that may be needed later in the same loop.
for (var i:int = 0; i < DocumentClass.enemyList1.length; i++){
if(DocumentClass.enemyList1[i] && DocumentClass.enemyList1[i].hit){
if (hitTestObject(DocumentClass.enemyList1[i].hit)){
trace("hitEnemy");
removeSelf();
DocumentClass.enemyList1[i].takeHit();
break;
}
}
}
Not the correct solution in this question. You can always do != null in a conditional statement.
if(object!=null){
party.drink();
}

custom mouse hiding behind objects as3

i have this here http://www.nzombie.eshost.es/ with a custom mouse. It works perfect, only that when it is behind another movie clip it "hides" itself. I don't know what's wrong. Any advice or help with be appreciated. Here's the mouse class:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.ui.Mouse;
public class myCursor extends MovieClip
{
public function myCursor(stage):void
{
stop();
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
addEventListener(Event.REMOVED_FROM_STAGE, onRemove);
}
private function updateCoor(e:MouseEvent):void
{
x = e.stageX;
y = e.stageY;
e.updateAfterEvent();
}
private function onDown(e:MouseEvent):void
{
updateCoor(e);
gotoAndStop(2);
}
private function onUp(e:MouseEvent):void
{
updateCoor(e);
gotoAndStop(1);
}
private function onMove(e:MouseEvent):void
{
Mouse.hide();
updateCoor(e);
}
private function onRemove(e:Event):void
{
Mouse.show();
stage.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
removeEventListener(Event.REMOVED_FROM_STAGE, onRemove);
}
}
}
If you are adding multiple things to the stage at runtime it would be worth overriding addChild so that everything is added at index 1, leaving the cursor (at index 0) always on top.
Something like this:
override public function addChild(value:displayObject):void
{
var index:uint = 1;
if(value is myCursor){index = 0;}
addChildAt(value, index);
}
Or simply only ever add new display objects using addChildAt(displayObject, 1) and be sure to add your cursor class at 0;
I believe the issue lies not in this class, but in the class where you add myCursor object.
The buttons might have been added after the cursor & so the cursor lies behind the buttons in the display list. Try adding the myCursor after the buttons have been added to stage.

Make Flash Parent Fade Out & adding sound BrickBreaker Game

Hi i am trying to get this brick to fade out when the ball hits it in my brickbreaker game in flash AS3. Here is the code. At the moment there is just a removechild function which makes it just dissapear i want to know how to make it fade out instead. Also i have a breaking sound i would like to add when the ball hits the brick and wonder how i would add this aswell?
EDIT: I have managed to add sound by using Var & Play after the remove child line
package {
import flash.display.*;
import flash.events.*;
public class Brick extends MovieClip {
private var _root:MovieClip;
public function Brick(){
addEventListener(Event.ADDED, beginClass);
addEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
private function beginClass(event:Event):void{
_root = MovieClip(root);
}
private function enterFrameEvents(event:Event):void{
if(this.hitTestObject(_root.Ball)){
_root.ballYSpeed *= -1;
this.parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
}
}
}
No need for any tweener pack for just one tween.
You can use the Tween class provided in AS3 itself. Try this :
new Tween(mc,"alpha",
Strong.easeIn,
mc.alpha,
0,
2,
true).addEventListener(
TweenEvent.MOTION_FINISH,
function() { removeChild(mc); },
false, 0, true);
Note:
mc is the movieclip (or the brick).
The code removes the movieclip from stage after the tween completes.
You may play the sound as soon as the ball touches the brick & put
this code after that.
The last three parameters (false, 0, true) set the motion finish listener to be garbage collected.
How I would do it would be to first create a variable hit:Boolean and set it to true when it gets hit and change your code inside enterFrameEvents function to something like this
if(!hit && this.hitTestObject(_root.Ball)){
hit = true;
_root.ballYSpeed *= -1;
//this.parent.removeChild(this);
//removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
if(hit){
this.alpha -= 0.1; //change value to preference
if(this.alpha <= 0){
this.parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
}

Categories