how to add a movieclip to second frame of main timeline through document class? - actionscript-3

i simply have one layer which has two frames
frame 1 : menu with only one button
frame 2 : blank but with document class want to put Movie Clip named circle
I want to put it that way because i will program the symbol to draw ....(till now wrote nothing)
In document class till now i have written
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 ourShip:circle = new circle()
//our constructor function. This runs when an object of
//the class is created
public function engine()
{
ourShip.x = stage.stageWidth / 2;
ourShip.y = stage.stageHeight / 2;
addChild(ourShip)
}
}
}
First frame button as file :
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
{
}
}
}
By the way i only know addchild (which i wrote in as here,right now it would display circle in both frame 1 and frame 2 but i want it in only frame 2)

Because of how the Flash timeline works, you can only add something to a frame when you are there. So you can do,
goToAndStop(3);
addChild(myClip);
But then if you leave frame 3 it is gone forever.
You can
Add the code to the individual frame of the timeline, or
You can create a simple Event listener like below
Adding Event Listener:
addEventListener(Event.ENTER_FRAME, function() {
if (this.currentFrame == 3) {
addChild(myClip)
}
})

Related

Main class was not the first class which was called in ActionScript 3.0

I have a weird problem in a game which I want to create. At first I have created a project without external classes.
On the root I have three Characters and one Level. Also there is a script for the key listeners and I have eventListeners to register the level, levelElements, coins and the characters. Then I have a CharacterControl MovieClip in the library. This MovieClip contains the character behaviour. As example walk, jump, idle, gravity if not colliding to the ground. There are also different events and eventListeners.
The scripts are on the timeline. If I call in both timelines a trace-function, the root was called before the CharacterController.
After that in my next exercise I created a document class Main. Now there are all root scripts. And for the CharacterController I also copied the timeline code and put it into an external class.
Now my problem is that the CharacterController class is called before the main class gets called. This leads to the problem that the eventListener and events can't get called in right order. There are happening a few errors. No Coin and no Character collides on the ground or a plattform. Everything is falling down.
How can I achieve that the Main gets called at first? Should I remove the characters and create them by script?
EDIT:
Ok, I give a short example which shows the basic problem without the complex code of my game.
package {
import flash.display.MovieClip;
public class Main extends MovieClip {
public function Main() {
trace("main was called");
}
}
}
package {
import flash.display.MovieClip;
public class My_Circle extends MovieClip {
public function My_Circle() {
// constructor code
trace("circle was called");
}
}
}
Here are some pictures of the configuration and structure of my project:
I need Main called as first. I think it's a basic problem in as3.
You'd make the class file of your stage Main.as in the properties pane.
Edit: Interesting. Just replicated this. I believe then that flash/air constructs elements so they're ready to be put on the stage instead of constructing the stage first and elements after. You should put the code you want to execute for your circle in some sort of init function and execute it in.
package
{
import flash.display.MovieClip;
public class Main extends MovieClip
{
public function Main()
{
super();
trace("Hello");
(circle_mc as Circle).init();
}
}
}
Circle:
package
{
import flash.display.MovieClip;
public class Circle extends MovieClip
{
public function Circle()
{
super();
}
public function init():void
{
trace("World");
}
}
}
ok, I figured out a simple solution how you can make it by code. At first I think it's a better solution to create the object (circle, character, whatever) by code.
The timeline code:
import flash.events.Event;
Main.setStageRef(this.stage); //Super-important
stop();
The Main class code:
package {
import flash.display.MovieClip;
import flash.display.Stage;
import flash.display.DisplayObject;
import flash.events.Event;
public class Main extends MovieClip {
public static var stageRef : Object = null;
var movieClipExample : My_Circle;
public function Main() {
this.addEventListener(Event.ENTER_FRAME,this.afterMainTimeLine);
stage.addEventListener("myEvent", myEventFunction);
}
public function afterMainTimeLine(e:Event) {
trace("Hello");
movieClipExample = new My_Circle;
movieClipExample.init();
stageRef.addChild(movieClipExample);
removeEventListener(Event.ENTER_FRAME, this.afterMainTimeLine);
this.addEventListener(Event.ENTER_FRAME,this.updateFunction);
}
public function updateFunction(e:Event){
movieClipExample.moveFunction();
}
public function myEventFunction(_event: Event) {
trace("myEvent was triggered");
}
//Getter/setter for stage
public static function setStageRef(_stage : Object) : void
{
stageRef = _stage;
}
public static function getStageRef() : Object
{
return stageRef;
}
}
}
The Object code (as example My_Circle):
package {
import flash.display.MovieClip;
import flash.display.Stage;
import flash.display.DisplayObject;
public class My_Circle extends MovieClip {
public function My_Circle()
{
stageRef = Main.getStageRef();
trace("World");
this.x = x;
this.y = y;
var evt = new Event("myEvent", true);
stageRef.dispatchEvent(evt);
}
public function init():void
{
trace("Created Circle");
this.x = 300;
this.y = 100;
}
function moveFunction(){
this.y += 1;
}
}
}
The output is following:
Hello
World
myEvent was triggered
Created Circle
Maybe this could be helpful for others.
Just one thing. For different objects from the same class it's better to use an array. The position (maybe) should be random.

