flash és más

Elkezdtem az Androidot tanulgatni, ide jegyzetelek magam és mások okulására. Flash programozás is lesz, ha úgy érzem, hogy van olyan amit szívesen megosztanék másokkal.

Friss topikok

Rekurzív függvény alkalmazása Flash-ben

2014.04.09. 16:14 hopetheorc

Az egyik interjúmon kaptam egy ehhez hasonló feladatot, persze kiszórtak, mert azért az ember ritkán használ rekurziót. Eldurrant az agyam és megcsináltam, hogy legközelebb legyen fogalmam róla.

A cél az volt, hogy egymásba ágyazott movie clipeken átfutva megtaláljam a leginkább bal oldalon lévő objektum koordinátáit. Nem röhög, ezt találtam ki megoldandó példának.

//A rekurzív föggvény
function getMostLeft(cont):Number
{
    //A cont beérkező objektum globális koordinátáit
    //megkapjuk egy ideigelenes változóban

    var globalPoint:Point = cont.localToGlobal(new Point(0,0));
    //A kapott pont x koordinátája lesz az adott objektum
    //referenciapontja az x tenegelyen

    var mostleft:Number = globalPoint.x;
    // Átfutunk a cont objektumunkban létező összes objektumon egy for ciklussal
    for (var i:int = 0; i < cont.numChildren; i++)
    {
        var mc = cont.getChildAt(i);
        if (mc is MovieClip)
        {
            // ha mc movie clip akkor belelépünk a rekurzív függvényünkbe, ahonnan
            // megkapjuk az aktuális leginkább balra fekvő objektum
            // x koordinátáját

            var temp = getMostLeft(mc);
                        // ha ez az érték kisebb mint az eddigi legkisebb,
            // akkor átírjuk a mostleft értékét
            if (mostleft > temp){
                mostleft = temp;
            }
        }
    }
    // visszaadjuk a mostleft értékét
    return mostleft;
}

var mostleft:Number = getMostLeft(container);

trace (mostleft);

Hát ő lenne az. Meg lehet csinálni iteratív módszerrel is, de kicsit snassz ehhez képest :)

Szólj hozzá!

Címkék: flash as3 pozíció rekurzív egymásba ágyazás

Bitmap használata canvas-en, androidban...

2013.05.17. 11:23 hopetheorc

...meg úgy általában mindenhol, gondolom én.

Csinálgatom a kis játékomat önmagam és (remélhetőleg) mások örömére és belefutottam egy olyan problémába, hogy amikor példányosítottam egy karaktert, ami meg fog jelenni a canvas-en, akkor minden egyes alkalommal érezhetően belassult a játék. Ez főleg akkor jelentkezett, amikor képsorozatot jelenítettem meg a vásznon, például egy robbanást.
Emiatt nem is nagyon erőltettem az animált karaktereket. Aztán véletlenül, böngészve a blogokat beugrott egy ötlet. Mégpedig onnan, hogy azt írta az egyik manus, hogy mindig mikor már nincs szükség a bitmap-re, akkor törölni kell a heap-ből, mert iszonyatosan eszi a memóriát, de nem akkor törlődik, mikor te azt mondod neki, hanem mikor a gc úgy gondolja.
A gondolatot tett követte, az ugrott be, hogy mi lenne, ha a játék elején létrehoznám a majdan animálandó bitmap-et és csak azt a változót, ami ezt a bitmap-et tartalmazza, tolnám bele a példányosított karakterbe.

Ez a megoldás. Gyönyörűen fut a játék, nem akadozik, így már bele merek vágni egy kicsit komolyabb animált karakteres fejlesztésbe.


Előbb-utóbb érkezik egy kód is a bejegyzéshez :)

Szólj hozzá!

Címkék: animáció karakter andorid bitmap canvas

Activity újratöltésének elkerülése a készülék forgatásával

2013.01.14. 14:19 hopetheorc

Megőrültél már attól, hogy egy saját gyártású activity-d hülyeséget csinál, mikor elfordítod a készüléket? Engem ma kisebb szívroham kerülgetett, hogy aszongya "a franc, ezt is le kell kezelni...". Ugye ismerős?

Persze, hogy ezt is az AndroidManifest.xml-ben kell lekezelni :)

