AS3 MOVING OBJECT ON SPECIFIC FRAME - actionscript-3

so i've been working on this game for a week now and i dont have any coding background at all so im trying to find tutorial here and there.. then i come up with this problem ...
so what i wanna do is move the object (CHARA) to the right when i hit frame 80 inside (CHARA,which is a nested movieClip with 99 frames btw ) then move it back to original position when i hit frame 99...
the problem is anything i do doesn't make my object move at all (movieClip still played btw) what did i do wrong here? did i just put the code at the wrong position ?? (CHAR is moved only if i put the code x= directly inside frame 80 but i try using class here)
here is my code,sorry i know its messy its my first code i try my best here
package {
public class Main extends MovieClip {
public var CHARA:CHAR = new CHAR;//my main char
public var rasen:Rasen_button = new Rasen_button;//the skill button
public var NPCS:NPC = new NPC;// the npc
public function Main() {
var ally:Array = [265,296];//where me and my ally should be
var jutsu:Array = [330,180];// where the buttons should be
var enemy:Array = [450,294];//where the enemies should be
addChild(NPCS);
NPCS.x = enemy[0];
NPCS.y = enemy[1];
NPCS.scaleX *= -1;
addChild(rasen);
rasen.x = jutsu[1];
rasen.y = jutsu[0];
addChild(CHARA);
CHARA.x = ally[0];
CHARA.y = ally[1];
rasen.addEventListener(MouseEvent.CLICK, f2_MouseOverHandler);
function f2_MouseOverHandler(event:MouseEvent):void {
CHARA.gotoAndPlay(46); //here is the problem
if (CHARA.frame == 80)
{
CHARA.x = ally[1]; //just random possition for now
}
}
}
}
}
any suggestions?

Your if statement is inside a click handler (f2_MouseOverHandler), so it only gets executed when a user clicks rasen, not necessarily when the playback reaches frame 80. This is a common beginner mistake related to timing and code execution. The most straight forward solution is to write some code that will execute every frame using an ENTER_FRAME handler:
rasen.addEventListener(MouseEvent.CLICK, f2_MouseOverHandler);
function f2_MouseOverHandler(event:MouseEvent):void {
CHARA.gotoAndPlay(46); //here is the problem
// add an ENTER_FRAME handler to check every frame
CHARA.addEventListener(Event.ENTER_FRAME, chara_EnterFrameHandler)
}
function chara_EnterFrameHandler(event:Event):void {
if (CHARA.currentFrame == 80)
{
CHARA.x = ally[1]; //just random possition for now
// remove the ENTER_FRAME after the condition is met
// so it stops executing each frame
CHARA.removeEventListener(Event.ENTER_FRAME, chara_EnterFrameHandler);
}
}

Related

Actionscript, load random Movie Clip into Scene

I'm making a simple flash shooting gallery animation with about 5 targets on screen but I am useless at action script.
I have the main scene and 5 Target movie clips in an array. I would like to...
-> Start Animation -> load random clip -> play random clip till end-> generate new random clip -> Repeat with Delay Offset....
So far I have the following:
function getRandomLabel():String {
var labels:Array = new Array("Tar1", "Tar2", "Tar3", "Tar4", "Tar5");
var index:Number = Math.floor(Math.random() * labels.length);
return labels[index];
}
this.gotoAndStop(getRandomLabel());
}
This is working... but I would like to add a delay and no repeat to this...
Ok, lets do it.
// If you need to avoid playing the same movie two times.
var lastLabel:*;
// The list of labels.
var Labels:Array = ["Tar1", "Tar2", "Tar3", "Tar4", "Tar5"];
function playRandom():*
{
do
{
// Get a random index.
var anIndex:int = Math.random() * Labels.length;
}
while (Labels[anIndex] == currentLabel);
// Keep the current label in the variable.
currentLabel = Labels[anIndex];
gotoAndStop(currentlabel);
}
function playNext():void
{
// 1000 milliseconds = 1 second delay.
setInterval(playRandom, 1000);
}
Then. At the end of each of your movie clips you need to correctly call the playNext method. If these movies are in the same timeline, as the code above, just call playNext(); If they are separate MovieClip objects, it will probably be (parent as MovieClip).playNext(); I cannot really tell because I don't know the structure of your movie. You will probably need to read the following to understand: http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3e.html