Add your Stage in a ScrollWindow ActionScript 3.0

I'm gonna try explaining my situation with images, to make sure that everyone will understand what i want to succeed.
First of all i have 3 files:
GenImage.fla which is linked to class GeneralImage.as
and it only contains the following picture (I tried to make the image Movie Clip but again it's not working):
Pic1
and a file named ScrollUI.as which contains the class ScrollUI.
What i want to succeed is from my GeneralImage class to create a ScrollUi item, pass the stage, and there create a ScrollPane which makes the picture look like this:
Pic2
The center part of the second image is the ScrollPane Component, which i need to make it Scrollable through the whole image. I managed to get it in my screen but i can't put the Stage in it and make it scrollable.
These are my codes :
GeneralImage.as
package {
import flash.display.*;
import flash.events.*;
import flash.display.Stage;
import ScrollUI;
public class GeneralImage extends MovieClip
{
public function GeneralImage()
{
var k = new ScrollUI();
k.ScrollConstructor(this);
}
}
}
ScrollUI.as
package
{
import flash.display.*;
import flash.events.*;
import fl.containers.ScrollPane;
import fl.events.ScrollEvent;
import fl.controls.ScrollPolicy;
public class ScrollUI extends MovieClip
{
private var _mainStage:Stage;
var aBox:MovieClip = new MovieClip();
var aSp:ScrollPane = new ScrollPane();
public function ScrollUI()
{
}
function ScrollConstructor(stage:Object):void
{
_mainStage = (stage as MovieClip).stage;
aBox == stage as MovieClip;
aSp.source == aBox ;
_mainStage.addChild(aBox);
aSp.setSize(300,300);
aSp.move(150, 75);
aSp.scrollDrag = true;
aSp.horizontalScrollPolicy=ScrollPolicy.OFF;
_mainStage.addChild(aSp);
}
}
}
So what i want it to set the Source of the Scroll Pane ( which is named aSp ) to be the _mainStage which is the stage i get from GeneralImage
Your issues is likely these two lines:
aBox == stage as MovieClip;
aSp.source == aBox ;
You're doing a comparison by using two ==, which effectively does nothing in your case. Use a single = to assign a value.
This is how I would suggest you approach this:
In the FlashPro library, find your image asset (I'm going to assume you have it wrapped in a MovieClip), right-click (or command click) and go to it's properties. Check the "export for actionscript" box, and give it a meaningful class name (for my example, I'll assume you called it MyImage)
Then you could do the following:
ScrollUI Class
package
{
import flash.display.Sprite;
import fl.containers.ScrollPane;
import fl.events.ScrollEvent;
import fl.controls.ScrollPolicy;
public class ScrollUI extends Sprite
{
//just declare the variables here, don't assign them new values
private var aBox:MovieClip;
private var aSp:ScrollPane;
public function ScrollUI()
{
//use the actual constructor...
aSp = new ScrollPane(); //instantiate a new scroll pane
addChild(aSp); //add the scroll pane to the display
aBox = new MyImage(); //instantiate an new MyImage from the library
//set the scroll pane properties
aSp.source = aBox; //you had two = signs here before, which doesn't actually assign anything it compares
aSp.setSize(300,300);
aSp.move(150, 75);
aSp.scrollDrag = true;
aSp.horizontalScrollPolicy=ScrollPolicy.OFF;
}
}
}
Document Class
package {
import ScrollUI;
public class GeneralImage extends MovieClip
{
public function GeneralImage()
{
var k:ScrollUI = new ScrollUI(); //create a new instance of the ScrollUI class
addChild(k); //add the scrollUI object to the display;
//OR, you just do this:
//addChild(new ScrollUI());
}
}
}
You could also just set the .source property of the scroll pane to the physical path of your image.
I found the solution, Thanks Batman for his help, I changes some things into my code and the program is working.
First of all as Batman said , In my GenImage.fla i made the logo a MovieClip and i named it "wholemap"
Here are my codes :
GeneralImage.as
package {
import flash.display.*;
import flash.events.*;
import flash.display.Stage;
import ScrollUI;
public class GeneralImage extends MovieClip
{
//as Batman indicated, I should have used the ScrollUI constructor, but
//except for the Stage, i also send the wholemap that is in my GenImage.fla
//<< this.getChildByName("wholemap") as MovieClip) >>
public function GeneralImage()
{
var k = new ScrollUI(this, this.getChildByName("wholemap") as MovieClip);
}
}
}
ScrollUI.as
package
{
import flash.display.*;
import flash.events.*;
import fl.containers.ScrollPane;
import fl.events.ScrollEvent;
import fl.controls.ScrollPolicy;
public class ScrollUI extends MovieClip
{
private var _mainStage:Stage;
var aBox:MovieClip = new MovieClip();
//So our constructor gets 2 items, a Stage, and a MovieClip
public function ScrollUI(stage:Object, pic:MovieClip)
{
//We set the Stage at the variable _mainStage with that way:
_mainStage = (stage as MovieClip).stage;
//We set the Image that we will take at our clip variable :
var clip:MovieClip = pic;
//And we send the Movieclip (clip) in our ScrollConstructor function
ScrollConstructor(clip);
}
function ScrollConstructor(Clip:MovieClip):void
{
var aSp:ScrollPane = new ScrollPane();
aBox = Clip;
_mainStage.addChild(aBox);
aSp.source = aBox ;
aSp.setSize(300,300);
aSp.move(150, 75);
aSp.scrollDrag = true;
aSp.horizontalScrollPolicy=ScrollPolicy.OFF;
aSp.verticalScrollPolicy=ScrollPolicy.OFF;
_mainStage.addChild(aSp);
}
}
}
Thank you very much for your assistance, I hope if someone else come across with this problem to be able to solve it with this Answer

How do I fix the error 1120: Access of undefined property?

While sitting, watching and reading about framework, I tried it and cant get my program going.
So when I programmed I had 3 frames. One for pre loader, one for Game (no menu, just straight to game), and one last one for me to keep notes and patch note etc in.
I coded in the frame. I didnt have any extra .as files or nothing, and it all works.
Then I tried converting to having a GameControler.as and a C.as (for constant values etc), and that didn't work.
So I started over, and ended up just trying it out and ended with this code:
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.*;
import flash.utils.*;
import flash.ui.*;
import Game.*;
public class GameController extends MovieClip {
private var score: Number;
public function GameController() {
// constructor code
}
public function startGame() {
score = C.score;
stage.addEventListener(Event.ENTER_FRAME, update);
}
public function scoreF(e: MouseEvent):void {
score = score + 1;
}
hitBtn.addEventListener(MouseEvent.CLICK, scoreF)
private function update(e: Event) {
score_n.text = String(score);
}
}
}
I end up with these two errors.
Line 30, Column 3 1120: Access of undefined property hitBtn.
Line 30, Column 45 1120: Access of undefined property scoreF.
What am I not understanding?
I just wanna click the button, witch is on stage, add up the score and update the on stage score.
Even though your question was answered, here is a pattern you might want to follow:
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.*;
import flash.utils.*;
import flash.ui.*;
import Game.*;
public class GameController extends MovieClip {
private var hitBtn:MovieClip;
private var score: Number;
public function GameController() {
// constructor code
createChildren();
}
protected function createChildren():void {
// when it was not read from the display list
// or created in a subclass via inheritence
if (!hitBtn) {
hitBtn = getChildByName('hitBtn') as MovieClip;
if (hitBtn) {
hitBtn.addEventListener(MouseEvent.CLICK, scoreF);
} else {
trace('Child #hitBtn is not found or not a MovieClip.').
}
}
}
public function startGame() {
score = C.score;
if (stage) {
stage.addEventListener(Event.ENTER_FRAME, update);
} else {
trace("Attempt to start the game, although the controller is not added to stage.");
}
}
public function scoreF(e: MouseEvent):void {
score = score + 1;
}
private function update(e: Event) {
score_n.text = String(score);
}
}
}
When using Flash to add children, those are added to the MovieClip when it is created, so you can access them right away. Following the pattern will give you more safety when working on larger projects, which sometimes change ... this way you can get very fast an idea of what's wrong.

AS3, Adding an event listener to a constructor class?

this is probably really simple I cannot for the life of me work out why this is not working. I am trying to create an object (only for testing) and assign event listeners within the constructor. In my head it should work but I am sure I must be missing something:
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class Box extends MovieClip {
public function Box() {
// constructor code
var mySound:Sound = new Bark();
trace("Box created");
height=800;
width=300;
x=100;
y=100;
addEventListener(MouseEvent.MOUSE_OVER, overThis);
addEventListener(MouseEvent.CLICK, clickToPlay);
}
public function overThis(m:MouseEvent){
trace("SADF");
}
function clickToPlay(m:MouseEvent){
mySound.play();
}
}}
By doing this i wanted the "box" to be self sufficient in regards to managing its own events. (Please ignore stuff like play(), that all works when I run within the MAINDOC.as directly.
This is the main doc:
package {
import flash.display.MovieClip;
import flash.media.Sound;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
public class MainDoc extends MovieClip
{
public function MainDoc()
{
// constructor code
init();
function init()
{
createBox(300,300);
}
function createBox(newX,newY)
{
var box = new Box();
box.x = newX;
box.y = newY;
addChild(box);
}
}
}}
When I test it creates the box (which i have drawn) but does not run any events?
Hope you guys can help
Ray
You have to add some graphics to your box so your MouseEvents can work:
public function Box()
{
// constructor code
var mySound:Sound = new Bark();
trace("Box created");
// begin the filling of some graphics, you can change color/alpha as you want
this.graphics.beginFill( 0x000000, 1 );
// make a rectangle 300x800
this.graphics.drawRect(0,0,300,800);
// stop filling
this.graphics.endFill();
// you don't need it anymore
//height=800;
// you don't need it anymore
//width=300;
// place your clip where you want but you do that in the Main class so no need there
//x=100;
//y=100;
// now you have graphics attached to your MovieClip the MouseEvent must work
addEventListener(MouseEvent.MOUSE_OVER, overThis);
addEventListener(MouseEvent.CLICK, clickToPlay);
}
Hope that will help you :)