A következő a megoldás: megkeresed az adott Activity-t és beleilleszted a következő sort:

<activity android:name=".SomeActivity"
            android:configChanges="keyboardHidden|orientation">
</activity>

Voilá.

Szólj hozzá!

Címkék: forgatás android újratöltés activity portrait landscape

Több tábla készítése egy SQLite adatbázisban (Android)

2012.12.11. 11:45 hopetheorc

Egy olyan problémára akadtam, amivel még nem foglalkoztam bővebben, nevezetesen az adatbázis kezeléssel. Jó, jó, megcsináltam én is a google Notepad tutorialját, persze, de az egyrészt nem életszerű, másrészt meg miért használjon az ember SQLite-ot, ha másképp is meg tudja oldani a dolgokat. Hát nem tudja, vagyis csak körülményesen.


Egy jó ismerősöm segített átgondolni az alapokat, mikor felvázoltam a problémát... Azt mondta legalább 3 tábla kell majd az adatok rögzítéséhez. Uhh, mondom, erről nem volt szó, három táblát lekezelni, egyel is meggyűlt a bajom, de megindokolta, azzal, hogy ha dinamikusan akarom kezelni az adatokat, akkor muszáj szétbontani őket.

Egy adatbázis elkészítésével nincs gond, a következőképp történik, készítünk egy stringet az adatbázishoz:

private static final String TABLE_1 =
" create table " + table1 + " (_id integer primary key autoincrement," 
+ " title text not null, note text not null);";

majd meghívjuk az onCreate metódust a DB Adapter osztályunkban:

@Override
public void onCreate(SQLiteDatabase db) {
	db.execSQL(TABLE_1);
}


Hát ez így egyszerű volt. De mi van több tábla esetén?

Tudni kell azt, hogy db.execSQL egy parancsot tud végrehajtani, ezért három db.execSQL parancsot kell meghívnunk az onCreate metódusban, három parancsstringgel:

private static final String TABLE_1 =
" create table " + table1 + " (_id integer primary key autoincrement," + 
" title text not null, body text not null);"; private static final String TABLE_2 = " create table " + POI_TABLE +
" (_id integer primary key autoincrement," + " poiName text not null)"; private static final String TABLE_3 = " create table " + LOC_TABLE +
" (_id integer primary key autoincrement," + " lattitude text not null, longitude text);"; @Override public void onCreate(SQLiteDatabase db) { db.execSQL(TABLE_1); db.execSQL(TABLE_2); db.execSQL(TABLE_3); }

Ennyi az egész. Ha mégsem sikerülne, kódból is lehettörölni a hibás adatbázist:

public void deleteDatabase(){  
context.deleteDatabase(DATABASE_NAME);
}

De a csodálatos Eclipse fejlesztőkörnyezetben is lehetséges és talán így jobban átláthatóbb és kezelhetőbb a dolog. Ehhez nem kell mást tenni, mint a DDMS nézetet megnyitni (Window -> Open perspective -> Other -> DDMS) és itt értelemszerűen kikeresni az előbb létrehozott adatbázist, majd azt lehúzni az adott készülékről.

Szólj hozzá!

Címkék: tábla android SQLite

Ctrl + Alt + V vagy AltGr + V Chromeban

2012.12.11. 10:26 hopetheorc

Több flashben készített applikációban is jelentkezik egy olyan probléma, ami megoldásért kiáltott, nevezetesen a @ jel használata beviteli mezőkben. Ez igazából a Chrome-ban jeletkezik, a Ctrl + Alt + V billentyűkombinációra nem csak a kukacot illeszti be a jószág, hanem a vágólapon található cuccot is. Ennek kiküszöbölésére találtam ki egy módszert, mert sehol nem találtam rá megoldást. Ez a megoldás csak magyar nyelvű Windows és billentyűzet kombónál működik,  német nyelvű billentyűzetnél ugyanez a probléma a Ctrl + Alt + Q betűnél jelentkezik. Ezt nem szűri ki az én megoldásom.


Nézzük tehát:

package
{
    import flash.events.Event;
    import flash.events.FocusEvent;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    
    // első körben kiterjesztem az osztályomat a szabványos TextField osztállyal 
    public class InputTextField extends TextField
    {
        private var firstPart:String;
        private var lastPart:String;
        private var car:int;
        private private var pressed:Boolean = false;
        
        public function InputTextField()
        {
            // a super() függvénnyel biztosítom azt, hogy az osztályom 
            // constructor függvénye a TextField constructor függvényének 
            //tulajdonságait megkapja 
            super();
            //hozzáadok egy MouseEvent.CLICK eseményt az osztályomhoz 
            this.addEventListener(MouseEvent.CLICK, addFocusHandlers);
        }
        
        private function addFocusHandlers(e:MouseEvent):void
        {
            //a példányosított szövegmezőre kattintva a következő eseménykezelők 
            //kerülnek: 
            //leszedem a CLICK eseménykezelőt - ez majd a későbbiekben 
            //visszakerül, ha elveszti a fókuszt a szövegmezőnk
            this.removeEventListener(MouseEvent.CLICK, addFocusHandlers);
            
            //a FocusEvent.FOCUS_OUT lekapja a billentyűzet eseménykezelőket 
            //és saját magát majd visszateszi a CLICK eseménykezelőt 
            
            this.addEventListener(FocusEvent.FOCUS_OUT, focusOutHandler2);
            //Ha fölengedünk egy gombot, akkor az alábbi eseménykezelő 
            //hívódik meg: 
            this.addEventListener(KeyboardEvent.KEY_DOWN, detectKey);
            
            //Ha lenyomunk egy gombot, akkor az alábbi eseménykezelő 
            //hívódik meg: 
            this.addEventListener(KeyboardEvent.KEY_UP, releaseKey);
        
        }
        
        private function focusOutHandler2(e:FocusEvent):void
        {
            this.removeEventListener(KeyboardEvent.KEY_DOWN, detectKey);
            this.removeEventListener(KeyboardEvent.KEY_UP, releaseKey);
            this.addEventListener(MouseEvent.CLICK, addFocusHandlers);
            this.removeEventListener(FocusEvent.FOCUS_OUT, focusOutHandler2);
        }
        
        //ha a billentyűzeten lenyomódik egy vagy több gomb, letesztelem, 
        //hogy a pressed változó hamis értékű-e (Ez azért kell mert ez az 
        //eseménykezelő egy billentyű lenyomásával nem egyszer hívódik meg, 
        //hanem ismétlődik a rendszerbeállításoknak megfelelően), ha igen, 
        //akkor tesztelem a ctrl + alt + v billentyűkombinációt. 
        
        private function detectKey(e:KeyboardEvent):void
        {
            if (pressed == false)
            {
                if (e.ctrlKey && e.altKey && e.keyCode == 86)
                {
                    //a car változó a kocsi pozícióját menti el (az a villogó vonal 
                    //ami azt a pontot jelöli ahová be lesz szúrva a következő betű) 
                    car = this.caretIndex;
                    
                    //firstPart változó a textmezőben esetlegesen már beírt szöveget fogja 
                    //tartalmazni a kocsi pozíciója előtt 
                    firstPart = this.text.substring(0, car);
                    
                    //lastPart változó a textmezőben esetlegesen már beírt szöveget fogja 
                    //tartalmazni a kocsi pozíciója után 
                    lastPart = this.text.substring(car, this.text.length);
                    
                    //hozzácsapunk még egy Event.CHANGE eseménykezelőt a TextField-ünkhöz, 
                    //ez azért kell, hogy detektáljuk, ha változik a szövegmező tartalma 
                    this.addEventListener(Event.CHANGE, changeTextField);
                    
                    //a pressed változó igaz értéket kap 
                    pressed = true;
                }
            }
        }
        
        private function changeTextField(e:Event):void
        {
            //Ha változik a szöveg tartalma, akkor beszúrjuk a kukacot a két 
            //lementett szövegrészletünk közé 
            this.text = firstPart + "@" + lastPart;
            
            //majd a kocsit a megfelelő helyre teszzük, ha még írna a szövegmezőbe 
            //a júzer 
            this.setSelection(car + 1, car + 1);
        }
        
        private function releaseKey(e:KeyboardEvent):void
        {
            //Ha felemeli az ujját a júzer a V betűről, akkor pressed változó ismét 
            //false állapotba kerül, valamint leveszzük a szövegmezőben változást 
            //értelmező eseménykezelőt 
            if (e.keyCode == 86)
            {
                this.removeEventListener(Event.CHANGE, changeTextField);
                pressed = false;
            }
        }
    }
}

