Toon posts:

[as2]instance maken met dynamische classname

Pagina: 1
Acties:

Verwijderd

Topicstarter
ik wil in actionscript2 class-instances kunnen aanmaken adhv een dynamische classname. de methode die ik hiervoor op diverse plaatsen tegenkom is deze:
Flash ActionScript:
1
2
var cName:String = "Testclass";
var myInstance:Object = new _global[cName]();

dit lijkt bij mij echter niet te werken, tenzij ik al eerder een instantie van de betreffende class heb aangemaakt:
Flash ActionScript:
1
2
3
var myInstance1 = new Testclass();
var cName:String = "Testclass";
var myInstance2:Object = new _global[cName]();

als ik voor het aanmaken van de instances check met typeof(_global["Testclass"]) is die wel aanwezig als type function.
Doe ik nou iets verkeerd, of moet je inderdaad altijd eerst een instantie van je class hebben gemaakt?

Verwijderd

Het lijkt erop dat ergens in het script een referentie naar "new classname()" moet staan, omdat anders de geïmporteerde class niet ineens in de _global voorkomt (zie alle properties van _global). Hoe je dit toch dynamisch kan realiseren, zodat je het met new _global[classname] kan aanroepen.. wist ik het maar!

edit:
Eerdere (loze) opmerking over trace() vervangen.

[ Voor 185% gewijzigd door Verwijderd op 27-03-2006 17:09 ]


Verwijderd

Topicstarter
ik heb deze testclass:
code:
1
2
3
4
5
6
7
8
class Testclass {

    public function Testclass(msg:String) {
        if (!msg) msg = "no msg";
        trace("Testclass ("+msg+")");
    }

}

wanneer ik deze mbv een dynamische naam instantieer wordt er niets getracet, wanneer ik eerst "statisch" een instance maak en daarna dynamisch, krijg ik tweemaal een trace.

[ Voor 9% gewijzigd door Verwijderd op 27-03-2006 12:40 . Reden: stond nog packagenaam bij die niet klopt met rest van code ]


Verwijderd

Topicstarter
ik kom er net achter dat wanneer ik dit doe:
code:
1
2
3
4
5
6
instantiate = function() {
    var myInstance:Object = new Testclass();
}

var cName:String = "Testclass";
var myInstance2:Object = new _global[cName]();

dat het dan met de dynamische classname wel werkt, zelfs wanneer ik de functie instantiate() niet heb uitgevoerd :?
op zich zou dit mij kunnen helpen omdat het in mijn huidige toepassing gaat om een set classes met namen Tile0 t/m Tilen. Daarbij is nog onbekend hoeveel classes het zijn, maar ik zou dus zo'n functie als hierboven kunnen maken waarin je achtereenvolgens een ruime hoeveelheid instances aanmaakt (wanneer je er 10 nodig denkt te hebben er 50 definieren):
code:
1
2
3
4
5
6
7
8
instantiate = function() {
    var myInstance:Object = new Tile0();
    myInstance = new Tile1();
    myInstance = new Tile2();
    ...
    myInstance = new Tile100();
    delete myInstance;
}

mooi is anders natuurlijk. Ook weet ik niet zeker of die aangemaakte instances verdwenen zijn wanneer je myInstance verwijdert, of dat ze nog ergens in het geheugen staan.
edit:
natuurlijk staan ze niet in het geheugen, de functie wordt immers niet eens uitgevoerd

Heeft iemand een betere suggestie?

[ Voor 6% gewijzigd door Verwijderd op 27-03-2006 15:06 ]


Verwijderd

Geen bettere suggestie, maar een kleine tweak. Volgens een posting bij Flashcoders is het enkel nodig om de volledige classname te noemen. Je hoeft dus geen instanties te maken van alle benodigde classes. Scheelt weer iets aan handelingen, tijd, geheugen, etc.

  • sanderb
  • Registratie: November 2000
  • Laatst online: 23-02 19:39
geen oplossing voor je probleem maar een vraag...
verschillen die classes zoveel van elkaar dat je er uberhaupt 100 nodig hebt?
waarin verschilt tile1 van tile100, en als het alleen andere waarden van properties zijn, dan kun je die toch ook meegeven als je hem aanmaakt?

" A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools. " - Douglas Noel Adams


Verwijderd

Topicstarter
ik wil een tilebased game maken, die ik naderhand eenvoudig kan uitbreiden. de levels bouw ik op mbv een map waarin per tile staat welk type het is. ik wil het zo maken dat wanneer je een nieuw type tile wilt introduceren, je alleen maar die tile in de map hoeft te zetten en er een nieuwe class voor hoeft te maken. Elke tileclass geeft dan informatie over wat er moet gebeuren als de speler er op staat.
In vrijwel alle tutorials die ik ben tegengekomen wordt dergelijke informatie min of meer hard in de code gezet die de speler bestuurt (if type=1 doe dit, if type=2 doe dat, etc). Ik hoop dat dit een beetje duidelijk is. Ik weet zelf overigens nog niet precies hoe en of ik het ga klaarspelen.
hoeveel tiles ik nodig ga hebben weet ik nog niet; ik verwacht geen 100, maar met 100 weet ik tenminste zeker dat ik er genoeg heb.

