[ cobragangsta @ 05.04.2010. 17:24 ] @
pokusavam da savladam oop u AS3.0. Znam solidno C (proceduralno) ali OOP nisam radio ni u kom jeziku (do sad, kad ucim AS)
problem mi je sta treba biti u jednoj klasi. Za jednostavne stvari to je OK (nar vozilo, zgrada itd)
medjutim kada bih hteo nesto sto nije tako "opipljivo" (nesto apstraktno) ne umem da sklopim sta treba pripadati klasi.

zamolio bih sve koji poznaju materiju da u postuju primere klasa ili linkove ka primerima.
Mislim da ce mnogima koristiti!

pokusao sam radi vezbe da napravim delove travijana (samo u swf, ne serverski deo)
dakle:
klase
class selo
class stanovnici
class skladiste
class silos
class resursi
class glina extends resursi
class zito extends resursi
class gvozdje extends resursi
class drvo extends resursi

sto je bilo relativno jednostavno. Radi na klik, ima tajmer... i naterao sam ga da funkcionise
tek da ne bude da nisam nista radio!

PS mogu se postovati i klase pisane u C++

znam da AS nije najsrecniji izbor za ucenje oop-a, al sta je tu je


Zelim da se zahvalim unapred svima koji budu doprineli ovoj temi
[ StarCraft @ 06.04.2010. 10:59 ] @
Postoji mnogo mnogo načina da organizuješ svoje klase i to je u suštini posebna nauka. Za neke veće projekte treba baš puno posvetiti pažnje organizaciji klasa (MVC pattern...) dok je za manje projekte to - manje bitno (a u flashu postoje i oni najmanji projekti - baneri)

Igrice su priča za sebe - više suve logike, manje "naprednih tehnika". I igre su možda najpraktičnije da se uzmu kao primer za objašnjavanje OOP-a.

Aj da počnemo od flash AS3 helpa. Pogledaj recimo ovu klasu (TextField)
http://livedocs.adobe.com/flas...efV3/flash/text/TextField.html
Primetićeš da postoji "inheritance" (tzv. "nasleđivanje" klasa). Konkretno, textField nasleđuje sledeće klase:
TextField > InteractiveObject > DisplayObject > EventDispatcher > Object
Sve klase u flashu potiču od Object klase (čak i Number, String... baš sve). Ovo konkretno znači da SVE klase u flashu imaju SVE osobine koje ima Object klasa. A gore navedeni textField pored toga ima SVE osobine koje imaju svi EventDispatcher-i i SVE osobine koje imaju DisplayObject-i i InteractiveObject-i. I konačno na kraju TextFieldovi koji imaju svoje jedinstvene osobine (osim klasa koje dalje nasleđuju TextField, ali mislim da takvih nema)

Tako recimo, u ovom tvom travian primeru, trebalo bi da napraviš klasu "Zgrade" i da u toj klasi definišeš SVE što je zajedničko SVIM zgradama u tvojoj igri. Plus možeš dodatno da ih klasifikuješ ako treba. Evo recimo:
Silos > Zgrada
Baraka > mulitaryZgrada > Zgrada
Štala > mulitaryZgrada > Zgrada
...

Međutim, ponekad nije potrebno praviti posebnu klasu od nkog posebnog objekta, (recimo resursi) Ti možeš da napraviš klasu "resurs" i da mu zadaš parametar (definisan u toj klasi) "vrstaResursa" i ostale parametre "količina"... tako da sva 4 resursa u stvari mogu da budu u stvari jedna ista klasa samo svaka instanca da ima svoje posebne parametre.

Mada bi možda bilo logično da napraviš klasu "igrač" (da recimo praviš realan multiplayer travian) i onda bi instancirao po jednu klasu "igrač" za svakog igrača koji se registruje na tvom serveru, i svaki bi imao svoj username i pass. Zatim bi imao posebnu klasu "selo" i instancirao tu istu klasu za svako selo na tvom serveru. Pritom bi svako selo imalo svoju "pripadnost" (kojem igraču pripada) i onda eventualno pod-klase (i instance tih pod-klasa) koje bi definisale koliko zgrada tu ima i koliko resursa se dobija po jedinici vremena, itd.
[ cobragangsta @ 09.05.2010. 18:18 ] @
ocekivao sam da se prikljuci vise ljudi ovoj temi!
Nisam hteo da postujem da ne bi zatrpali ovu temu, al izgleda da to nece biti problem :)