Ha van kérdés, szívesen segítek. Esetleg ha tudtok jobb megoldást és az nem az angol billentyűzetre váltás és utána a shift + 2 akkor azt szívesen fogadom :)

További jó kódolást!

Szólj hozzá!

Címkék: flash @ chrome Ctrl+Alt+V AltGr+V

Video banner flash-ben

2012.03.02. 11:17 hopetheorc

Úgy érzem ezt meg kell, hogy osszam, mert szükség lehet rá a jövőben. Túrkáltam a netet érte fél napon keresztül, innen-onnan összejött egy jó kis alap, ha az ember video bannert akar készíteni.

A kódokat úgy próbáltam leírni, hogy magában a flash fejlesztőkörnyzetben használhatóak legyenek, tehát egyenesen másolható a timeline-ra. Sietek leszögezni, nem szeretem a timeline-os kódolást, de egy egyszerű banner esetén nincs szükség külső osztályok létrehozására.

lássuk:

Itt a cégben Tweenert használunk a szabványos flash elemek mozgatásához, erre nem fecsérelnék sok időt, akit érdekel, az itt megnézheti. Esetleg a greensock cuccait, melyek itt találhatóak. A videó újraindítása ezeknek a segítségével történik majd, a végén visszatérek rá.

Definiáljuk a videó lejátszásához sükséges változókat:

var video:Video;
var nc:NetConnection;
var ns:NetStream;
var URLVideo:String = "http://www.ateszervered.hu/atevideod.flv"

Az URLVideo sztring mutat a lejátszandó videóra.

Nézzük a videó betöltését, hozzunk létre egy Video osztályt a megfelelő paraméterekkel:

initVideo()
function initVideo(){
    // létrehozzuk a Video osztály egy példányát
    // amely megkapja a stage szélességét és magasságát
    video = new Video(stage.stageWidth, stage.stageHeight);
    // a video példányt hozzáadjuk ahhoz az osztályhoz 
    // ahol éppen vagyunk. ez lehet egy bármilyen MovieClip
    // is ami a stage-en található
    addChild(video);
    // rápakolunk egy élsímítást a video példányunkra
    // hogy szebb legyen a videó lejátszáskor
    video.smoothing = true;
}

Ebbe fogjuk beletölteni a külső urlről betöltött flv fájlt. Ezt a metódust többet nem kell meghívnunk, fölösleges terhelni a gép memóriáját újabb és újabb példányok létrehozásával.

A következő lépésben hozzunk létre egy NetConnection és egy NetStream példányt.

initVideoStream();
function initVideoStream(){
    // A NetConnection kétirányú kapcsolatot hoz létre a 
    // kliens és a szerver között.
    nc = new NetConnection();
    // A connect-el hozzuk létre a kapcsolatot, általános
    // esetben webszerverről kapjuk a videót ehhez egy      
    // null-t kell átadnunk.
    nc.connect(null);
    // A NetStream megnyit egy egyirányú streaming 
    // csatornát a NetConnection-on keresztül
    ns = new NetStream(nc);
    // Az AsyncErrorEvent listenert azért adjuk hozzá, 
    // mert ha tartalmaz metadatát a video, akkor az 
    // megpróbálja lekezeltetni azt a cliens oldalon,      
    // de ha ehhez nincs definiálva kód, akkor errort 
    // fogunk kapni.
    ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, 
                                    asyncErrorHandler);
    // A NetStatusEvent minden olyan eseményről 
    // értesít minket ami a NetStream objektumunkal 
    // történik, ezzel tudjuk majd a későbbiekben 
    // elindítani a bannerünket
    ns.addEventListener(NetStatusEvent.NET_STATUS, 
                                    videoStatusEvent);
    // Adunk neki egy buffert, lassú netkapcsolat 
    // esetén ez hasznos lehet
    ns.bufferTime = 5;
    // hozzácsapjuk a videó objektumunkhoz 
    // a NetStream-et
    video.attachNetStream(ns);
    // A play-el értelemszerűen indítjuk a lejátszást
    ns.play(URLVideo);
}