Communication between the Document Class and MovieClip Class: error 1009

I am learning how to make MovieClip classes. All I am trying to do is give the MovieClip the ability to move with the left and right arrow keys, but it's not working.
Here is my code for my Document Class Main:
package {
import flash.display.MovieClip;
public class Main extends MovieClip{
var blueBall:Ball = new Ball; //This is line 7
public function Main()
{
addChild(blueBall)
}
}
}
My code for my Ball class is:
package
{
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Ball extends MovieClip
{
public function Ball()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed); //This is Line 11
}
function keyPressed(evt:KeyboardEvent):void
{
switch (evt.keyCode)
{
case Keyboard.RIGHT :
this.x += 10;
break;
case Keyboard.LEFT :
this.x -= 10;
break;
}
}
}
}
When I run this in the debug, I get this error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Ball()[C:\Users\Joel\Desktop\Flash\Projects\DropClassTest\Ball.as:11]
at Main()[C:\Users\Joel\Desktop\Flash\Projects\DropClassTest\Main.as:7]
Now, if I just leave my Main document class blank, and just drag and drop the blueBall Movieclip out of the Library, it works the way I want it to, but once I try to use the document class to do it, it's not working.
Needless to say, I am quite lost, even thought the debugger is telling me what lines are wrong.
Any ideas?
The problem is that you are trying to access the stage from inside the Ball class before the ball is added to the stage. Before an object is added to the stage, it does not have direct access to the stage.
Option 1: You could pass the stage from the main class to the Ball constructor.
Add this to your Ball class' imports:
import flash.display.Stage;
Add a stage parameter to the Ball class' constructor:
public function Ball(stage:Stage):void {
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
}
And pass the stage to your Ball instance (in Main)
var blueBall:Ball = new Ball(stage);
Option 2: You can listen for the ADDED_TO_STAGE event inside of the Ball class and add the KEY_DOWN listener once ADDED_TO_STAGE occurs:
Inside the Ball class import the Event class:
import flash.events.Event;
Replace your constructor with this:
public function Ball():void {
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
Then add your KEY_DOWN listener inside the ADDED_TO_STAGE listener:
function addedToStage(evt:Event):void {
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
}