pokusao sam da resavam problem na razlicite nacine i svaki put sam nailazio na problem
jedan od problema sastojao se od toga da kada sam dodavao MOUSE evente u klase koje nisu glavna !
Tako da sam sve evente premestio u glavnu klasu
tu sam naleteo na sledeci problem:
Seoce je glavna klasa (ostale su trenutno nebitne)

Code:

package {

    import flash.display.MovieClip;
    import flash.events.*;
    import flash.utils.Timer; 
    import flash.text.TextField;
    import flash.display.SimpleButton;

    public class Seoce extends MovieClip {

               ...

        var moveTimer:Timer;
        var tuString:String;
        
        
        // ---------- constructor ------------

        public function Seoce(zi:uint=0,gv:uint=0,gl:uint=0,dr:uint=0,sk:uint=100) {
        var moveTimer:Timer;

                        ...

            moveTimer=new Timer(1000,250);
            moveTimer.addEventListener(TimerEvent.TIMER,akcijeUSeocetu);
            moveTimer.start();
                        ...
        } // end constructor        

        private function akcijeUSeocetu(e:TimerEvent):void{
            trace("f-ja akcije u Seocetu");
            vilageProduce();
            vilageDigest();
        }
        private function vilageProduce():void{
            _silos.kolicinaZiUSilosu+=_zito.proizvodnjaPoKliku;
            _skladiste.kolicinaGvUSkladistu+=_gvozdje.proizvodnjaPoKliku;
            _skladiste.kolicinaGlUSkladistu+=_glina.proizvodnjaPoKliku;
            _skladiste.kolicinaDrUSkladistu+=_drvo.proizvodnjaPoKliku;
        }
        private function vilageDigest():void{
            var zitoP:uint=_silos.kolicinaZiUSilosu;
            var glinaP:uint=_skladiste.kolicinaGlUSkladistu;trace("gozba");
            var gvozdjeP:uint=_skladiste.kolicinaGvUSkladistu;
            var drvoP:uint=_skladiste.kolicinaDrUSkladistu;
            
            if( zitoP && glinaP && gvozdjeP && drvoP ) 
                            {
                             zitoP-=pp;// zitoP-=_zitelj.getPojeduNaKlik();
                             glinaP-=pp;
                             drvoP-=pp;
                             gvozdjeP-=pp;
                             _silos.kolicinaZiUSilosu=zitoP;
                             _skladiste.kolicinaGlUSkladistu=glinaP;
                             _skladiste.kolicinaGvUSkladistu=gvozdjeP;
                             _skladiste.kolicinaDrUSkladistu=drvoP;
                            }
                            else {trace("you're out of resources ");}
        }// end villageDigest    
    } // end class
} // end package

problem stvaraju pozivi f-ja"
vilageProduce();
vilageDigest();
u f-ji private function akcijeUSeocetu(e:TimerEvent):void{
pri testiranju dobijam poruku:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Seoce/::trejs()
at Seoce/::akcijeUSeocetu()
at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
at flash.utils::Timer/flash.utils:Timer::tick()
f-ja akcije u Seocetu

Hvala ti puno StarCraft sto si se potrudio da mi pomognes
kao i za sve sto cinis za ceo flash forum!!!
[ StarCraft @ 10.05.2010. 09:42 ] @
Pa iz mog iskustva primetio sam da apsolutno SVE flash gure izuzetno i neviđeno smara kada neko pita da mu se objasni OOP. (Isto važi i za MVC patterne, tek na to što su alergični...) Istina je u stvari da je OOP u stvari jako teško objasniti jer to je nešto što ti treba da organizuješ u svojoj glavi.

MouseEventovi neće da rade u ostalim klasama samo ako:
1) ta klasa ne extenduje InteractiveObject klasu (ili njene podklase) što znači da taj objekat mora da bude DisplayObject koji se nalazi na ekranu
2) ako nisi importovao MouseEventove (što pretpostavljam da nisi blesav da zaboraviš)

Ja koliko vidim iz error reporta tebi problem nastaje unutar funkcije trejs() koju ja ne vidim ovde u tvom kôdu. Error reportove možeš da čitaš odozdo-na-gore↑. Primetićeš da je error nastao iz tajmerEventa, pa je onda pozvana funkcija akcijeUseocetu() pa unutar nje ta neka trejs() funkcija koja pravi problem. Error #1009 nastaje kada pokušavaš da pozoveš neki objekat koji (više) ne postoji ili neki njegov property ili metodu (funkciju).