Unable to reference MovieClip inside Button AS3

I have this annoying issue that I hope someone might be able to help me with.
I have a mute button that I created and I have another movieclip inside of that button. All I want it to do is when I toggle the mute the movieclip inside will go to the according frame.
However, every time I try to call the movieclip inside of the button, this error comes up:
Access of possibly undefined property mcMuteToggle through a reference with static type flash.display:SimpleButton.
The instance name for the movieclip within is "mcMuteToggle".
Why not make movieClips that act like buttons?? Since I dont think actual button (simpleButton) types can deal with sub-MovieClips (especially if they too have code). Even if possible don't do it, I can predict a mess whereby Button does things it shouldn't do depending on what code you have in those MClips.
Try an alternate button method, just for a test... You didnt show any test code to work with so I will make assumptions..
1) Make a shape (rectangle?) and convert to MovieClip (or if all coded, then addchild shape to new MovieClip). Let's assume you called it mc_testBtn.
2) Make that MC clickable by coding mc_testBtn.buttonMode = true;
3) Add your mcMuteToggle inside the mc_testBtn
(or by code: mc_testBtn.addChild(mcMuteToggle);
Now you can try something like..
mc_testBtn.addEventListener (MouseEvent.CLICK, toggle_Mute );
function toggle_Mute (evt:MouseEvent) : void
{
if ( whatever condition )
{
mc_testBtn.mcMuteToggle.gotoAndStop(2); //go frame 2
}
else
{
mc_testBtn.mcMuteToggle.gotoAndStop(1); //go frame 1
}
}
This is likely due to strict mode. You can either disable it in the ActionScript settings dialog, access it with a different syntax myButton['mcMuteToggle'], or make a class for the symbol that includes a property mcMuteToggle.
You can also check to make sure the symbol is actually on the stage and that clip is actually in the button:
if('myButton' in root) {
// ...
}
if('mcMuteToggle' in myButton) {
// ...
}
i think u just overwrite that codes. You u can use something like this:
var soundOpen:Boolean = true;
var mySound:Sound = new Sound(new URLRequest("Whatever your sound is"));
var mySc:SoundChannel = new SoundChannel();
var mySt:SoundTransform = new SoundTransform();
mySc = mySound.play();
mcMuteToggle.addEventListener(MouseEvent.CLICK, muteOpenSound);
function muteOpenSound(e:MouseEvent):void
{
if(soundOpen == true)
{
mcMuteToggle.gotoAndStop(2);
/*on frame 2 u need to hold ur soundClose buton so ppl can see :)*/
soundOpen = false;
mySt.volume = 0;
mySc.soundTransfrom = st;
}
else
{
mcMuteToggle.gotoAndStop(1);
soundOpen = true;
mySt.volume = 1;
mySc.soundTransfrom = st;
}
}
This is working for me everytime. Hope u can use it well ;)

Using MovieClip(root) in ActionScript 3

