I'm having a problem with my app. I've 3 frame in the timeline, in the 2nd frame I've a MC with its own class: at the end of the animation of the MC I call a function from the main class.
THE CODE OF THE MC CLASS IS THIS
public function frame134() {
stop();
var vMainTimeline: MainTimeline = new MainTimeline();
vMainTimeline.gotoFrame3();
}
THE FUNCTION IN THE MAIN CLASS IS THIS
public function gotoFrame3() {
trace("gotoFrame3");
this.gotoAndStop(3);
trace("DONE");
}
The output in the console is gotoFrame3 and DONE but gotoAndStop(3); doesn't work.
Any suggestion or help?
Thanks in advance
Rather then creating instance of MainTimeline you need to get reference by using parent property or by referring it by stage directly. Replace your frame134() method with below code.
public function frame134() {
var stageRef = this.parent;
stageRef.gotoAndStop(3);
}
or with
public function frame134() {
stage.gotoAndStop(3)
}
Hope it will work for you.
Related
I have loaded movieClip to stage and was performing some events on that movieClip. Movie clip has own public functions and variables, and those are NOT accessible through currentTarget object in events.
Here is sample class:
package {
import flash.display.MovieClip;
import flash.display.Shape;
public class SampleClass extends MovieClip {
var str:String;
public function SampleClass() {
str="Some string";
/* draw just a sample rectangle to click on it */
var rectangle:Shape=new Shape ;
rectangle.graphics.beginFill(0x000000);
rectangle.graphics.drawRect(0,0,100,100);
rectangle.graphics.endFill();
}
public function getStr():String {
return str;
}
}
}
And here is loading on the stage and creating event:
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class MainClass extends MovieClip {
var a:SampleClass;
public function MainClass() {
a=new SampleClass();
addChild(a);
a.addEventListener(MouseEvent.CLICK,clickEvent);
}
function clickEvent(evt:MouseEvent):void {
var Obj=evt.currentTarget;
trace (Obj.getStr());
}
}
}
Tracing will return null instead of string value cause currentTarget is an Object, not a Class (movieClip). Any idea how to solve this?
//use this code it will work
function clickEvent(evt:MouseEvent):void {
var Obj:SampleClass = evt.currentTarget as SampleClass;
trace (Obj.getStr());
}
I dont know if your problem is solved now but the code you posted in your question worked okay for me..
What I did to test it..
In a new blank document, open Library (ctrl+L) and right-clicked to make symbol (MovieClip)
In linkage section, tick Export for Actionscript and call it SampleClass
Right click symbol item now added in Library list and choose Edit Class option
In that SampleClass I replace all with a paste of your code BUT NOTE: after that line rectangle.graphics.endFill();.. I also added the line addChild(rectangle);
Now when I test (Debug: Ctrl+Shift+Enter).. I see a black square that traces "Some string" everytime I click it..
Your MainClass.as was attached to the FLA as the Document Class (see Properties with Ctrl+F3)
I hope this is useful to you or anyone else trying this kind of code. Any issues just add a comment. Thanks.
I'm trying to create a intro screen then a start screen after the intro screen is done playing.
I thought the easiest way of doing this would be on scene 1 frame 1, I would create a
MovieClip.
By the way this is a separate document file. So I gave it a document class name of mcStartGameScreen and linked it to Flash Develop for actions.
Now the MovieClip that is on frame 1, I gave an instance name of startMenu then inside the startMenu MovieClip there is a MovieClip that I wanted the buttonMode enabled to be true. I add this MovieClip which is called mcStart on frame(65) inside my startMenu.
Now in my Actions I have this:
public class mcStartGameScreen extends MovieClip
{
private var mcStart:MovieClip;
private var startMenu:MovieClip;
public function mcStartGameScreen()
{
startMenu.mcStart.buttonMode = true; //This is giving me the ERROR!
mcStart.addEventListener(MouseEvent.CLICK, startOnClick);
}
private function startOnClick(e:MouseEvent):void
{
dispatchEvent(new Event("START_GAME"));
}
public function hideScreen():void
{
this.visible = false;
}
public function showScreen():void
{
this.visible = true;
}
}
When I test the movie I get this
error: Cannot access a property or method of a null object reference.
Does anyone know what I am doing wrong?
If you already have a MovieClip with instance name startMenu placed on the stage, so no need for,
private var startMenu:MovieClip; you remove this from your code.
And always have the stage instance first and then proceed.
So modify your constructor like so:
public function mcStartGameScreen()
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
startMenu.mcStart.buttonMode = true; //Now this will not give the ERROR!
startMenu.mcStart.addEventListener(MouseEvent.CLICK, startOnClick);
}
I'm making an adventure game in AS3 and have many classes. I heard it is best for performance if there is only one Enter Frame function and all update functions run from that.
I currently have a mainGameLoop in my main.as, what is the best way for all my classes to contain an update function running from this single enter frame function?
Here is an example of what I've done to run an update function in my Player class, but I don't like this solution at all.
If anyone could help it'd be much appreciated, thanks.
public class Main extends MovieClip
{
// Initialising variables...
private var m_SceneHandler:SceneHandler;
private var m_UserInput:UserInput;
public function Main()
{
// Adding main update function...
addEventListener( Event.ENTER_FRAME, mainGameLoop );
// Creating the scene handler...
m_SceneHandler = new SceneHandler();
addChild( m_SceneHandler );
}
private function mainGameLoop( event:Event )
{
doUpdate();
}
private function doUpdate():void
{
// Update player...
if (m_SceneHandler.m_aCurrentScene[0].m_Player)
{
m_SceneHandler.m_aCurrentScene[0].m_Player.doUpdate();
}
}
Use the composite pattern and code to an IUpdateable interface.
package view {
public interface IUpdateable {
function doUpdate():void;
}
}
In your main game loop, just switch out which object(s) should be updated:
package{
public class Main extends MovieClip implements IUpdateable {
protected var updateChildren:Vector. = new Vector.();
//other logic would manage who is currently updateable and who is not
public function doUpdate():void {
for each (var updateable:IUpdateable) {
updateable.doUpdate();
}
}
}
}
Then, if there are subcomponents that need to update, they could also be IUpdateable, and the higher level IUpdateable could call the method.
Before firing away, I know there are many questions here on SO that are quite similar. Yet, none of the solutions given were of any help to me, probably because my case is a little different.
I have a main class which loads an external class (separate .as file). In this external class, there are several objects which have tweens and time events bound to them.
What I want to do, is starting the animations when a certain function is called in my Main class. However, I've tried numerous things to stop and/or reset the animations in the external class, so it will start from the beginning if the required function in Main is called.
Main.as:
package {
//required imports
public class Main extends MovieClip {
var myClass:MyClass = new MyClass; //this is the external class
var button:Button = new Button; //movieclip in the library
public function Main() {
addChild(myClass); //I want to do this here so the objects show from the start
//try 1: myClass.gotoAndStop(1);
//try 2: myClass.stop();
button.addEventListener(MouseEvent.MOUSE_CLICK, playAnimation);
}
function playAnimation (e:MouseEvent) {
//try 1: myClass.gotoAndPlay(1);
//try 2: myClass.start();
//try 3: controlling the startTweening() function in MyClass, I tried different ways
}
}
}
The problem starts in the Main class above. I don't want to animate yet!
MyClass.as:
package {
//required imports
public class MyClass extends MovieClip {
//vars
public function MyClass() {
startTweening();
}
function startTweening() {
//tween event
//calling next function (with use of a TimerEvent) after tween is done. This is repeated several times.
}
}
}
Everything in this class works fine, so that's not the problem.
If this makes any difference, I used TweenMax in MyClass for tweening. I didn't use the timeline in the .fla.
Any help would greatly appreciated!
If you don't want to animate at creation of MyClass remove startTweening(); call from the constructor of MyClass.
Make startTweening(); a public function and call it whenever your need with myClass.startTweening().
Here the MyClass
public class MyClass extends MovieClip {
//vars
public function MyClass() {
}
public function startTweening() {
//tween event
//calling next function (with use of a TimerEvent) after tween is done. This is repeated several times.
}
}
and here the Main class
public class Main extends MovieClip {
var myClass:MyClass;
var button:Button = new Button; //movieclip in the library
public function Main() {
myClass = addChild(new MyClass()) as MyClass;
button.addEventListener(MouseEvent.MOUSE_CLICK, playAnimation);
}
function playAnimation (e:MouseEvent) {
myClass.startTweening();
}
}
I'm trying to play a movie clip when I mouse_over it. I can do it fine by doing:
mc1.addEventListener(MouseEvent.MOUSE_OVER,mover);
function mover(e:MouseEvent):void {
mc1.play();
}
But, I want to use the same function for other movie clips, for example, to play movieclip2, movieclip3 etc.
How would I achieve this?
mc1.addEventListener(MouseEvent.MOUSE_OVER,mover);
mc2.addEventListener(MouseEvent.MOUSE_OVER,mover);
mc3.addEventListener(MouseEvent.MOUSE_OVER,mover);
function mover(e:MouseEvent):void {
e.currentTarget.play();
}
You can make a class to encapsulate your logic for example, to access the MovieClip from the calling function, use the property of the Event object
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class PlayMovieClip {
// register the mouse over event with whatever MovieClip you want
public static function register(mc:MovieClip):void{
mc.addEventListener(MouseEvent.MOUSE_OVER,mover);
}
// unregister the event when you dont need it anymore
public static function unregister(mc:MovieClip):void{
mc.removeEventListener(MouseEvent.MOUSE_OVER, mover);
}
// the MouseEvent will be throw whenever the mouse pass over the registered MovieClip
// and in the MouseEvent property you have the targeted object
// so use it
public static function mover(e:MouseEvent):void{
// check if we have really a MovieClip
var mc:MovieClip=e.currentTarget as MovieClip;
if (mc!==null) {
// we have a MovieClip so we can run the function play on it
mc.play();
}
}
}
usage:
PlayMovieClip.register(mc1);
...
PlayMovieClip.register(mcX);
and to remove the event:
PlayMovieClip.unregister(mc1);
...
PlayMovieClip.unregister(mcX);