Ezt metódust sem kell többé meghívni, a létrehozott objektumok bőven elegendőek ahhoz, hogy megfelelően működjön a bannerünk.

A fenti kódrészletben a NetStream objektumunkhoz hozzáadtunk két listenert, kezeljük le azokat:

function videoStatusEvent(statusObject:Object):void{
    // trace-szel láthatjuk, hogy milyen események 
    // történnek a video lejátszásakor, ezekhez 
    // tudjuk igazítani a banner lefutását.
    // Ilyenek pl a NetStream.Buffer.Flush ez jelzi, 
    // hogy a buffer tele van, indulhat a lejátszás. 
    // Érdekes lehet még a  NetStream.Play.Stop 
    // (ezzel elindíthatjuk a banner többi részének 
    // lejátszását) vagy a NetStream.Play.Start, 
    // használja mindenki azt ami neki megfelel.

    trace (statusObject.info.code);
    if(statusObject.info.code=="NetStream.Buffer.Flush"){
        // innen elindíthatunk egy tweenert ami 
        // mozgatja a banner animált részét
    }

}

function asyncErrorHandler(event:AsyncErrorEvent):void 
{ 
    // ide nem kell semmi, ezzel kiküszöböljük a 
    // lehetséges metadata által okozott problémákat
}

Ha már nincs szükségünk a banner végéig a videó utolsó képkockájának látványára, nem kell, hogy fusson a videó, akkor állítsuk le, tekerjük az elejére, adjunk még egy cleart a videónak, hogy törölje a képet.

function pauseVideo():void{
    // NetStream-et leállítjuk
    ns.pause();
    // visszacsévéljük az elejére (videót csévélni 
    // szokták? :))
    ns.seek(0);
    // adunk egy clear-t a videó objektumnak, hogy 
    // eltüntessük a képet, ha még lenne rajta valami.
    video.clear();
}

Ezt a metódust egyik tweener használata után, a movieclipek mozgatása közben hívhatjuk meg. A pause és a seek fontos része a folytonos lejátszásnak, ezeknek köszönhető, hogy nem kell a NetStream play funkcióját újra hívni, amely újra kapcsolódna a szerverhez és így terhelné is azt rendesen.

Ha vége a tweener animációnak, újra kell indítanunk a videót. Ez hallgatólagosan a doLoop metódussal történik:

function doLoop():void{
    // A resume újra indítja a pause-zal leállított
    // NetStream-et
    ns.resume();
}

FONTOS!: A NetStatusEvent-et használjuk arra, hogy elindítsuk a tweener animációinkat, abból történhet a legjobb időzítés.

Boldog kódolást! :)

Szólj hozzá!

Kék halál

2011.11.13. 09:52 hopetheorc

Nahát, tegnap este szenvedtem ám rendesen. Próbáltam lefuttatni az emulátoron az újonnan beírt scriptet és lefagyott a gép. Egész egyszerűen kidobta a kék halált és kezicsókolom.

Hajnali kettőig szenvedtem vele, újratelepítettem az SDK-t meg az összes AVD-t, aztán feladtam. A kék halál a következőket emlegette:

SYSTEM_SERVICE_EXCEPTION

meg

embDA64.sys

Aztán ma reggel ezekre rákerestem és ritkásan, de talált a gugli rá megoldást. A fórumokon a videokártya meghajtókat emlegetik na meg az antivírus programokat a lehetséges kiváltó okként.

Gondoltam az antivírus programok írói csak nem csinálnak problémát. Videokártya driver fel - Kék halál ismét... Káromkodás ezerrel.

Aztán mondom csak kikapcsolom én a tűzfalat. És lőn...

Tehát az avast free antivirus okozhat meglepetéseket.

Öhmm, update:

Mégsem az antivírus volt. van egy leadtek winfast kütyüm, amin tévét nézünk. Annak a drivere miatt hal be a rendszer. Érdekes módon a legújabb driver frissítése 2008 decemberi. Tehát, ha android fejlesztés van, akkor nincs tv nézés. Howgh.

Szólj hozzá!

R mint Resources

2011.10.22. 18:32 hopetheorc

Fifikás dolog :)

Dolgozom az ofisl tutoriálokon, persze Eclipse a társam ebben. Vannak jó részei és vannak kevésbé jók. Minjdárt kifejtem, hogy mire gondolok.