Ako hoćeš okači ceo fla pa ću videti, najbolje tako.
[ cobragangsta @ 10.05.2010. 19:49 ] @
Razumem potpuno da nekog smara da nesto objasnajva!
al ja sam ipak samo skromno trazio da se ovde postuju gotovi primeri, sto raznovrsniji!

sto se tice poslednjeg problema
funkcija trejs je obicna f-ja za pracenje . Hteo sam da vidim da li je problem u ovim f-jama ili sto pozivam bilo koju!
pa sam izbacio ove dve i napravi trejs koja u samo u sebi sadrzi standardne metode trace();
ispostavilo se da je problem poziv bilo koje funkcije

kada sam video da ne radi sa ove dve
kad izbacim trejs a napisem ostale vilageProduce(),akcijeUSeocetu() dobijam:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Seoce/::vilageProduce()
at Seoce/::akcijeUSeocetu()
at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
at flash.utils::Timer/flash.utils:Timer::tick()

samo je problem u ovoj klasi seoce, ostale ne uticu na rezultat!

pokusacu da okacim al se sve sastoji iz bar 10 zasebnih as fajlova + jedan fla!
[ StarCraft @ 10.05.2010. 22:34 ] @
Pa naravno da imaš desetak as fajlova i jedan fla :) zato se sve klase obično trpaju u src folder (skraćeno od "source" valjda)

Slobodno okači, nemam šta da ti ukradem :) ja inače radim mnogo ozbiljnije i skuplje projekte, a i moći ću da ti dam određene sugestije na samu strukturu klasa i programa uopšte. Samo ispiši neke komentare da mogu makar okvirno da se snađem :) Stavi na rapidshare pa baci link, svejedno. Problem možda može da bude i sa nekim objektim akoji se (ne) nalaze na ekranu, odavde stvarno ne mogu da vidim...
[ cobragangsta @ 14.05.2010. 00:33 ] @
evo ga u arhivi, ne bi trebalo da ima virusa ali skenirati za svaki slucaj!!
[ StarCraft @ 15.05.2010. 11:25 ] @
Ok baš ovih dana nemam nešto vremena ali pogledaću tamo od ponedeljka.
Malo sam na brzinu bacio pogled i mogu da ti kažem da na ovakav error nisam do sada nikada naleteo. Prijavljuje "null object reference" u funkciji koja poziva neke druge dve funkcije koje obe nisu null. Trebalo bi da prijavi grešku u nekoj od te dve funkcije a ne u "parent" funkciji...

Ček, ček... nešto mi je palo na pamet...

Evo ipak sam našo uzrok problema. Fora je u tome što nisi instancirao _silos promenljivu. Ona pravi problem.

Ali ovo je stvarno fenomen da vidim ovakav error report...
[ cobragangsta @ 10.06.2010. 03:28 ] @
A kako ti se cini stuktura klasa?
jesam li posatavio metode u odgovarajucim klasama ili je trebalo malo drugacije
evo zakacicu za ovu poruku klase kako mi je "logicnije" da se trebaju upakovati u klasu
medjutim to uopste ne funkcionise!
pokusao sam u svaki fajl da importujem klase (iako misli da nema potebe jer sve moje klase pripadaju istom paketu)
pokusao sam da ih "extend-ujem" od MovieClip klase, jer moraju da pristupe objektu (dugmetu- butZito npr) na sceni

al sve ovo nije pomoglo
gresim li ja ili je ovako nemoguce upakovati event-e u klasu!
[ StarCraft @ 10.06.2010. 10:48 ] @
Pa pazi, ja tako sigurno ne bih radio kako si ti počeo, ali svaki metod je dobar ako su na kraju rezultati dobri.

Problem kod razumevanja OOP-a je što je to nešto što ti moraš da razdvojiš u svojoj glavi. Ja radim već par godina u AS3 i mogu da ti kažem da sam možda jedamput samo extendovao neku svoju klasu (nekom drugom mojom klasom). Tako da za razumevanje OOP-a ne moraš da lupaš glavu o multi-level extendovanju klasa previše jer generalno to nije neophodno. Ali ono za šta to tebi treba jeste da bi razumeo kako je dokumentacija organizovana (AS3 reference). Kad jednom skapiraš "tech-tree" objekata u flashu (onih default ugrađenih klasa u flešu) mnogo bolje će ti ceo fleš biti jasniji i lakše ćeš razmišljati o svojim klasama kad ih budeš pravio.