im at frame 3.. i have text field on the stage name scoreTxt.. at frame 3 i added TryClass..
var Try:TryClass = new TryClass();
TryClass has function of updateScore.. this is working fine if im on frame 3. so my code is
public function updateScore(amount:int):void
{
score += amount;
if(score < 0) score = 0;
realNumber = score;
setInterval(updateDisplayedScore, 10);
}
public function updateDisplayedScore():void
{
displayedNumber += Math.round((realNumber-displayedNumber)/5);
if (realNumber - displayedNumber < 5 && realNumber - displayedNumber > -5)
{
displayedNumber = realNumber;
}
addZeros();
}
public function addZeros():void
{
var str:String = displayedNumber.toString();
MovieClip(root).scoreNa.text = str;
}
but then if for example .. the user died or he reaches the required score.. im suppose to go a certain frame using this code..
MovieClip(this.root).gotoAndStop("Main"); this code is on the class..
its reaching the frame "Main" but its pointing errors to this -->
MovieClip(root).scoreTxt.text
that "Main" frame is on frame 4.. which i did not yet added the TryClass.. should i add to all my frames the TryClass? and how is that?
Sorry for the question.. i dont know yet how to perfectly code in the class.. and accessing the timelines and other external class.. Please dont use deeper language of actionscript.. on a beginner way only..
here is the full error message when i go to the frame "Main"
TypeError: Error #1009: Cannot access a property or method of a null object reference.
atTumba/addZeros()[C:\Documents and Settings\Chrissan\Desktop\Game and Docs\Game\Tumba.as:686]
atTumba/updateDisplayedScore()[C:\Documents and Settings\Chrissan\Desktop\Game and Docs\Game\Tumba.as:680]
atFunction/http://adobe.com/AS3/2006/builtin::apply()
atSetIntervalTimer/onTimer()
atflash.utils::Timer/_timerDispatch()
atflash.utils::Timer/tick()
this is the line 686 of Tumba.as - MovieClip(root).scoreNa.text = str;
public function updateDisplayedScore():void
{
displayedNumber += Math.round((realNumber-displayedNumber)/5);
if (realNumber - displayedNumber < 5 && realNumber - displayedNumber > -5)
{
displayedNumber = realNumber;
}
addZeros(); -->> this is the line 680 of Tumba.as
}
about the setInterval sir.. its working fine cause i imported the flash.utils.* ..its working fine on frame 3 which i added the class.. but on "Main" fram. it isnt..
Try using (root as MovieClip) instead of MovieClip(root)
My guess would be that "root" is undefined, because I'm guessing TryClass is not inherited from a MovieClip or other DisplayObject that lives in the existing heirarchy.
To fix it, I'd add a parameter to the class's constructor. Then, I would send it a movieclip that you can access. For instance, if you are instantiating your class from within a movieclip, just send it the "this" for that movie.
public class TryClass {
...
static var myroot:MovieClip = null;
...
public function TryClass(someclip:MovieClip=null) {
...
if (this.myroot == null && someclip != null && someclip.root != undefined) {
this.myroot = someclip.root;
}
...
}
...
}
Then from within a movie clip:
var something = new TryClass(this);
Anyway, this is the technique I'm using for a class that I'm making. For mine, I have it adding an instance of an external movie clip if the class detects that the root does not already have it loaded. In my case, a universal loading-bar called from my loading wrapper class. If a particular movie I put it in already has a custom loading bar, then it won't do anything, but for any I don't have one in yet, it'll add it.

Flash/AS3: Type was not found or was not a compile-time constant

it's been several years since I've touched AS3, but have a project requiring a bit of scripting.
I'm trying to have a Table of Contents menu slide down, then slide up, depending on a generic Open/Close button. The concept is the same as using .slideToggle() in jQuery.
I've created a MovieClip, given it an Instance Name and have Exported it for ActionScript in my Library, but for some reason, when I try and run a method to just shift it down 325px, I keep getting this error:
1046: Type was not found or was not a compile-time constanc: toc.
I realize that the library is missing a reference for something, but since the MC has an Instance Name and has been exported for AS, I'm a little puzzled as to what it could be. All of my scripts are in Frame 1, and I'm not using any external classes. Any help/pointers would be greatly appreciated!! I'm also having the same issue when I try to create the Email link, towards the bottom of my code.
Again, any help would be greatly appreciated!! Thanks!!
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.display.SimpleButton;
// Initial load elements
gotoAndStop("Frame1");
UpdateFrame();
// Mouse events
btnNextSlide.addEventListener(MouseEvent.CLICK, NextSlide);
btnPrevSlide.addEventListener(MouseEvent.CLICK, PrevSlide);
btnTOC.addEventListener(MouseEvent.CLICK, ShowToC);
//btnDifferenceLink.addEventListener(MouseEvent.CLICK, Email);
// Various Methods
function NextSlide(event:MouseEvent):void
{
// find current slide, go to next slide
var currentFrame = this.currentFrame;
var nextFrame = currentFrame + 1;
if (int(nextFrame) == this.totalFrames)
{
// stop
gotoAndStop("Frame" + this.framesLoaded);
}
else
{
// go to next slide
gotoAndStop("Frame" + nextFrame);
}
// go to and stop at the next frame
UpdateFrame();
}
function PrevSlide(event:MouseEvent):void
{
// find current slide
var currentFrame = this.currentFrame;
var prevFrame = currentFrame - 1;
if (int(prevFrame) == 1)
{
// stop
gotoAndStop("Frame1");
}
else
{
// go to next slide
gotoAndStop("Frame" + prevFrame);
}
// go to and stop at the next frame
UpdateFrame();
}
function UpdateFrame():void
{
txtCurrentSlide.text = this.currentFrame.toString();
}
function Email():void
{
var email:URLRequest = new URLRequest("mailto:emailaddress");
navigateToURL(email, "_blank");
}
function ShowToC():void
{
// slide Table of Contents down
toc.y = 325;
}
function HideToC():void
{
// slide Table of Contents up
toc.y = -325;
}
I have just found the solution!
curtismorley.com/2007/06/20/flash-cs3-flex-2-as3-error-1046
In his first paragraph, he mentions objects on your stage and in your library cannot have the same name. In my case, I had an asset called "toc" in the library, and was referencing "toc" via Instance Name. By changing this, the problem has been solved. I've been searching for a day and a half on this stupid error..