[ Voor 9% gewijzigd door Verwijderd op 28-03-2006 09:34 ]


  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 16-01 10:51
Waarom maak je niet gewoon 1 basis tile class en extend je deze met verschillende soorten behaviours? En koppel je die nieuwe Tile classes aan de juiste tiles (movieclips).

[ Voor 27% gewijzigd door McVirusS op 28-03-2006 11:38 ]


Verwijderd

Topicstarter
Ik maak inderdaad 1 class Tile die ik extend voor alle verschillende tiles. Ik wil proberen om de game volgens het model-view-controller pattern te te organiseren, en uit dat oogpunt wil ik de classes niet direct aan movieclips hangen (die deel uitmaken van de view), maar koppelen aan mijn model.
Of begrijp ik je antwoord nu niet goed?

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 16-01 10:51
Verwijderd schreef op dinsdag 28 maart 2006 @ 14:11:
Ik maak inderdaad 1 class Tile die ik extend voor alle verschillende tiles. Ik wil proberen om de game volgens het model-view-controller pattern te te organiseren, en uit dat oogpunt wil ik de classes niet direct aan movieclips hangen (die deel uitmaken van de view), maar koppelen aan mijn model.
Of begrijp ik je antwoord nu niet goed?
Jawel je begrijpt m'n antwoord wel goed ;).

Al eens naar registerClass gekeken?

Het is alleen niet heel erg duidelijk hoe je dat met AS2.0 classes moet gebruiken. Ik heb het even opgezocht:

Flash ActionScript:
1
2
3
4
import Test;
Object.registerClass("movieclip", Test);

var mc = this.attachMovie("movieclip","mc",1);


"movieclip" is overigens de linkageidentifier van de movieclip die ik attach (zoals al duidelijk is uit het voorbeeld waarschijnlijk). Doet dit ongeveer wat je wilt?

[ Voor 3% gewijzigd door McVirusS op 30-03-2006 10:47 ]


Verwijderd

Topicstarter
ik heb idd naar registerClass gekeken, maar ik wil de classes niet aan de mc's koppelen, zoals registerClass doet, maar andersom.
in mijn opzet heb ik 3 componenten: het model, de view en de controller. Het model houdt de status bij van alle objecten, de view is de grafische representatie van het model en de controller zorgt voor het aansturen van model en view. concreet:
  • de view bevat een world-movieclip met daarin alle tile-mc's en mc's voor player, enemies etc.
  • het model bevat voor alle elementen uit de view een class-instance (met daarin o.a. een referentie naar de bijbehorende mc in de view)
  • de controller stuurt bv de player aan, en haalt daarbij benodigde info uit het model.
Bij het aanmaken van een level doe ik dus twee dingen: ik attach een mc voor elke tile in de view, en ik maak een class-instance voor die tile aan in het model.
wanneer ik nu de classes aan de mc's zou koppelen, komt de informatie over de status etc van de objecten in de view terecht, ipv in het model, en dat wil ik niet.

Wat betreft het oorspronkelijke probleem lijkt het er overigens op dat het gedrag voor native Classes anders is dan dat voor custom classes. Wanneer ik mijn allereerste voorbeeld pak:
code:
1
2
var cName:String = "Testclass";
var myInstance:Object = new _global[cName]();

(wat dus niet werkt) en die techniek gebruik om een array te maken:
code:
1
2
3
var cName:String = "Array";
var myInstance:Object = new _global[cName]("nul","een");
trace(myInstance[0]);

werkt dat wel, terwijl het met een eigen class niet werkt.

[ Voor 22% gewijzigd door Verwijderd op 30-03-2006 12:06 ]


  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 16-01 10:51
Ik zie toch niet helemaal in wat er mis is met het vermengen van de view/model in jouw voorbeeld. Als het schermelementen zijn die een bepaald gedrag moeten hebben waarom zou je dan niet het model linken aan die movieclip? Heb het idee dat je het jezelf beetje te moeillijk maakt ;).

Ik snap na je laatste voorbeeld echter wel ineens je probleem. Eens kijken of ik daar oplossing voor kan vinden.

Verwijderd

Topicstarter
Het idee achter de scheiding van view en model is dat je meerdere views van een model kunt hebben; je zou bijvoorbeeld één view kunnen hebben van de ruimte waarin je je bevindt, en één met een overzicht van alle ruimtes. beide views worden dan op basis van hetzelde model samengesteld, en daarom wil je alle data in het model hebben en niet in de view.
Of het in mijn geval strikt noodzakelijk is weet ik ook nog niet, maar ik wil graag proberen het zo netjes mogelijk op te zetten.

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 16-01 10:51
Het was even zoeken en heel wat testen maar ik heb denk ik gevonden wat jij zocht. Het heet de ClassFinder en zit goed weggestopt in Flash. Je gebruikt 'm zo:

Flash ActionScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Test.Test2;
import mx.utils.ClassFinder; 

/*
Dit is helaas nodig om de classfinder te gebruiken,
er moet een dependancy link naar de Class zijn.
*/
var SomeClassDependancy = Test.Test2;

// Naam van class (met package erbij)
var cName = "Test.Test2";

// Do the magic trick
var myClass = mx.utils.ClassFinder.findClass(cName);
var el = new myClass();


Als je vragen hebt hoor ik het wel ;).

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 16-01 10:51
Kleine aanvulling, eigenlijk is dit natuurlijk beetje vreemde manier. Je zou ook gewoon een array kunnen maken met classes en 'm daar gewoon uit kunnen halen.

Iets ala:
Flash ActionScript:
1
2
3
4
5
var classes = new Object();
classes.TileType1 = Tiles.TileType1;
classes.TileType2 = Tiles.TileType2;

var el = new classes["TileType1"];

Verwijderd

Topicstarter
wow, bedankt voor de moeite die je hierin gestoken hebt! Het merkwaardige blijft dat zowel bij deze twee constructies die jij aangeeft als bij de oplossing die ikzelf boven gevonden had het altijd nodig is om in elk geval ergens de class namen hard te coderen. Eerlijk gezegd vind ik dat geen van de varianten echt een schoonheidsprijs verdient, maar ik kan het nu in elk geval op drie manieren oplossen. Nu alleen nog beslissen hoe... ;)

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 16-01 10:51
Verwijderd schreef op maandag 03 april 2006 @ 17:02:
wow, bedankt voor de moeite die je hierin gestoken hebt!
Graag gedaan, ik vond het intressant ;).
Het merkwaardige blijft dat zowel bij deze twee constructies die jij aangeeft als bij de oplossing die ikzelf boven gevonden had het altijd nodig is om in elk geval ergens de class namen hard te coderen.
Op zich is dat natuurlijk wel logisch, anders weet Flash niet welke classfiles er moeten worden geinclude. Echt mooi is het niet natuurlijk. Je zou verwachten dat een import er al voor zorgt dat de classes worden opgenomen in de Flash file/_global array. Maar dat is dus niet het geval, erg jammer :).
Eerlijk gezegd vind ik dat geen van de varianten echt een schoonheidsprijs verdient, maar ik kan het nu in elk geval op drie manieren oplossen. Nu alleen nog beslissen hoe... ;)
Ben ik het mee eens maar het is volgens mij beetje inherent aan de manier waarop AS2.0 en Flash werkt. Ben benieuwd hoe je het uiteindelijk gaat oplossen :).

Verwijderd

Is het dan per sé nodig dat je Tile class een MovieClip extend? Ik heb ook verschillende games gemaakt die op tiles waren gebaseerd (ook voor bv. collision detection). Hiervoor heb ik zover ik me kan herinneren nog nooit een MovieClip als tile gebruikt.

Daarnaast kan ik me niet voorstellen dat je zoveel type tiles hebt. Ik ga er vanuit dat je een solid, transparant, misschien wat bonus tiles en dat was het dan wel zo ongeveer.

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 16-01 10:51
Verwijderd schreef op dinsdag 04 april 2006 @ 10:07:
Is het dan per sé nodig dat je Tile class een MovieClip extend? Ik heb ook verschillende games gemaakt die op tiles waren gebaseerd (ook voor bv. collision detection). Hiervoor heb ik zover ik me kan herinneren nog nooit een MovieClip als tile gebruikt.
Hij wilde juist niet dat z'n Tile classes een movieclip extenden ;).
Daarnaast kan ik me niet voorstellen dat je zoveel type tiles hebt. Ik ga er vanuit dat je een solid, transparant, misschien wat bonus tiles en dat was het dan wel zo ongeveer.
Ligt er helemaal aan wat je aan het maken bent toch? Er zijn vast wel situaties te bedenken waar je veel soorten tiles wilt hebben. Bijvoorbeeld bij erg uitgebreide games.

Verwijderd

Topicstarter
ik heb nog geen idee hoeveel types tiles ik nodig ga hebben; maar ik hoopte het zo op te zetten dat ik dat ook niet hoef te weten. Ik wil eigenlijk aleen een soort basis-engine maken, die ik dan voor verschillende toepassingen desgewenst zou kunnen uitbreiden. Los van de uiteindelijke implementatie vind ik het ook gewoon leuk om te kijken hoe ik het zo uitbreidbaar mogelijk kan maken.
Pagina: 1