A tutarialok a beírandó vagy inkább bekopizandó java scripteket nem teljes egészében adják meg, a beimportálandó osztályok általában nincsenen ott. Ez abból a szempontból rendben van, hogy legalább kicsit rá van az ember kényszerítve arra, hogy átnézze, hogy most akkor mi is történik, milyen osztályokra van még szükség ahhoz, hogy a csomag működjön.

Eclipse partner ebben, de túl van automatizálva. Van egy billentyűkombináció benne (CTRL + SHIFT + O) amit megnyomva az összes hiányzó osztályt beimportálja.

És itt a bibi.  Tele piroshullámozta a scriptet ezután is... Kutatnom kellett az internetvilághálón cseppet, hogy rájöjjek mi is a probléma ezzel. Azért írtam, hogy túl van automatizálva, mert azokat az osztályokat is megtalálja az Eclipse, amikre nincs szükség. Peldául beimportálta az android.R bázis osztályt is, amire nincs szükség a program implementálásakor, mert a bázis osztály helyett ilyenkor a fejlesztő környezet létrehoz egy lokális R osztályt a különböző változókból, miegymásokból, amire szüksége van.

Halkan jegyzem meg, hogy a Flash Developot azért tartom jobbnak, mert ott is van egy hasonló billentyűkombináció (Ctrl + Shift + 1), ami szintén behúzza a szükséges osztályokat, viszont mindegyik hiányzó osztályra egyenként kell alkalmazni azt, tehát nincs jelen a túlautomatizáltságból adódó veszély.

Howgh

Szólj hozzá!

Android kezdőknek

2011.10.15. 16:05 hopetheorc

No, hát én is kezdő vagyok, pár év flash programozás után, amibe kicsit belefáradtam, gondoltam új kihívások után nézek.

Ne kell félreérteni, a flash még mindig tartogat meglepetéseket, nap mint nap tanulok valami újat, de kell valami ami utána jön... Gondoltam miért ne legyen ez az android. Kacérkodtam már kicsit a jávával, ez meg úgy is azon alapul.

Volt egy régi hat éves gépem, amin fönt volt az eclipse, föltelepítettem rá hát az android plug-int. Őrjítő volt. Az első tutorial ez volt, amit megcsináltam. Minden szépen alakult, az eclipse szépen működött is, hanem amikor elindítottam az emulátort... Az a szegény öreg gép mint a kutya, úgy szenvedett. Kb. 5 perc kellett neki, hogy elinduljon, csak egy olyan kis program, ami kiírja a képernyőre azt, hogy hello, world. A 3.2-es táblagéphez való emulátorról ne is beszéljünk.

Be is disznultam, pár napra rá már ott virított az új alaplap, proci, memória és a többi ami kell még. Talán nem kellett volna...

Tudni kell azt, hogy az androidot htmlszerűen, xml alapú layout elrendezéssel kezdi el tanulni az ember (bátrabbaknak is ajánlom, scripttel összerakni egy layoutot nem mindig ésszerű).

Kicsit hajaz a html leíró kódra, úgy értem az elv hasonló, bár talán kicsit komplexebb. És ami a legszebb, hogy amíg tanulja az ember ezeket a layoutokat, addig nem is muszáj az emulátort használni, az eclipse, vagyis az android plug-in az eclipse-hez gyönyörű szépen megmutatja, hogy hogyan is fog kinézni a kívánt layout. Van egy "graphical layout" nevű tab és ha bármit változtatok az xml-ben, megnyomom azt a tab-ot és ő hűségesen megmutatja, hogy ilyen is az, amit én az xml-benkialakítottam. Többnyire.

Kicsit azért bugos a kicsike, de egy ajtócsapkodást megér a dolog.

Tehát bizony mondom néktek, a tanulás első fázisában fölösleges beleölni a pénzt egy komolyabb vasba, elmegy az anélkül is egy darabig.

Ja és még egy fontos info: ha nem emulátorral teszteli az embör, hanem egyenesen telefonra tölti, az jóval gyorsabb. Már akinek van androidos telója.

Ecsém, androidra akarok programozni és nincs hozzá eszközöm. Jól kinézek én ki.

Szólj hozzá!

süti beállítások módosítása