Prvo, imaj na umu da tvoje klase ne moraju da extenduju uvek MovieClip. Obrati pažnju da SVI objekti u flešu nasleđuju osnovnu klasu Object. To važi za apsolutno sve objekte u flešu što uključuje i Number,String, Array, MovieClip, BitmapData, Event, MouseEvent... sve.

Ti kad praviš svoju klasu, ona ne mora a extenduje ništa, što te i dalje ne sprečava da instanciraš tu klasu (biće Object po defoltu) a ta "prazna" klasa (koja ne extenduje ništa) može u sebi da instancira druge MovieClipove, da ih čuva u sebi (u nekom areju ili u pojedinačim variablama) i da im kaže da se šetju levo-desno, da prikazuju određene vrednosti u TextFieldovima itd. Na taj način ti si praktično njima napravio njihov lični _root objekat koji može u sebi da radrži informacije koje nima trebaju.
Recimo primer takve strukture bi bila:
Main klasa instancira SeloMenager (Main -> SeloMenager:Object )
SeloMenager posle instancira druga Sela (SeloMenager -> Selo:MovieClip, Selo:MovieClip, Selo:MovieClip...)
Svako selo ima svoju thumbnail sliku koja predstavlja to selo na globalnoj mapi i listenuje mouseEvent da možeš da klikneš na njega.
Kad klikneš na neku instancu sela, ono onda otvara novi prozor i prikazuje ti zgrade koje sadrži u sebi (Selo -> Zgrada:MovieClip, Zgrada:MovieClip Zgrada:MovieClip...)
Sve zgrade su iste klase, jedina razlika je u tome što im se predaje drugi parametar koju sliku treba da prikazuju. (Selo.addChild( new Zgrada(slikaSilosa); )
Mada bi verovatno trebalo da i za sve te zgrade napraviš posebnu klasu ZgradeMenager koja ce sama da ispostavlja sve te zgrade, čisto da bi imao centralizovano mesto gde ćeš držati informaciju o svim zgradama nekog sela.
Tada recimo ako hoćeš da getuješ koliko neko selo ima zgrada, onda path do toga bi bio:
MainKlasa.SeloMenagerInstanca.SeloBroj72.ZgradeMenagerInstanca.getBrojZgrada();
Isto tako bi trebalo da imaš i path do svih resursa nekog sela na sličan način:
MainKlasa.SeloMenagerInstanca.SeloBroj72.ResursMenager.getGlina();

Naravno, nećeš morati svaki put da pišeš ceo path do konkretnog sela. Ako takve informacije recimo tražiš iz SeloMenager klase, onda je dovoljno da napišeš:
SeloBroj72.ResursMenager.getGlina();
ili
SeloBroj72.getVlasnikSela(); // ako treba da proveriš ko je vlasnik sela

Obrati pažnju da ja nisam extendovao ni jednu svoju klasu nekom drugom svojom klasom, ovde se čisto radi o parent.child strukturi instanci tih klasa.

Ako hoćeš da dinamički instanciraš neki MovieClip iz library-a, onda mu kaži u properties-u da je taj MovieClip u stvari NekeKlase i da extenduje MovieClip (jer i jeste MovieClip). Kada klikneš OK fleš će ti reći da NekaKlasa ne postoji i da će automatski biti generisana prilikom kompajliranja (samo kažeš OK). Šta sad ovo znači? to znači da sada u library-u imaš jedan MovieClip koji extenduje NekuKlasu i da možeš iz koda da ga instanciraš preko:
var instancaNekeKlase:NekaKlasa = new NekaKlasa();
this.addChild( instancaNekeKlase );
Ne moraš da praviš poseban as fajl za taj objekat.

Evo ti dole u atačmentu moja custom klasa za bacanje custom eventova. Možeš da predaš Object kao parametar u koji možeš da trpaš promenljive bilo koje vrste.
dispatchEvent(new Ev(Ev.GOTOVI_XMLOVI, {ucitaniXML:xmlData, dodatniParametar:"dodatni prametar"} ));
u tu Ev klasu možeš da stavljaš dodatne public static promenljive kao što je recimo ova gore GOTOVI_XMLOVI.
public static const GOTOVI_XMLOVI :String = "gotoviXMLovi";
a sve te dodatne parametre izvlačiš preko "data" property-a

public function pokreniPreloader(e:Ev):void {
trace( e.data.dodatniParametar ); // trejsuje: dodatni prametar
}