ENTER FRAME stops working without error

When does ENTER_FRAME stops?
1. removeEventListener(Event.ENTER_FRAME,abc);
2. error occurs or the flash crashes
3. the instance of class is removed from stage
4. ?
The story:
I have several AS document for a game,one of it contains ENTER_FRAME which adding enemies.
It works fine usually,but sometimes it don't summon enemies anymore. I didn't change anything,I have just pressed Ctrl+enter to test again.
I have used trace to check, and found the ENTER_FRAME stops.
Otherwise, I put trace into another AS file of ENTER_FRAME, it keeps running.
Another ENTER_FRAME in levelmanage class for testing if it's working, both of it and addEventListener(Event.ENTER_FRAME, process); stops too
I also don't get any errors, and I can still move my object via keys.
The levelmange class doesn't connect to any object,it shouldn't stop if anything on stage has removed.
what could be the problem?
The below as code is the one who stops operating.
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.*;
public class levelmanage extends MovieClip
{
var testing:int=0
private var sttage = ninelifes.main;
public var framerate = ninelifes.main.stage.frameRate;
public var levelprocess:Number = 0;
public var levelprocesss:Number = 0;
private var level:int;
public var randomn:Number;
public function levelmanage(levell:int)
{
level = levell;
addEventListener(Event.ENTER_FRAME, process);
}
function process(e:Event)
{
testing+=1
if(testing>200){
testing=0
trace("working")//it don't trace "working"sometimes which means enterframe doesn't going
}
if (levelprocess>levelprocesss)trace(levelprocess);
levelprocesss = levelprocess;
if (levelprocess>=100 && enemy.enemylist.length==0)
{
finish();
return();
}
if (levelprocess<=100 && enemy.enemylist.length<6)
{
switch (level)
{
case 1 :
arrange("cir",0.5);
arrange("oblong",1);
break;
}
}
}
public function arrange(enemyname:String,frequency:Number)
{
randomn = Math.random();
if (randomn<1/frequency/framerate)
{
var theclass:Class = Class(getDefinitionByName(enemyname));
var abcd:*=new theclass();
sttage.addChild(abcd);
trace("enemyadded")
switch (enemyname)
{
case "cir" :
levelprocess += 5;
break;
case "oblong" :
levelprocess += 8;
break;
}
}
}
private function finish()
{
levelprocess=0
trace("finish!");
removeEventListener(Event.ENTER_FRAME,process);//not this one's fault,"finish" does not appear.
sttage.restart();
}
}
}
It's possible you eventually hit "levelprocess==100" and "enemy.enemylist.length==0" condition, which causes your level to both finish and have a chance to spawn more enemies, which is apparently an abnormal condition. It's possible that this is the cause of your error, although unlucky. A quick fix of that will be inserting a "return;" right after calling finish(). It's also possible that your "levelmanage" object gets removed from stage somehow, and stops receiving enter frame events, which might get triggered by a single object throwing two "sttage.restart()" calls. Check if this condition is true at any time in your "process" function, and check correlation with this behavior. And by all means eliminate possible occurrence of such a condition.
if(testing>200){
testing=0
trace("working")//it don't trace "working"sometimes which means enterframe doesn't going
}
The deduction in your comment isn't correct. It means either EnterFrame isn't firing, or testing <= 200.
Try putting a trace right at the beginning of your process function.
If you don't have removeEventListener elsewhere, then it is unlikely EnterFrame is really stopping - it's hard to be sure from the example you've posted but I would bet the problem is somewhere in your logic, not an issue with the EnterFrame event itself.