AS3.0 Calling a function from an .as file from Main class

Started by
7 comments, last by jeteran 11 years, 8 months ago
Hello once again.

I'm working now on putiing everything in place.

I create i main.as file that will rule all the others.

Then I create, in the root, a com folder, then jeteran folder, then missions.as

From the main.as is calling the missions.as perfectly.

But now, inside the missions.as constructor, I'm making a class call mission1 and when I try to access it from the mail.as file, I can't.

I try different things, like missions.mission1(), MovieClip(root) and parent and I couldn't get it.

What can it be?

Thanks so much for your time !
Advertisement
Can you post an example of what you're trying to do? It could be that mission1 is private or protected, that there's no function mission1():Mission, that there's no function get mission1():Mission, etc. If your Main can instantiate Mission, I'm guessing it's something along those lines but I couldn't be sure without seeing code.
Hey greenvertex, thanks SO much for your reply.

I want to check 2 things:
1) If I'm able to call a function from inside the constructor, or;
2) If I have to make another function outside the constructor function (the present example)

I think either way it's ok. Inside the mission file, I want to have variables and code for a specific mission; for example: have the function mission1, mission2 and so on.

Ok i'm going to write the code in a simplify way so you can see what's going on:

External file "Missions.as" saved in /com/jeteran/ folder

package com.jeteran {
public class Missions {
public var mision1:Array;
public var totalObjectsMission1:uint;
public var mission1Room1:Mission1Room1;
public var mission1Room1Object1:Mission1Room1Object1;

public function Missions() {
totalObjectsMission1= 6; I can call this var from the main file.
}

public function Mission1() {
totalObjectsMission1= 6; I can't call this var from the main file.
}


Main file "Main.as" saved in root folder

package {
import flash.display.MovieClip;
import com.jeteran.Missions;
import com.jeteran.Missions.Mission1; I try this and didn't work

public class Main extends MovieClip {

private var missions:Missions; Good
private var mission1:Mission1; Then I tried this and didn't work, even :Missions.Mission1

public function Main() {
missions = new Missions();
trace(missions); Works great
trace(missions.totalObjectsMission1); Works great
trace(missions.mission1.totalObjectsMission1); Don't work
trace(mission1.totalObjectsMission1); Don't work

This is what's happening. Hope I was clear enough. What do you think it is?

BTW I have another question. I'm new to AS3.0, even though I have some good knowledge in AS1.0 The thing is that I'm try hard to learn and apply good programming tecniques, so my question is: is this a good practice? to have different files for different objects in the game? And to declare the global and local vars and function in the way I'm doing it?I believe that, in that way, I wall have better control in programming the game. I'm just having difficult to connect the codes between files.

Thanks SO SO much for your help !!
So from the example above, you're going to want to do something like this to call Mission1:


package {
import flash.display.MovieClip;
import com.jeteran.Missions;

public class Main extends MovieClip {
private var missions:Missions;

public function Main()
{
missions = new Missions();
trace(missions); //OK
trace(missions.totalObjectsMission1); //OK, should show 0
missions.Mission1();
trace(missions.totalObjectsMission1); //OK, should now show 6
}
}
}


Now why this is correct: Mission1 is not a type (class in AS3) so you can't declare a variable of type Mission1. It is a member function of the Mission type. The best way to get at it, then, is to create a new Mission instance, like you did, then use the dot (.) operator to call the function Mission1.

Also, the following code will never work:


public var mision1:Array;

//...

trace(missions.mission1.totalObjectsMission1);


This is because totalObjectsMission1 is not a member of the Array type, it is a member of the Mission type. If your Array contains Mission objects, you could do:


trace(missions[0].totalObjectsMission1);


Provided you had at least one instance of a Mission (at position 0) in the array.

BTW I have another question. I'm new to AS3.0, even though I have some good knowledge in AS1.0 The thing is that I'm try hard to learn and apply good programming tecniques, so my question is: is this a good practice? to have different files for different objects in the game? And to declare the global and local vars and function in the way I'm doing it?I believe that, in that way, I wall have better control in programming the game. I'm just having difficult to connect the codes between files.[/quote]

Sometimes this kind of question starts an OOHW (Object-Oriented Holy War) so anything I tell you here is opinion only. In AS3 most (not all, there are some pretty esoteric exceptions that I won't get into) types go into their own file. The way you've set up Main and Mission is good practice. Declaring all your class members public is not good practice though, if you never use mission1Room1 outside your Mission class, it should be private. Public variables in classes should also be treated very carefully. While it's certainly OK to declare public variables (again, my opinion), make sure that changing the values of those variables is safe no matter who does it. Otherwise, crashes and bugs are certainly going to be a big part of your future.

From what I can gather, your class structure does need some work though. Try thinking of the whole scheme like this:

  • The game has a set of missions.
  • Each mission has rooms you can visit.
  • Each of these rooms may or may not contain one or more objects.


From that list, you might want to go about things like this:


public class Main {
private var missions:Array; //The game has a set of missions
}

public class Mission {
private var rooms:Array; //Each mission has a set of rooms you can visit.
}

public class MissionRooms {
private var missionObjects:Array; //Each of these rooms may or may not contain one or more objects.
}

public class MissionObjects {
//Some behavior for a mission object.
}


The goal here is to set things up so that you can think about a piece at a time. What can a MissionObject do? Does it participate in a goal? Does it have a name? How about a MissionRoom? Does it have dimensions? Walls? Doors? Windows? And Missions? Do they have goals? Time limits? Etc.

Try and break your code into pieces that make sense on their own. Like a room, a room can exist in a hotel, a house, an office building, etc. it's still a room though and has certain properties like walls, a door, and so on.

Hopefully some of that helped, let me know if you have any questions on it, it's a lot to digest...
WOW greenvertex I'm very impressed for your careful explanation, usually, people don't stop to teach you in that way.

Ok now with the Main / Missions code.
I read what you told me and really makes sense. I modify my code to work in that way and runs correctly. If I had an array, I can save all the functions in all the position starting at 0 and call them the way you told. That’s pretty awesome.

With this done and understood, I have a question:
- Making use of that code, I saw that the first totalObjectsMission1 actually disappear; and now shows the totalObjectsMission1 of the Mission1 function. This is good so far I don’t need to use the constructor code, but what if I do? I tried to name null the Mission1 function after tracing totalObjectsMission1 and got an error, how do you think I can handle this? Considering I will have other missions to go (going a little farther, I think I can leave the Missions constructor empty and just use the other functions, what do you think?)

Ok now, about the good programming techniques.
Declaring all your class members public is not good practice though, if you never use mission1Room1 outside your Mission class, it should be private.


With this you are saying that (and thinking that class members are all the vars) I have to declare them private? If so, this is true; I have seen other codes and I found that actually, they use private vars. You say that this safer, why is that? (curiosity)

About what you gather of the small information I presented you, I have some Qs (will make you one that can help me understand the rest). But before it, I want to tell you how the game is functioning (even though you got it right)

There will be 8 missions, that will have from 3 – 7 rooms, and each room will have from 2 – 5 objects. Now:

- Well at first sight I say WOW, looks very clean and awesome. The thing is that, for example, all the missions (inside every room) will have an array of inventory objects [scissors, paper, scanner and so on (up to 4)]. I already successfully make that those objects to be left over the objects inside every room. For the objects in the room I declared another array that has all the objects in the room. Now, I made a for that finds all the objects in the inventory (objectsInv) and created a listener that listens when that object is click. If it does, stratDrag(). If it doesn’t (this is the tricky part) I declared a for that reads all the objects in the scene (mission1Objects[j]) and, if event.currentTarget.hitTestObject(mission1Objects [j]) remove listener, if it doesn’t, you inventory object go to your initial place. (Please tell me if I made myself clear)

The question is, how can I handle this? Thinking a little more, I can import the Inventory file to the Missions file, maybe? But that Inventory will interact too with a small store, so this is where I get a little confused, what do you think?

So far so good and once again, thanks so much greenvertex for your patient and time !!
Making use of that code, I saw that the first totalObjectsMission1 actually disappear; and now shows the totalObjectsMission1 of the Mission1 function. This is good so far I don’t need to use the constructor code, but what if I do?[/quote]

So this turns out to be a pretty hairy design question in my opinion. I stay clear of public functions (other than maybe the constructor of the class) that change public member variables. What does that mean? Something like this:


public class MyObject {
public var myPublic:int;
private var myPrivate:int;

//Change away here.
public function MyObject()
{
myPublic = 1;
myPrivate = 2;
}

public function doSomething():void
{
myPublic = 4; //This is bad!
myPrivate = 5; //This is OK.
}
}



function someOutsideFunction():void
{
var mine:MyObject = new MyObject();
mine.myPublic = 7;
trace(mine.myPublic); //So far so good, traces 7.
mine.doSomething();
trace(mine.myPublic); //What? I just said you were supposed to be 7, not 4!
}


You should try avoiding situations like that as much as possible.

With this you are saying that (and thinking that class members are all the vars) I have to declare them private?[/quote]

You don't HAVE to. It's just a really good idea to give each variable the lowest level of access to the outside world as possible. So if you only use a variable inside one class, make it private. That way, it can never be changed by some other class accidentally.

If so, this is true; I have seen other codes and I found that actually, they use private vars. You say that this safer, why is that?[/quote]

So this is a really contrived example but:


//MyClass
public myVar:int;

public function myFunction():void
{
if(myVar == 5) {
throw new Exception("myVar isn't supposed to be 5!");
}
}

//Later...

function causeTrouble():void
{
var myClass:MyClass = new MyClass();
myClass.myVar = 5;
myClass.myFunction();
}


You're never going to intentionally write code like that, but you may write something similar accidentally. Having private variables helps you avoid that.

- Well at first sight I say WOW, looks very clean and awesome. The thing is that, for example, all the missions (inside every room) will have an array of inventory objects [scissors, paper, scanner and so on (up to 4)]. I already successfully make that those objects to be left over the objects inside every room. For the objects in the room I declared another array that has all the objects in the room. Now, I made a for that finds all the objects in the inventory (objectsInv) and created a listener that listens when that object is click. If it does, stratDrag(). If it doesn’t (this is the tricky part) I declared a for that reads all the objects in the scene (mission1Objects[j]) and, if event.currentTarget.hitTestObject(mission1Objects [j]) remove listener, if it doesn’t, you inventory object go to your initial place. (Please tell me if I made myself clear)
The question is, how can I handle this? Thinking a little more, I can import the Inventory file to the Missions file, maybe? But that Inventory will interact too with a small store, so this is where I get a little confused, what do you think?[/quote]

So each room has a set of objects you need to use in it? Hopefully I understood that correctly or this might not make any sense:

What it seems you have is a bunch of keys that fit into a bunch of locks. For example, a pair of scissors (the key) fits into a sheet of paper (the lock). When that happens the paper gets cut (or whatever else). So maybe your setup works something like this:

  • Each room has a set of locks, all these locks are paired with a key (a unique identifier shared by both keys and locks, like a unique number or string).
  • Each room can also have keys inside it that you can pick up and add to your inventory.
  • Whenever you click and drag a key to a lock, something happens.


It would make sense to have each of your missions refer to your inventory object because they might change the contents of your inventory (add an item if you pick something up, remove one if you drop something or put something in a "lock").
Thanks once again greenvertex for your reply !


I stay clear of public functions (other than maybe the constructor of the class) that change public member variables.

Got it, I'll not do that. So that brings us to one Q I had: for example the missions, it's better to have each function separately? away from constructor? With each one having it's own vars?


So if you only use a variable inside one class, make it private.

Awesome, starting TODAY in modify this habit, thanks !


So each room has a set of objects you need to use in it? Hopefully I understood that correctly or this might not make any sense:

Crap I'm really sorry that I didn't explain myself more clearly.

In a much simpler way, you are a person that has to put things inside rooms, that are inside missions. In your inventory, you have like a microphone, a teddy bear and so on. Those inventary object you have to put them in the game objects (in a table, in a door, in a bed, and so on)

At the end, if you put the inventory objects in the game objects correctly, you gain points, if points are f.i. > 60, you can go next mission.

That's the design of the game. Besides this and before the mission, you will have to buy objects from the store that will be in your inventory (right now working on this)

But your explanation is not far from this. F.i. if you put teddy bear in the table, the teddy bear disappear and you gain +20 level points. But if you put the teddy bear in the TV, you gain +0 level points.You can't put another object in a place you already put one (I think this is done with a simple flag)

With this in mind, how can I make interact both inventory objects and game objects? So far, I have them in the same file and works great. But thinking in using better programming techniques? I thought about:
1) Create another file (for example InventoryGameInteraction) that imports and uses both inventory objects and game objects.
2) Import the game objects to the inventory objects and use them from there.

What do you think?

Thanks so much greenvertex for your time, you are really helping me out, I really appreciate it.
for example the missions, it's better to have each function separately? away from constructor? With each one having it's own vars?[/quote]

If it were me I'd most likely make a mission class like you have, and have each room maintain a mission. All missions will most likely work roughly the same way, they'll all start, and they'll all end. They all have goals (place the teddy bear on the table, etc.). If any of them behave differently, you can make a specialized type of mission by inheriting from the basic mission type (like you were inheriting from MovieClip for Main). Then each one will have its own copy of mission variables that you can set to default values in your constructor.

With this in mind, how can I make interact both inventory objects and game objects? So far, I have them in the same file and works great. But thinking in using better programming techniques? I thought about:
1) Create another file (for example InventoryGameInteraction) that imports and uses both inventory objects and game objects.
2) Import the game objects to the inventory objects and use them from there.
What do you think?[/quote]

I like the first option simply because it makes more sense to think about in a non-programming way. What I mean by that is: I tend to think about problems in terms of real-world objects. So, locks and keys, or rooms and missions. Consider: You walk into a room and in your pockets are a few items you're have to put in that room. What are you going to use to actually place them? The second option basically says you'd use your pocket to place them. The first option is easier to think about if you think of it as a "hand" that's taking something out of your pocket (inventory) and placing it in the room.
Hey greenvertex, as always, thanks so much for your response.

If any of them behave differently, you can make a specialized type of mission by inheriting from the basic mission type[/quote]
Sounds interesting, I'm going to dig more deeply to see if I got the chance to do it. Thanks !!

The first option is easier to think about if you think of it as a "hand" that's taking something out of your pocket (inventory) and placing it in the room.[/quote]
This is interesting. Actually, you will have a bar in the GUI of the game with the inventory objects there, if you want to put teddy bear in the table, the character have to be close the table, and with the mouse, you have to drag the object to the table (and wait like 5 seconds to put it)

I don't know, , , but I think we can handle it has part of your pocket. So maybe yes, the first option could be good. What do you think?

Thanks greenvertex once again !!

This topic is closed to new replies.

Advertisement