[as2] Zestrzelił i uciekł - asteroids-textoids :-)
 Oceń wpis
   

Czyli zasada levelowania w asteroids. Które pisze Darek 3DH.

var speed:Number = 1;
var speed_const:Number = 1;
var speed_multiplier:Number = 2;
var speed_acc:Number = 0.2;
var speed_prevAccSpeed:Number = 0;
//
var shootOut_counter:Number = 0;
var shootOut_speedStep:Number = 3;
var shootOut_bonusStep:Number = 5;
var bonus_prevShootCount:Number = 0;
//
this.onEnterFrame = function () {
//
var output:String = "";// "\n" jeżeli chcesz dodatkowy odstęp (przy trace z flasha jest niepotrzebny - dodaje sam)
//
output += "Zestrzeliłeś asteroidę... ";
output += "zestrzelonych: " + shootOut_counter + " asteroid. ";
output += "Prędkość: wynosi " + speed + ". ";
shootOut_counter++;
//
if (!(shootOut_counter % shootOut_speedStep) && (speed_prevAccSpeed != speed))
{
 speed_prevAccSpeed = speed;
 speed = speed_const + int (shootOut_counter * speed_multiplier) * speed_acc;
 output += "No i przyspieszam do " + speed + ".";
}
if (!(shootOut_counter % shootOut_bonusStep) && (bonus_prevShootCount != shootOut_counter))
{
 bonus_prevShootCount = shootOut_counter;
 output += " I bonus nr " + int (shootOut_counter / shootOut_bonusStep) + " też się trafił.";
}
if (shootOut_counter == 200)
{
 delete this.onEnterFrame;
}
trace(output);
};
Skrypt symuluje grę w asteroids przy zadanych parametrach - level'owanie na podstawie prędkości, co 3 zestrzelone sztuki, wrzucanie bonusa co pięć zestrzelonych asteroid. Oczywiście jest to model - bardzo łatwy do połączenia z View.

Wynik działania:

Zestrzeliłeś asteroidę... zestrzelonych: 0 asteroid. Prędkość: wynosi 1. 
Zestrzeliłeś asteroidę... zestrzelonych: 1 asteroid. Prędkość: wynosi 1. 
Zestrzeliłeś asteroidę... zestrzelonych: 2 asteroid. Prędkość: wynosi 1. No i przyspieszam do 2.2.
Zestrzeliłeś asteroidę... zestrzelonych: 3 asteroid. Prędkość: wynosi 2.2. 
Zestrzeliłeś asteroidę... zestrzelonych: 4 asteroid. Prędkość: wynosi 2.2.  I bonus nr 1 też się trafił.
Zestrzeliłeś asteroidę... zestrzelonych: 5 asteroid. Prędkość: wynosi 2.2. No i przyspieszam do 3.4.
Zestrzeliłeś asteroidę... zestrzelonych: 6 asteroid. Prędkość: wynosi 3.4. 
Zestrzeliłeś asteroidę... zestrzelonych: 7 asteroid. Prędkość: wynosi 3.4. 
Zestrzeliłeś asteroidę... zestrzelonych: 8 asteroid. Prędkość: wynosi 3.4. No i przyspieszam do 4.6.
Zestrzeliłeś asteroidę... zestrzelonych: 9 asteroid. Prędkość: wynosi 4.6.  I bonus nr 2 też się trafił.
Zestrzeliłeś asteroidę... zestrzelonych: 10 asteroid. Prędkość: wynosi 4.6. 
Zestrzeliłeś asteroidę... zestrzelonych: 11 asteroid. Prędkość: wynosi 4.6. No i przyspieszam do 5.8.
...
...
Zestrzeliłeś asteroidę... zestrzelonych: 39 asteroid. Prędkość: wynosi 16.6.  I bonus nr 8 też się trafił.
Zestrzeliłeś asteroidę... zestrzelonych: 40 asteroid. Prędkość: wynosi 16.6. 
Zestrzeliłeś asteroidę... zestrzelonych: 41 asteroid. Prędkość: wynosi 16.6. No i przyspieszam do 17.8.
Zestrzeliłeś asteroidę... zestrzelonych: 42 asteroid. Prędkość: wynosi 17.8. 
Zestrzeliłeś asteroidę... zestrzelonych: 43 asteroid. Prędkość: wynosi 17.8. 
Zestrzeliłeś asteroidę... zestrzelonych: 44 asteroid. Prędkość: wynosi 17.8. No i przyspieszam do 19. I bonus nr 9 też się trafił.
...
...
Zestrzeliłeś asteroidę... zestrzelonych: 60 asteroid. Prędkość: wynosi 25. 
Zestrzeliłeś asteroidę... zestrzelonych: 61 asteroid. Prędkość: wynosi 25. 
Zestrzeliłeś asteroidę... zestrzelonych: 62 asteroid. Prędkość: wynosi 25. No i przyspieszam do 26.2.
Zestrzeliłeś asteroidę... zestrzelonych: 63 asteroid. Prędkość: wynosi 26.2. 
Zestrzeliłeś asteroidę... zestrzelonych: 64 asteroid. Prędkość: wynosi 26.2.  I bonus nr 13 też się trafił.
Zestrzeliłeś asteroidę... zestrzelonych: 65 asteroid. Prędkość: wynosi 26.2. No i przyspieszam do 27.4.
...
...
Zestrzeliłeś asteroidę... zestrzelonych: 90 asteroid. Prędkość: wynosi 37. 
Zestrzeliłeś asteroidę... zestrzelonych: 91 asteroid. Prędkość: wynosi 37. 
Zestrzeliłeś asteroidę... zestrzelonych: 92 asteroid. Prędkość: wynosi 37. No i przyspieszam do 38.2.
Zestrzeliłeś asteroidę... zestrzelonych: 93 asteroid. Prędkość: wynosi 38.2. 
Zestrzeliłeś asteroidę... zestrzelonych: 94 asteroid. Prędkość: wynosi 38.2.  I bonus nr 19 też się trafił.
Zestrzeliłeś asteroidę... zestrzelonych: 95 asteroid. Prędkość: wynosi 38.2. No i przyspieszam do 39.4.
Zestrzeliłeś asteroidę... zestrzelonych: 96 asteroid. Prędkość: wynosi 39.4. 
Zestrzeliłeś asteroidę... zestrzelonych: 97 asteroid. Prędkość: wynosi 39.4. 
Zestrzeliłeś asteroidę... zestrzelonych: 98 asteroid. Prędkość: wynosi 39.4. No i przyspieszam do 40.6.
Zestrzeliłeś asteroidę... zestrzelonych: 99 asteroid. Prędkość: wynosi 40.6.  I bonus nr 20 też się trafił.
Zestrzeliłeś asteroidę... zestrzelonych: 100 asteroid. Prędkość: wynosi 40.6. 
...
... 
Zestrzeliłeś asteroidę... zestrzelonych: 199 asteroid. Prędkość: wynosi 80.2.  I bonus nr 40 też się trafił.

Przy połączeniu z kontrolerem (GameManager/Controller) i z View bardzo prosto przejść do normalnej gry. Wystarczy linijkę shootOut_counter++; zamienić na wywołanie metody sprawdzającej skutek strzału/położenie pocisku względem obiektów do zestrzelenia.

Po linijce  speed = speed_const + int (shootOut_counter * speed_multiplier) * speed_acc; można dodać linijkę zmieniającą  wartość shootOut_bonusStep, która decyduje o ilości asteroid na jeden level. Np. na proste shootOut_bonusStep++; (czyli na każdym kolejnym levelu będzie trzeba zbić o jedną asteroidę więcej). Podobnie można też regulować wartość shootOut_bonusStep - np. dodanie shootOut_bonusStep++; spowoduje, że bonusy będą coraz rzadsze.

Wyobrażacie sobie grę w Asteroids w postaci tekstowej ? :D

PS. Z powodu niewłaściwego dobrania parametrów shootOut_counter (= 2) i speed_multiplier (= 0.2) zbyt szybko rośnie prędkość - od 1 do 80 w 66 leveli. To trochę za szybko. Choć w sumie: czy ja wiem ? :D

Komentarze (0)
BitmapData.getPixel jest BE!
 Oceń wpis
   

Dzisiaj miał być kolejny odcinek cyklu "piszemy grę". Nie będzie. Możecie za to podziękować silnikowi renderującemu flasha eli edytorowi, eli metodzie getPixel...

Oczywiście można by było narzekać, że to z winy reklamacji nie ma wpisu - ale reklamacje sprawa ludzka - sprawdzić raport, rozpatrzyć, załatwić (i ewentualnie wystawić rachunek - naprawdę, zacznę wystawiać!). I tyle.

Zazwyczaj potrzebuję na załatwienie reklamacji maks 48 godzin - z czego na samo szukanie usterki góra 2-3 godziny - tym razem to ja byłem pragnienie, a flash sprite...

Jest taka ładna metoda klasy BitmapData, którą wszyscy "bitmapowcy" (tzn. pracujący we flashu z bitmapami) zapewne znają - getPixel(bmpX,bmpY); - ja używa jej do pathfindingu.

W tym reklamowanym przypadku, oprócz tła "reagującego" na bieżąco rysowało się sześć ścieżek ruchu:   0x0000ff, 0xffff00,  0xff0000, 0x00ff00, 0x00FF0F, 0xff00ff. No i za Chiny Ludowe nie chciała działać ścieżka 0x00FF0F (nie wykrywało jej) - rwałem już sobie włosy z głowy, czy to nie wina algorytmu przypisującego obiekt do ścieżki - ale nie! Obiekty biegały sobie jak im klasa sterująca nakazała.

W końcu poszedłem po rozum do głowy - tą samą metodą, którą używałem w klasie wykrywającej ścieżki, potraktowałem pierwszą linię bitmapy celu, sprawdzając, jakie kolejno kolory się ukażą:

  var clr:Number = 0;
  var c:Number;
  //
  for (var i:Number = 0; i < hitmap.getBitmapData().width; i++)
  {
   c = hitmap.getBitmapData().getPixel(i, 0);
   if (clr != c)
   {
    trace(c.toString(16));
    clr = c;
   }
  }

i oto wynik:

ffffff
ffff
0
ff
0
ffff00
0
ff0000
0
ffff
0
 ff00
0
FF0A
0
ff00ff
0
ffff
ffffff

AAAaaaAAaaaAAaaa i wiele  jeden-JEDEN-jeden (z shiftem) - widzicie zaznaczoną wartość ? Niech ktoś mi wytłumaczy, dlaczego jest tam A, a nie F ??? W edytorze wspomniana bitmapa ma wartość składowej niebieskiego 0x0F, a nie 0x0A.

Flashu, w którym momencie kłamiesz ?

Komentarze (0)
Aaaaarghhh.... błędy wykonania po polsku ? :-/
 Oceń wpis
   

Kojarzy mi się to z rasizmem. Serio - jakoś nie przemawia do mnie to, że moduł jest spolszczony.

Same teksty w RMBmenu byłbym w stanie przecierpieć - zawsze idzie przecież zbudować swoje w jedynie słusznym języku ;-) - ale co tam menu - siedzieć przy pięciu wersjach flasha i niektóre błędy mieć w zasadzie na pamięć wykute, a teraz czytać np. Nie można uzyskać dostępu do właściwości lub metody dla odniesienia do obiektu null.WTF ?? Serio, w pierwszym odruchu człowiek łamie sobie głowę i język próbując przeanglojęzyczyć z polskiego na nasze... horror ;-).

No ale nie ma się co rozpisywać. Uważam, że każdy powinien mmieć wybór - nie po to w końcu kupowałem angielskojęzyczną wersję flasha, by teraz czytać polskie tłumaczenia angielskich komunikatów (owszem, nie są najgorsze, ale głowa zaczyna boleć, jak próbuje się je zrozumieć).

Więc: popieram akcję: "język narodowy jest BE w oopisach błędów" - akcja zaczęła się w wątku na FZ - stamtąd pochodzi cytowana treść błędu, tam też odsyłam: flash player i sdk po polsku .

Poprzyj i Ty.

EDIT: Jak donosi Artur: pracując w Niemczech na niemieckim systemie, błedy są również po niemiecku, co oznacza, że średnio co pół godziny musi słyszeć "Artur, halte klappe!" ("Artur, zamknij twarz" /tzn., że koledzy Artura już doszli do tego, co znaczy po polsku: "ku***", "ja pie***", "to jest po***" :D/) - tak to jest, jak pracuje się w obcym kraju znając tylko angielski... ^^

Komentarze (0)
Najmniejszy pakiet bibliotek z MS.NET2.0 (upd)
 Oceń wpis
   

Gdyby ktoś szukał (potrzebował) do odpalenia aplikacji opartych o środowisko Microsoft .NET 2.0, to polecam link do najmniejszego pakietu (tylko 26MB!) bibliotek potrzebnego do odpalenia takich aplikacji: microsoft.net 2.0 runtime library .

...najmniejszy - to znaczy nie mający ponad 320MB jak pełny .NET SDK framework.

//EDIT: Jest jeszcze wersja 3.5 ściągana online (bezpośrednio instalator 2,7MB, a potem z 82MB) - część programów wymaga już tego środowiska.

Komentarze (0)
[as... ?] Zaokrąglij dziesiętnie
 Oceń wpis
   

Przeglądając przepastne otchłanie moich starych projektów znalazłem pewną metodę, która w bardzo prosty (?) sposób rozwiązywała problem sumowania błędów zaokrąglenia dziesiętnego (czyli sytuacji, kiedy 1+1 nie jest równe 2, a 1.999999999999999999999999999999 )//level - ilość miejsc po przecinku, up: 0 - w dół, 1 - w górę
function Zaokr10 (num, level, up)
{
 var log_num, pow_num, znak = 1;
 if (num < 0)
 {
  znak = -1;
  num = -num;
 }
 log_num = int (log10 (num));
 pow_num = Math.pow (10, log_num - level + 1);
 if (up == 0)
 {
  num = int (num / pow_num) * pow_num;
 }
 else
 {
  num = Math.ceil (num / pow_num) * pow_num;
 }
 return (znak * num);
}
niektóre konstrukcje są tak proste, że aż uniwersalne - ta akurat... pochodzi z projektu napisanego pod flash5, z pakiektu (tak! Z PAKIETU!!!) wspomagającego przeliczanie... 3D.

Nic dodać, nic ująć -może tylko to, że ten projekt obecnie liczy sobie... sześć czy siedem lat.

Komentarze (0)
Embedowanie Fontów (upd)
 Oceń wpis
   

...czyli podstawowe rzeczy, które o uzyskaniu polskich fontów pod flashem w przeglądarce powinieneś wiedzieć.

1. Sprawdź, czy Twój font pokazuje poprawnie poskie znaki

ą ż ś ź ę ć ń ó ł  Ą Ż Ś Ź Ę Ć Ń Ó Ł

2. Sprawdź, czy są one dostępne z poziomu edytora

Sprawdź, czy w Twoim edytorze widzisz polskie znaki

Jeżeli nie są dostępne, to prawdopodobnie będziesz musiał użyć takiego małego, sprytnego programiku (lub podobnego do niego) - WGL assistant, dzięki któremu możemy zamapować polskie fonty w skrypt western lub załączyć obsługę wybranego skryptu lokalnego (po ludzku: uzyskać wyświetlanie polskich ogonków w międzynarodowym zestawie znaków lub dodać fonta z rozszerzeniem "CE" zawierającego ogonki).

3. Minimalizm - czyli jak mieć polskie fonty nie zwiększając znacząco wagi pliku

W przypadku pól dynamicznych należy kliknąć w przycisk "EMBED" i dopisać nasze "znamię narodowe" w polu "Include these characters":

A teraz staramy się, by były one widoczne przy wyświetlaniu u użytkownika.

Po tej to operacji powinniśmy mieć podstawowy zestaw fontów dostępny po eksporcie swfa nawet w polach input.

Czasami konieczne będzie dodatkowe zaimportowanie kilku znaków, które niekiedy nie są dołączane przez edytor - oto te znaki (razem z polskimi, dla łatwiejszego przeklejenia):

{tab}ążśźęćń󳥯ŚŹĘĆŃÓŁ#$%&*+=@[\]^_{}

{tab} - to znak tabulacji, którą nie da się umieścić w inny sposób, jak tylko poprzez otwarcie notatnika, użycie tabulacji, zaznaczenie tego odstępu i wklejenie do linii znaków.

4. Po eksporcie

Może się okazać, że znaków nie ma, albo w polach input są niepoprawnie wprowadzane. Najczęstszym tego powodem jest to, że obiekt flash jest osadzony przy załączonej opcji eksportu "transparent" -w tym trybie plugin flash źle interpretuje wprowadzane polskie znaki - jeżeli masz z tym problem, możesz użyć sposobu Semy, o wszystkim nt. odczytywania polskich fontów przy użytej opcji transparent poczytasz na flabie. Jeżeli nie poradzisz sobie z tym - niestety, zostaje Ci ominięcie opcji transparent poprzez umiejętne maskowanie/dodanie maskującego tła we flashu (np. poprzez użycie obiektu zarejestrowanego w StageResizerze).

Uwagi na koniec

Tak samo jak nie tworzymy stron WWW przy kodowaniu win1250, tak samo nie wysyłamy z serwera znaków kodowanych latin2. Flash od wersji MX używa UTF (UTF-8) do kodowania danych, co pozwala na elastyczny ich eksport i użytkowanie w wielu wersjach narodowych - o ile pamiętamy, by ustawić te kodowanie po stronie serwera (przypomnienie od Mooski :) ).

To tyle podstaw. Mam nadzieję, że będą przydatne. Wszelkie dodatkowe uwagi mile widziane.

//EDIT: Noizz przypomniał jeszcze jedną sprawę - fikuśne znaczki Wordowskie - należy je tak samo dodać, jak dodatkowe z listy w pkt. 4 - a więc wypunktowania, cudzysłowy drukarskie (skośne), apostrofy, cyferki w potędze, inne znaki diakryczne, które w tekście z worda mogą się znaleźć. No i zapowiada się "druga edycja" - ze względu na to, że nie wszystkie encje są przez flasha rozpoznawane (czyli trzeba je we flashu zamienić na ich odpowiednik literowy) - i nie każdy znak, który przychodzi w "url-encoded" ("procenty") będzie widziany jako właściwy...

Komentarze (7)
Jak usunąć plugin flasha pod FF (upd)
 Oceń wpis
   

...bo sprawa wygląda tak, że FireFox ma swój osobny folder pluginów, więc też inne pliki playera używa.

O sprawie doniósł mi na gg Andrzej "Bender" - gdy miał problem z niemożliwością zmiany pluginu na nowszą wersję. I to dzięki niemu macie sposób na rozwiązanie tego problemu.

Sprawa koncentruje się wokół folderu FireFoxa pod nazwą: mozilla firefox/plugins - sposób rozwiązania jest podany na stronie CNET.com CNET.com:Problems updating the Flash player in Firefox? Here's help i tam odsyłam.

//EDIT: jak donosi Andrzej: sprawa w sumie sprowadza się do usunięcia jednego pliku z folderu plugins : NPSWF32.dll (usunięcia, nie zmienienia nazwy - bo to nic nie daje)

Komentarze (0)
Dziwny problem z BitmapData
 Oceń wpis
   

Chyba z godzinę siedziałem z rozdziawioną szczęką patrząc na błąd, który mi się pojawił w outpucie:

**Error** [TOP SECRET]/_GAMESWORKSHOP/_ROZPOCZETE/[TOP SECRET]/gameloader.as: Line 10: The class or interface 'flash.display.BitmapData' could not be loaded.

Było to już po usunięciu wszystkich plików ASO, dwukrotnym przekompilowaniu i usunięciu plików *.swd.... mój mózg ciężko trybił próbując przerobić ten błąd na postać zrozumiałą dla logiki. Jak to czegoś, co jeszcze dwa dni temu było, teraz nagle nie ma ?

Idąc za wskazaniem mojego małego rozumku, po skasowaniu ASO(ó)w i SWD(f)ów pierw postąpiłem zgodnie z instrukcją w helpie - zamiast korzystać z polecenia import, usunąłem je i dopisałem pełną ścieżkę klasy do definiowanej zmiennej:

var bd:flash.display.BitmapData = ...

i ... **Error** znowu :|

idąc tropem wskazanym przez kompilator, tym razem przeniosłem importa z inkludowanego pliku do tajmlajna:

import flash.display.BitmapData;
#include "gameloader.as";

kompilator wyraźnie ze złośliwą radością wypluł, że tym razem błąd znajduje się w pliku fla :]

Cóż poradzić ? Założyłem na głowę moją sherlockowo-holmesową czapeczkę, wsadziłem w bok ust ustnik fajki i wyruszyłem na poszukiwanie łotra.

Zaglądnąłem do $(LocalData)/Classes\flash\display\BitmapData - BitmapData.as siedzi, gdzie miał siedzieć! Rzekł bym nawet: troszeczkę struchlały, bo musiałem nieźle wyglądać, jak tak przekrwionym okiem łypałem z góry na niego otwierając jego folder.

No był. I nie da się ukryć, nie zamierzał zwiać. Ba! nie ruszył się nawet, gdy zwiedziony myślą, że "może skasowanie go coś tu pomoże" mój palec zaczął ślimaczą wędrówkę w kierunku "[DELETE]". Na szczęście zdrowy rozsądek wygrał z chęcią karania niewinnych. A więc winny jest niewinny! Niech to!

Zmęłłęm swoją sherlockowo-holmesową czapeczkę i rzuciłem w kąt. Cóż ze mnie za detektyw ? :\

No ale nie jestem z tych, co się poddają po wykorzystaniu wszystkich kół ratunkowych przy pierwszym tysiącu. Milion (groszy) czeka! Ruszyłem w dalszy bój z niesfornym kodem.

Moje ciężko przesuwające się trybiki zaiskrzyły. Przypomniało mi się, że dziad jeden przy wklejeniu includa do klatki we flaku pytał mnie, czy chcę zmienić format zapisanego pliku i że po zmianie nie będzie on już odczytywalny w starszych wersjach flasha...

Wskoczyłem jak rozjuszony byk we flaka: "Gdzie jesteś Zbóju???" W pierwszej klatce go nie było. Ani w ostatniej. Popatrzyłem do zakładki Flash w Publish Settings. Action script dwa ? Dwa, no a co niby ? Stój! Ledwo się wyrobiłem przed kliknięciem w "Cancel". Mam Cię! Ha!

Mój mózg chwilę przed zamknięciem kątem oka zarejestrował, że coś mu tu nie pasuje w publikowanej wersji... FLASHA - TU CIĘ MAM!

Dwa dni temu wysyłałem Matowi plik, żeby zrobił instrukcję. Trochę byłem wtedy ciężko myślący... widocznie "przy okazji" zamiast wyeksportować do starszej wersji flasha plik z instrukcją, zapisałem w starszej wersji tego flaka. No a flash, jak to flash - "Piekło jest dobrymi chęciami wybrukowane" - zmienił automatycznie wersję publikacji na zgodną z wersją pliku. Teraz trzeba to było odkręcać. I zmienić wersję na nowszą.

Jaki z tego wniosek ? Jeżeli czegoś nie ma, a jest - usuń nie tylko pliki ASO i SWD, sprawdź nie tylko wersję Actionscript, ale także inne wersje pozycje.

Dlaczego to wyszło teraz ? Ano, zaremowanego kawałka i Salomon nie skompiluje, więc jak odremowałem, to draństwo wyszło...

...a poza tym to miłej niedzieli życzę. Bez kodowania. Exit.

Komentarze (1)
[as] Było spowalnianie, to teraz przyspieszamy
 Oceń wpis
   

W jednym z poprzednich wpisów opisałem jak spowalniać flasha kosztem procesora, teraz pora napisać jak przyspieszyć flasha kosztem procesora.

Jak zapewne wielu z czytających wie, prędkość odtwarzania uzależniona jest od FPS (frames per second), który ustawiamy w edytorze. Ci, co robią projekty pod as3 mają już troszeczkę lepiej, ponieważ mogą tego FPS-a regulować podczas pracy.

Czy my możemy wpłynąć na FPSa podczas wykonywania aplikacji ? W dowolnej wersji, nie tylko CS3/as3 ? Tak, w poprzednim akapicie to napisałem. No a jeżeli klip już jest skompilowany ?

Tutaj z pomocą przychodzi jedna z metod, które Adobe oznacza jako "deprecated". Jest to loadMovieNum - a więc załadowanie swfa na inny level. Czym się różni depth od levelu nie będę rozpisywał, w każdym razie kiedyś "depth" było słowem mitycznym, a jedyne, co szło zrobić, to załadować klipy na kolejne levele. No i nie szło ich zamieniać miejscami.

W naszym przypadku "ułomności leveli" nie są przeszkodą.

Co z tym ładowaniem ? Jeżeli w naszym klipie wywołamy loadMovieNum("nazwaklipu.swf",1); ładowanie na wyższy level, jego _root będzie oznaczał jego _level - w tym przypadku _level1 (jak zapewne pamiętacie, standardowym levelem jest _level0, co możecie w prosty sposób sprawdzić, odpalając klip w edytorze po wpisaniu w pierwszej klatce trace(_level0 == _root); )

Ok, dość już gadania. Teraz jeszcze pytanie: jak bardzo przyspieszy się odtwarzanie klipa ? Tak bardzo, jak pozwoli na to procesor. Biorąc pod uwagę, że player flasha jest stosunkowo wolny, ustawmy też na starcie _quality = "medium"; co pozwoli odzyskać część czasu z renderowania.

No i jeszcze jedno: żeby nie odpalać tysiąc razy flasha (czasami tego "wiecznego triala", co się u niektórych zdarza) dodajmy prosty skrypcik, który będzie zczytywał nazwę ładowanego klipu z nazwy swojej własnej:

var u:String = unescape(this._url).split("playfaster=")[1].split(".swf")[0];
//
trace(this._url.split("playfaster="));
if (u!="") {
 trace(u);

 loadMovieNum(u+".swf",1);
} else {
 trace("no file");

}
Stage.scaleMode = "noscale";
Stage.align = "TL";
_quality = "medium";

Ot, po prostu po nazwie "playfaster", po znaku równości wpisujemy nazwę pliku, który chcemy załadować. Bez rozszerzenia .swf. I to wszystko.

Niestety, ze względu na wysoki poziom zabezpieczeń playera, podany sposób działa tylko na pliki lokalne (z tej samej lokalizacji).

Pomyślcie, że cała ta sztuczka powstała przez to, że opisywane przeze mnie Age of War było na poziomie "hard" za wolne... za łatwe... Tak, jest poziom trudniejszy - "impossible" - ale są tam imho bardzo źle dobrane wskaźniki siły - udało mi się dojść do współczesności i zawsze jakoś forsy braknie na kolejnych komandosów (taa... gospodarka niedoboru... prawie jak w życiu...).

W załączniku: PlayFaster + Age Of War (4,2 MB). Polecam zagrać pierw z przyspieszeniem, a potem bez przyspieszenia... widać różnicę, co ?

Komentarze (1)
Odliczamy w dół. Plus liczba ze stałą ilością miejsc (upd)
 Oceń wpis
   

Naprawdę, chyba prościej się zrobić nie da.

1. Minutnik

Jeżeli interesuje nas czas, który będzie za 5 minut to znaczy, że do obecnego czasu musimy pięć minut dodać. Proste.

Obecny czas w Actionscript zwróci nam new Date() bez parametrów.

Czas za 5 minut ? new Date () + new Date(0,0,0,0,5,0,0) Jak to przechowywać ? Najprościej w postaci milisekundowej, a więc Date.valueOf() się kłania.

Teraz wystarczy od otrzymanej na początku końcowej daty (ironia, co ? koniec na początku - żeby programy tak się pisały :D ) odjąć bieżącą, żeby otrzymać różnicę wskazującą, czy jeszcze jesteśmy w naszej pięciominutówce, czy też już jest "po ptokach".

No i omawiany skrypcik:

 //5 minut
var endtime = new Date ().valueOf () + new Date (0, 0, 0, 0, 5, 0, 0).valueOf ();
//
trace (new Date ().valueOf ());
//
function multiPosNumber (nr:Number, pos:Number):String {
 //
 var n:String = nr.toString ();
 var o:String = "";
 //
 for (var i = 0; i < (pos - n.length); i++)
 {
  o += "0";
 }
 return o + n;
}
function showCountDown () {
 //
 var d:Date = new Date (endtime - new Date ().valueOf ());
 var ss:Number = d.getSeconds ();
 var mm:Number = d.getMinutes ();
 var hh:Number = d.getHours ();
 //
 trace (([multiPosNumber (hh, 2), multiPosNumber (mm, 2), multiPosNumber (ss, 2)]).join (":"));

if (!hh && !mm && !ss) {

trace ("czas się skończył!!!");
delete this.onEnterframe;

}
}
//
this.onEnterframe = showCountDown;

2. Liczba stałopozycyjna

Dodatkowo jeszcze przemycił się nam drugi skrypcik: multiPosNumber - metoda dodająca do naszej wartości zadaną liczbę zer - można oczywiście ją jeszcze usprawnić, by była to dowolna liczba (nie tylko zero), a nawet "ogonek" - np. " zł". No ale to już możecie zrobić we własnym zakresie.

function multiPosNumber (nr:Number, pos:Number):String {
 //
 var n:String = nr.toString ();
 var o:String = "";
 //
 for (var i = 0; i < (pos - n.length); i++)
 {
  o += "0";
 }
 return o + n;
}

Wszystko w "formie tajmlajnowej". Z przerzuceniem do klas nie powinno być żadnego problemu.

Miłego używania.

//EDIT: Liczba stałopozycyjna to pojęcie z binarki (czyli stringi "001010" itp.), ale nie widzę problemu w tym, by metoda działająca na zerojedynkowym zakresie działała też w innym.

Ponieważ i parseInt, i Number.toString(radix) zwraca typ String, a u mnie potrzebny jest typ Number, musimy przed przekazaniem do metody zrobić proste rzutowanie na Number - czyli Number(liczba.toString(2)); zwróci nam np. 1011001, a nie "1011001" - z powrotem znowu otrzymamy String. Co chyba widać ?

Komentarze (0)
Sprawy flabowe, czyli co (nie)piszczy na flabie
 Oceń wpis
   

Flab.pl - miejsce gdzie siedzą developerzy flasha i udawają, że o dupie maryni nie będą gadać...Do rzeczy: flab.pl to forum dla developerów flasha. Nie tych początkujących, co się pytają, czy if ma być z dużej litery i czy może iterować literkami alfabetu, albo czemu mu strona zaczyna pokazywać preloader od 70%. Flab to obecnie tylko forum - jak piszą na forum organizatorzy, nie udało się posklejać i połatać starego flaba tak, by mógł działać w nowych warunkach.

Ostatnio wystąpiły pewne trudności z formularzem rejestracyjnym - tych, którzy mieli problemy z zalogowaniem się/zarejestrowaniem się, proszę o lekturę tego wątku na flab.pl: problem z blokadą rejestracji i ewentualne przekazanie info Bartkowi wg podanej przez niego ścieżki.

A pozostałym czytelnikom mojego bloga, którzy jeszcze się nie wyklikali w swojej wypowiedzi czego chcą, polecam skierować myszkę tam (<==) czyli do ankiety.

Komentarze (0)
[math] Aksonometria - ktokolwiek... [update: rss już działa]
 Oceń wpis
   

...wie jakie różnice są między trymetrią, dimetrią, a izometrią ? Od razu skok do wiki, co ? Oooo nie... w polskiej wiki tego nie znajdziecie - aksonometria, izometria. Znów ktoś dopuścił jakiegoś jajogłowego naukowca do edycji do wiki... dobrze, że choć gdzie indziej w internecie ludzie mają prawdziwe głowy zamiast przerośniętego do szyi jaja.

Czy to prawidłowo, że są takie różnice w polskiej a angielskojęzycznej wersji wiki ?

No, jakie są różnice między trymetrią, dimetrią, a izometrią ? A kto wie, co to jest izometria skośna ?*

//EDIT (przedostatnie pytanie)

//EDIT 2:

//EDIT 3: * - oczywiście jest to pytanie dopełniające do pytania pierwszego, w którym nie pytam "czy wiesz, co to jest"...

Mała poprawka w definicjach mojego bloga - frajdę będą mieli ci, co "przegapili" - mój błąd, przyznaję się - z powodu podania niedozwolonego znaku rss bloga Flash'story & FlashFactory w niektórych czytnikach mógł nie odpowiadać... a więc nadganiajcie, którzy nie czytaliście :).
Komentarze (2)
[as2] Łindołize jurel.lel (windowizeURL, windowizeURLpath)
 Oceń wpis
   

Ot, taka zabawka stworzona z potrzeby wizualizacji ścieżki do pliku.

Wszyscy (piszący w as) wiemy, w jaki sposób flash pokazuje nam adres lokalny - jest to coś w rodzaju tego:

file:///F|/%5FMYDESIGN/%5FPUB/xyz/my%5Fapps.swf

Bardzo przyjemne i zjadliwe, nieprawdaż ? :D

No więc wyodrębnijmy elementy, które stoją nam na przeszkodzie:

- adres jest url-encoded (procenty)
- slashe zamiast backslashy
- "pipe" ( >|<) zamiast dwukropka po nazwie napędu
- określenie protokołu na dzieńdobry ("file:///")

ok, wyodrębnione, teraz przydałoby się jeszcze pokazać, gdzie znajdują się pliki lokalne - czyli pozyskać samą ścieżkę do pliku - czyli musimy odciąć nazwę pliku z rozszerzeniem. Najprościej to zrobić sprawdzając, gdzie "kończy się" nazwa foldera, w którym znajduje się nasz plik - czyli szukamy ostatniego slasha.

A oto cały kod:

 function windowizeURL(url:String):String {
  //
  return unescape((_url.substr(0,_url.lastIndexOf("/")+1)).split("file:///")[1]).split("|").join(":").split("/").join("\\");
 }
 function windowizeURLpath(url:String):String {
  //
  url = windowizeURL(url);
  return url.substr(0,url.lastIndexOf("\\")+1);
 }

Prawda, że ładnie skompresowane ?

Wynik ich działania na stringu zacytowanym u góry wygląda tak:

F:\_MYDESIGN\_PUB\xyz\my_apps.swf

F:\_MYDESIGN\_PUB\xyz\

i o to chodziło. Miłej niedzieli życzę.

MaW

Komentarze (0)
Jak schackierować SWFa ?
 Oceń wpis
   

Jak niektórzy się domyślają (a inni już wiedzą) SWF ("*.swf") to rozszerzenie pliku wykonywalnego flasha, a więc APLIKACJI FLASHOWEJ - w odróżnieniu od FLA ("*.fla"), który nawet nie jest plikiem kodu źródłowego, ponieważ oprócz instrukcji Action script (które coraz częściej /OOP/ są umieszczane w zewnętrznych plikach ("*.as") zawiera "instrukcje" wyglądu stage'u, pozycje klipów i parametry poszczególnych klatek movieclipów, które nie mają odzwierciedlenia w kodzie APLIKACJI (czyli pliku *.swf). To gwoli wytłumaczenia klientom, że nawet  kupując wykonanie aplikacji flashowej od zera, nie kupują zarazem praw do pliku FLA (* o ile umowa nie stanowi inaczej), ale o tym będę jeszcze pisał w innym wpisie.

Przejdźmy do rzeczy - parę wpisów temu popełniłem jeden wpis o łamaniu swfów, gdzie rąbek tajemnicy, który uchyliłem, był... bardzo mały.

Oczywiście pytania prywatne były, a jakże! No więc jak na prywatne pytania uchyliłem prywatnie więcej rąbka tajemnicy, to nawet przez niektórych zostałem obśmiany (no a jakże, przecież "oczywiste oczywistości" gadam). Np. przy tym, że jeden ze sposobów nazwałem "image injection" - oczywiście szczegółów nie poznali, ale obraz na swoje podobieństwo zbudowali (a kto im broni ? nikt :P)

To tyle tytułem wstępu. Pora teraz uchylić taaaaakiego rąbka, czyli przybliżyć parę sposobów jak zobaczyć, co w swfie piszczy (pizga ?).

MEMORY CRAWLER

Sposób najprostszy, bo bez ingerencji w swfa - ot, po prostu wystarczy sobie załatwić skaner pamięci. Jak to działa, nie będę opisywał, bo już ktoś to zrobil za mnie. A oto pokaz (z jutjuba) przeprowadzany na jednej z opisywanych przeze mnie gier - BOXHEADS

A tu link do tego, jak to zrobić (opisują twórcy programu - jednego z wielu): how to cheat flashgames. Oczywiście nie ma akcji bez reakcji: poznaj przeciwnika

Teraz pora pobawić się tym, co przez przeglądarkę przechodzi...

HTTP PROTOCOL SCANNERS

Tu nie ma co opisywać. Są programy, które zajmują się skanowaniem portów HTTP, śledzą co wchodzi, a co wychodzi z przeglądarki - często same są pluginami do przeglądarki, jak np. Data Temper i Live HTTP Headers do FireFoxa. Są też zewnętrzne, działające na konkretnym IP. Cała sztuczka polega na tym, żeby domyślić się co, gdzie, w danym miejscu ciągu oznacza.

DOWNLOAD & MODIFY

Opuszczamy teraz przeglądarkę - no może za chwilę, bo pierw musimy ściągnąć dodatek (jak się nazywa, to nie powiem, bo sam nie pamiętam) do przeglądarki, który pozwoli nam "na żywca" skopiować swfa z przeglądarki. Jak nie mamy takiego narzędzia, to wystarczy wziąć znaleźć na dysku pliki *.swf zapisane w ciągu ostatnich 10-30 minut. Oczywiście nie jest to sposób pozyskania w 100% skuteczny, ale od biedy...

Ok, download już był, teraz pora na modify - a to już wszyscy znają - ściąga się jakiegoś swf dekompilatora i bawi nim. W najgorszym przypadku dostaniemy tylko obrazki, ale to już coś ;)

No ale na akcję jest reakcja - po to ktoś wymyślił obfuskatory, żeby zabezpieczyć swfa przed dekompilowaniem.

CODE RESEARCH

No to... gdy mamy do czynienia z obfuskatorem: zapewne obrazki wyjmiemy, ale poza tym, jedyne co dostaniemy to taką sieczkę:
var \x1 = 681;
while (\x1 = eval("\x1") + 49, eval("\x1") == 670)
{
    \x1 = eval("\x1") - 669;
    break;
}
\x1 = eval("\x1") - 683;
if (eval("\x1") == 669)
{
    \x1 = eval("\x1") + 23;
   
   
}
\x1 = eval("\x1") - 594;
if (eval("\x1") == 930)
{
To już jest przepapane - całego kodu nie ściągniemy, ale... skoro mamy już swfa na dysku, to... zapiszmy w tym samym folderze drugiego swfa, z takim kodem (test.swf to oczywiście nazwa pliku, który ściągnęliśmy na dysk):

var MCL:MovieClipLoader = new MovieClipLoader ();
MCL.loadClip ("test.swf", createEmptyMovieClip ("test", 1));
MCL.addListener (this);
this.onloadInit = function (MC) {
 for (var name in MC)
 {
  for (var val in test[name]) {
   trace(name + "." + val + " = " + test[name][val]);
  }
 }
};

i odpalmy pod kontrolą edytora, albo jakiegoś innego debuggera... Kodu raczej nie zobaczymy, ale zmienne, wartości, nazwy klas już nam wiele dadzą. Jaki z tego wniosek ?

OBFUSKATOR ZABEZPIECZA WYŁĄCZNIE PRZED DEKOMPILACJĄ! Nie przed zajrzeniem w działający kod!

SHARED OBJECTS VIEWER

SO - czyli te "flashowe cookies" o których kiedyś pisałem, też nie są tak bezpieczne, jak się wydaje. Stąd: http://solve.sourceforge.net/ można pobrać projekt, który pozwala bez problemu oglądać te "czaszczeczka" (tylko szę nie udłafcze) i edytować je - a przynajmnej wartości cyfrowe i stringi.

Poza powyższym sposobem mam jeszcze dwa inne, w których da się SO wykorzystywać. Jeden - to wszystko możemy podejrzeć ręcznie (nawet odpalić), jeżeli tylko plik SO (odpowiednio spreparowany) umieścimy w folderze odpowiadającemu SO naszego projektu. Drugi - o nim trochę powiedziałem na spotkaniu "After Party" w Katowicach. Żeby nie rzucał się w oczy: nazwałem go "Function Injection". Koniec na ten temat.

IMAGE INJECTION

I za tą nazwę zostałem obśmiany, a tak dużo można przez to uzyskać!

Wyobraźmy sobie serwis, który pozwala na upload fotek we flashu, z wykorzystaniem w aplikacji flashowej - np. jak na miniklipie ta mutowarka zdjęć. Teraz pomyślmy, że flash w ten sam sposób ładuje i pliki *.jpg, jak i inne *.swf-y. Oświeciła się lampka ?

Jeżeli zmienimy rozszerzenie pliku *.swf na *.jpg, a po stronie serwera nie będzie niczego, co by sprawdzało faktyczną postać pliku, to praktycznie furtkę do swfa już mamy otwartą. I to ONLINE!!! Łącząc teraz niektóre z opisanych sposobów w logiczną całość razem z tym sposobem, mamy władzę nie tylko nad swfem - nad transmisją, zapisem wyników, śledzeniem użytkownika, a w najgorszym przypadku... mamy możliwość zapisu własnego pliku php na serwerze!!!

Dobra, jeżeli ktoś już sprawdza bity (czyli rzeczywistą postać plików), to wie, że około 128 pierwszych bajtów jest ważne - a jeżeli by tak wypróbować, czy administrator serwera zezwolił na odpalenie skryptów php spod innych rozszerzeń ? A pole description jpg-a ?

No to macie teraz prawie 50% mojej wiedzy ;)

Acha: i nie piszcie w komentarzach, że ten a ten idzie zabezpieczyć w taki a taki sposób (chyba, że chcesz się podzielić jakimś swoim autorskim sposobem, ale to już wtedy skontaktuj się prywatnie, a nie poprzez komentarz) - bo ja wiem, że na każdy z tych sposobów da się znaleźć odpór :D - jak już napisałem na każdą akcję znajdzie się reakcja.

Komentarze (0)
Zabezpieczenia zostały złamane!
 Oceń wpis
   

Krótka notka.

Wczoraj, późną nocą, udało mi się znaleźć sposób, aby obejść kodowanie swfów obfuskatorami. Oczywiście te związane z zabezpieczaniem danych, a nie z czytelnością kodu. Choć zapewne jakby się uprzeć, to i kod dało by się "przywrócić".

Uchylę rąbka tejemnicy - sposób wejścia nazwałem... nie - za dużo bym powiedział :). To drugi sposób - skuteczniejszy, a zarazem prostszy niż skanowanie pamięci :).

I jeszcze jedno: żaden allowDomain ani secureDomain przed tym nie zabezpieczy. Ani serializacja czy też hash'owanie transmisji.

Czy gra typu "jeszcze bardziej efektywne zabezpieczanie swfa" jest warta świeczki ? Myślę, że jest. Chociażby z powodu aplikacji konkursowych, przesyłania poufnych danych itp.

Jest parę sposobów, które na bieżąco testuję pod kątem zabezpieczenia przed tego typu włamianiami. Na skanery pamięci sposób już mam. Na pozostałe... wiadomo, zawsze znajdzie się ktoś przebieglejszy...

Nie - nie zamierzam nikomu rzucać rękawicy - po prostu, poprawiam komfort psychiczny moich klientów ;-).

Komentarze (1)
Bezpieczne przesyłanie danych - jak narobić smaczka ?
 Oceń wpis
   

Ostatnio mam zagwózdkę z okazji zapytania klienta pt "czy da się bezpiecznie we flashu przekazywać dane na serwer". Jak na razie jestem w fazie prób, ale jak się wydaje, wszystko będzie powoli szło w dobrym kierunku.

Ponieważ projekt ten miałby obejmować stronę flashową, serwerową i desktopową, do tego projektu będzie potrzebna osoba dobrze poruszająca się w AIR. No i oczywiście ktoś, kto w php umie różne dobre rzeczy wyczarowywać. Zgłoszenia i oferty współpracy mile widziane.

Wracając do tematu. Dotychczas - oprócz sposobów z "(r)" w nazwie - do przesyłania danych używałem metody scramble() i unscramble() które według określonego algorytmu "haszowały" mi dane. Oczywiście problem był tego typu, że efektem działania był string.

Jak to bywa w takich sytuacjach, trzeba było pójść po rozum do głowy i od czegoś zacząć.

Ja zacząłem od tego, że spytałem się administratora serwera, czy wywołanie https można przesunąć na inny port. Okazało się, że jest taka możliwość. Następnym krokiem było sprawdzenie, czy flash sobie poradzi z takim przesyłem po htps - tak, jak najbardziej - przydał się plik crossdomain.

Po swojej stronie przerobiłem troszeczkę metodę scramble() - znaczy: napisałem ją na nowo. Tym razem zmiana polegała na tym, że dla danego obiektu została zbudowana tabela typów - scramblowany obiekt już nie wraca w postaci stringu, lecz... obiektu! Oczywiście takiego, z którego niewiele można odczytać... gdyby nie tabela typów.

Tak spreparowany obiekt nadaje się teraz do wysłania przez amfphp na serwer.

A resztę - osłońmy zasłoną milczenia...

Komentarze (3)
Skrypt dla "kroczącego wygaszania"
 Oceń wpis
   

Wyrzucam z projektu jako niepotrzebne, a by się nie zmarnowało... zostawiam na blogu.

Ten skrypt powoduje powolne "wygaszanie" (_alpha) kolejnych obiektów o nazwach group+[nr] od nr 8 do 1, ale bardzo prosto zmienić tą numerację na inną.

...wyrwane z większej całości - żeby nie było Wam za łatwo :P

 private function hideButtons (group:String, _MC:MovieClip) {
  //
  var i:Number = 8;
  var tMC:MovieClip;
  //
  do
  {
   tMC = MC[group + i];
   trace ([group, i, tMC]);
   //
   with (tMC)
   {
    if (!_visible)
    {
     i--;
     continue;
    }
    else
    {
     _alpha -= 10;
     if (_alpha <= 0)
     {
      _alpha = 100;
      _visible = false;
     }
     else
     {
      break;
     }
    }
   }
   i--;
  } while (i > 0);
  //
  if (i == 0)
  {
   timer.removeListener (_MC);
  }
 }

uwaga: potrzebuje Timer-a do inicjalizazji:

timer.addListener(_MC, 0, Delegate.create(this, hideButtons, group, _MC));

Komentarze (0)
11 rad, jak być dobrym flashdeveloperem
 Oceń wpis
   

No to teraz posypią sie na mnie gromy...

...ktoś podesłał mi coś... co nie mogło pozostać bez echa... oto moje 11 rad:

1. Korzystaj z wzorców projektowych

..ale z umiarem - nie na siłę. Staraj się w tym naśladować innych, ucz się od "starszych stażem" kolegów po fachu, z książek, publikacji w necie, dostępnych przykładów. Naucz się tego artykułu, jak nie na pamięć, to przynajmniej czytać ze zrozumieniem.

2. Nie rzucaj się od razu na głęboką wodę

To, że przeczytałeś o MVC nie znaczy, że musisz go na siłę stosować. A o MVP słyszałeś ? O CPV ? Zaczynaj od jednej klasy widoku i modelu na tyle elastycznego, byś mógł go ponownie wykorzystać (dotyczy to także gier). Uprość zasady/stosowanie wzorców tak, by dostosować je do Twoich potrzeb.

3. Stosuj nazewnictwo zgodnie z zaleceniami języka

...lub specyfikacji. Najlepiej, by nazewnictwo było w języku angielskim, co ułatwi Ci później pracę z innymi developerami - nie wszyscy mieszkają w Polsce, nie wszyscy tylko w Polsce publikują. Nie skracaj na siłę nazw zmiennych, metod - "bo będzie szybciej" - "dvr1, ngr, lv_it1" - pomyśl sobie, co z tego zrozumiesz, jak będziesz musiał wrócić do projektu za pół roku ?

4. Kontekst Twoim przyjacielem

 Gdy musisz wykorzystywać zdarzenia obiektów, to pamiętaj o tym, że masz w rękach potężne narzędzie delegowania metod. Staraj się skupiać słuchaczy wokół niewielu obiektów obserwowanych. Jeżeli nie musisz, nie stosuj wzorca obserwator na korzyść delegowania. Jeżeli już musisz, niech obiektem obserwacji będzie klasa nadrzędna, której metody delegujesz.

5. Pamiętaj o tym, że istnieją zmienne lokalne, publiczne, prywatne i statyczne.

Nie przekazuj referencji do obiektu bezpośrednio, jeżeli jest ona wcześniej już przypisana do zmiennej klasy bieżącej. Gdy potrzebujesz działać wielokrotnie na obiektach, korzystaj ze zmiennych lokalnych - np. zmienne iteracyjne, referencje do obiektów wewnątrz pętli - grupuj działania na danego typu obiektach w odpowiednich metodach (lub klasach) i tym metodom (metodom tych klas) przekazuj wygenerowane referencje.

6. Timeline nie jest Twoim przyjacielem, ani też wrogiem.

 Ogranicz używanie go do minimum. Pamiętaj, że dla Ciebie korzystanie z osobnych plików (klas) jest korzystniejsze. Oczywiście, będą takie klatki, bez których projekt nie ruszy - wykorzystaj wtedy polecenie #include [nazwapliku.as] - będziesz mógł wtedy zawartość klatki przenieść do osobnego kodu. Pamiętaj, że obok Ciebie w zespole będzie jeszcze grafik/designer, a prawdopodobnie też i animator. To dla nich został stworzony timeline. Pomóż im zarządzać nim tak, by Wasze interesy nie kolidowały ze sobą nawzajem.

7. Nie sil się na używanie słów, których nie rozumiesz.

 Zwłaszcza w stosunku do osób, które z "fachowego słownictwa" deweloperskiego jeszcze mniej rozumieją niż Ty! Jeżeli Twój kolega po fachu mówi rzeczy, co do których rozumienia masz wątpliwości - powiedz mu, żeby Ci wytłumaczył o co chodzi. To nie boli, a potrafi przynieść wymierne pozytywne rezultaty dla obu stron. Jeżeli masz wrażenie, że używa ich w niewłaściwym kontekście - zapamiętaj te słowo, ten kontekst - zapisz je sobie, w wolnym czasie poszukaj informacji na ten temat w internecie.

8. Grafika. Designer/grafik i animator to osoby, bez których projekt by nie powstał.

Grafika. Nawet programując w innych językach wizualizacyjnych masz do dyspozycji przestrzeń roboczą projektu, w której rozmieszczasz obiekty na pozycjach im przypisanych. Rzadko kiedy w kodzie zmieniasz ich położenie - o ile nie wymaga tego interakcja z użytkownikiem. Nie ma nic złego, że obiekty na Stage'e - zwłaszcza te graficzne - będą poukładane zgodnie z zasadą WYSIWYG.

Gafik, animator - gdyby nie oni, Twój projekt prawdopodobnie wyglądał by na stronę w stylu "YE YE, to jest moja pierwsza strona ołaaa" (czyli leżał i kwiczał). Korzystaj z ich pomocy jak tylko możliwe. Pamiętaj: Klient patrzy na efekty. Lepiej jest dać dwie godziny czasu grafikowi na narysowanie dwóch obiektów lub animatorowi na stworzenie realnej animacji niż spędzić dziesięć dni siedząc nad kodem i próbując to samo "napisać z palca". Człowiek po to ma oczy, by je wykorzystywał do tworzenia. Gdyby graficy i animatorzy byli niepotrzebni, zamiast monitorów prawdopodobnie mielibyśmy czytnika braila. Te litery, na które teraz patrzysz, czy też kod Twojego programu lub jakiekolwiek inne znaczki, to też grafika. To, co możesz dla nich zrobić, by lepiej z nimi współpracować, to nauczyć ich prawidłowego używania podstaw kodu. O ile nad rozpoczęciem animacji Twój kod ma kontrolę, o tyle wielkim nieporozumieniem jest spradzanie interwałem, czy animacja się już skończyła. Naucz animatora, by na koniec animacji dodawał w ostatniej jej klatce wspólnie uzgodnioną komendę - np. onAnimationfinish(). Niech będzie do niej przypisana metoda wydelegowana z Twojej klasy (to Twoja działka). Naucz grafika korzystać z nazewania klatek za pomocą labeli i grupowania obiektów w ponazywanych klipach, a nie trzymania ich w grupach na Stage'u. Wytłumacz mu, że jedną magiczną linią Ty możesz spowodować, że narysowanej przez niego postaci zniknie bluzka, ale tylko pod warunkiem, że będzie ona nazywać się "bluzka" i jeżeli tych bluzek będzie dziesięć, to każda z nich będzie miała swoją unikatową nazwę. Wytłumacz mu, że lepiej Ci się pracuje, jeżeli są w warstwach jednej klatki, niż gdy są w wielu klatkach.

9. Wykorzystuj ten sam kod/model wielokrotnie.

 Myślisz, że diamenty, które tak uwielbiają kobiety, w takiej formie wychodzą z kopalni ? Nie - od diamentu do brylantu długa droga. Tak samo za każdym kolejnym projektem Twój kod będzie podlegał modyfikacjom, aż wkońcu uzyska wygląd zbliżony do "brylantu". Jeżeli stwierdzasz, że sam (lub z drugim programistą) jesteś (-cie) w stanie zapanować nad projektem używając wyłącznie swoich sił (swojego kodu), to korzystaj z własnego modelu - lepiej znać własny model na wylot niż nie znać się mało lub wcale na wielu, cudzych modelach. Jeżeli stwierdzasz, że samemu przychodzi Ci z trudnością zapanować nad projektem - poszukaj w sieci - może już ktoś stworzył taki szkielet projektowy (framework) i go udostępnił ? Jeżeli korzystasz już z takiego frameworka, pamiętaj że mniej czasu zajmie dopisywanie rzeczy, które są Ci potrzebne, niż wdrażanie innego frameworka, zwłaszcza gdy nie użyjesz go więcej niż raz.

10. Trace czyli output.

 Każdy program, nawet najlepszy, rozpoczyna swoje dzieje w wersji "wszystko jest, a nic nie działa". Wtedy Twoim pomocnikiem będzie komenda trace oraz konstrukcja try/catch, no i debugger. Zazwyczaj w tej kolejności, a nie innej. Stwórz także klasę/obiekt, który będzie przechwytywał/do którego będziesz wysyłał wyniki działania projektu w jego naturalnym środowisku (exe/www/inne), by pomógł Ci je wyświetlić, przeanalizować - używaj dodatków, które pomogą Ci zdebugować kod w tym środowisku.

11. Zastanów się jaki jest Twój target.

 Jakich narzędzi do tego potrzebujesz ? Czy będziesz tworzył gry, aplikacje bazodanowe, interfejsy użytkownika, aplikacje desktopowe ? Nie rzucaj się na coś dlatego, że "jest trendy". Lepiej zrobić coś "własnym" narzędziem, które znasz od podszewki, niż znosić sklinania szefa lub tracić klienta bo właśnie trafiłeś na taką zagwozdkę, której nie wiesz jak rozwiązać, bo nie znasz Twojego nowego narzędzia.

MaW

Hmmm... czy ja jestem dobry flashdeveloperem ? Hmmm... Oczywiście! :)

Komentarze (7)
[as] Spowalniacz flasha
 Oceń wpis
   

Każdy z flashowców wie, jak przyspieszyć odtwarzanie animacji - przeskok o więcej niż jedną klatkę. Ale czasami (zwłaszcza w niektórych grach) potrzebujemy nie przyspieszenia, a zwolnienia działania aplikacji.

Tak mi chodził od pewnego czasu po głowie pomysł na to, aby wykorzystać zabezpieczenie "nieskończonej pętli" - zmorę początkujących programistów, kiedy to albo warunek jest źle ustawiony, albo zmienna nie ta i wykonywanie skryptu kończy się komunikatem:

A sc<x>ript in this movie is causing Flash Pla<x>yer to run slowly. If it continues to run, your computer may become unresponsive. Do you want to abort the sc<x>ript ?

Najczęściej "ból" ten powoduje źle zainicjonowana (lub ze źle ustawionym warunkiem) pętla while. Z dokumentacji flasha możemy wyczytać, że po 20 sekundach wykonywania takiej pętli zostanie ona przerwana warunkowo wyżej pokazanym komunikatem. Oznacza to jedno: Flash Player podczas obliczeń kontroluje czas, jaki upłynął od zainicjowania klatki ze skryptem. Wobec tego, skoro może to zrobić flash, dlaczego nie moglibyśmy to zrobić i my ?

Do powyższego wykorzystam onEnterframe i dwie zmienne:goAfter - będę w niej trzymał czas trwania pętli while oraz nextStop - która posłuży mi do przechowywania czasu następnego postoju. Oraz - co najważniejsze - niezależną od "obciążenia" i czasu trwania jednej klatki funkcję systemową getTimer(), z której będę wyciągał, ile czasu (w milisekundach) upłynęło.

var goAfter:Number = 250;
var nextStop:Number = nextStop == undefined ? getTimer () + goAfter : nexstop;
this.onEnterframe = function () {
while (getTimer () < nextStop) ;
nextStop = getTimer () + goAfter;
};

Jak to działa ? Pusty while wykonuje się tak długo, jak jest niespełniny warunek getTimer(), a ponieważ wiemy, że się wykona dzięki niezależności getTimer-a od czasu trwania klatki, możemy co następny krok powiększać tą wartość o następny spowalniający czas - czyli o wartość goAfter. I tak w koło Macieju :)

A oto działający przykład:


SWF: Przykład spowalniania FPS (ilości klatek na sekundę)
PS. Nie wiem, jak u Was, ale u mnie zużycie zasobów procesora wzrosło do 50%... nie ma róży bez kolców...
Komentarze (1)
Flab ponownie na nogach
 Oceń wpis
   

Już tylu znajomych się zarejestrowało na flabie, a jeszcze żaden z nich nie napisał na swoim blogu, że flab znowu chodzi!

Flab.pl - miejsce gdzie siedzą developerzy flasha i udawają, że o dupie maryni nie będą gadać...Do rzeczy: flab.pl to forum dla developerów flasha. Nie tych początkujących, co się pytają, czy if ma być z dużej litery i czy może iterować literkami alfabetu, albo czemu mu strona zaczyna pokazywać preloader od 70%. Flab to obecnie tylko forum - jak piszą na forum organizatorzy, nie udało się posklejać i połatać starego flaba tak, by mógł działać w nowych warunkach.

W starej wersji struktury, na starym serwerze można znaleźć jednak wiele interesujących artykułów i zagadnień, które były już na forum omawiane. Tutaj poprzednia wersja - dla szukających, zainteresowanych artykułami z poprzedniej wersji flaba.

Zacytuję może kawałek tekstu "o flabie" z tej poprzedniej wersji:

Flab to serwis poświęcony przede wszystkim programowi Macromedia Flash i technologiom pokrewnym. Powstał z inicjatywy kilku osób, którym zależało na wprowadzeniu do społeczności serwisu silnego merytorycznie, otwartego na inne inicjatywy oraz dającego coś więcej niż tylko rozbudowane forum.

 Nie chcemy się ograniczać tylko do Flasha, interesują nas inne dziedziny informatyki, inne języki programowania. Zapewne będzie można poczytać od czasu do czasu o Javie, C#, PHP, Pythonie. O algorytmach, programowaniu obiektowym, nowych technologiach i zupełnych dziwactwach.Tematy nie wpisujące się w ramy serwisu będziemy poruszali na naszych blogach.

Mam nadzieję chłopaki, że Wam nie przeszło (i nie przejdzie) - skoro odpaliliście flaba ponownie (i to chyba już po raz trzeci) ?

Życzę Wam powodzenia i żeby nie zabrakło Wam sił :)

Komentarze (0)
flash9c.ocx, flash9b.ocx, flash9a.ocx (flash*.ocx) (upd)
 Oceń wpis
   

Note: English version of this text is below the polish version.

Note 2: Jak odinstalować plugin pod FireFoxem ? --> CNET.com:Problems updating the Flash player in Firefox? Here's help

Ten wpis jest ukłonem w stronę osób wchodzących na mój blog z googli.

Przeglądając analityki google zauważyłem, że spory procent ludzi trafia na mój blog przeszukując sieć pod kątem słowa kluczowego flash9c.ocx - pliku, o którym wspominałem w jednym z wcześniejszych wpisów.

Ten wpis dotyczy problemu, który może wystąpić w przypadku systemów windows XP/XP professional z systemem plików NTFS, polegający na braku możliwości usunięcia flash9c.ocx przez zwykłego użytkownika - np. po nieprawidłowej reinstalacji systemu - np. po takiej reinstalacji nie da się z powodu tego pliku sformatować dysku z poziomu windows, może się też nie dać zainstalować nowego flashplayera.

Ok, to tyle wstępu, pora na rozwiązanie problemu.

Po pierwsze: nic nie zrobisz, jeżeli nie znasz hasła superadministratora, o które prosi windows XP podczas instalacji - jest to hasło do konta "Administrator", które pojawia się dopiero podczas pracy w trybie awaryjnym.

Jak wejść do trybu awaryjnego: przytrzym klawisz F8 przy odpalaniu komputera - po chwili powinno otworzyć się menu tekstowe, gdzie na pierwszej pozycji będzie tryb awaryjny.

Ok, jeśli już znasz hasło superadministratora i zalogowałeś się na konto "Administrator", to musisz poszukać takiej ścieżki, jak ta na obrazku (ale zapewne już ją znasz).

How to find the flash9c.ocx file path (ścieżka do pliku flash9c.ocx)

Teraz musisz wybrać (kliknąć) plik "flash9C.ocx" (w nazwie może być inna literka po 9, możesz mieć także do czynienia z wcześniejszym playerem flasha - zasada jest taka sama). Musisz wybrać z menu spod prawego przycisku myszy "Właściwości", wejść do zakładki "Zabezpieczenia" - wybrać grupę "Administratorzy" - sprawdź, czy wszystkie uprawnienia są zaznaczone na "Zezwalaj":

flash9c.ocx - okno Właściwości, karta zabezpieczenia

Następnie kliknąć "Zaawansowane" w dolnym prawym rogu. Pokaże Ci się okno jak poniżej:

flash9c.ocx - zaawansowane ustawienia zabezpieczeń

Tam musisz dla podświetlonych pozycji -zaznaczyć "Zezwalaj" dla "Usuwanie" - i odznaczyć "Odmów" dla "Zapis atrybutów" (jeżeli nie zmienisz tej pozycji, to po wyjściu z okna zmiany nie będą uwzględnione).
Jeżeli wszystko wykonałeś poprawnie, możesz pozamykać kolejne okienka (klikając pierw "Zastosuj"). Teraz bez problemu możesz usunąć feralny plik.

Jeżeli kłopot ten wystąpi z pozostałymi plikami tego folderu, musisz postępować tak samo ze wszystkimi.

Ok, teraz wersja angielska (sorry for my terrible english :D ):

ENGLISH VERSION

This inscription is gratify for people who enter my blog by searchengines (i.e.google).

When I looked at google analytics I found, that more of hits to my blog is maked by looking for "flash9c.ocx" keyword - the name of file, which I use in one of my earlier inscriptions.

This tutor says about a trouble, which can be localized in windows XP/XP professional systems with NTFS filesystems on system disc, when you may not to delete flash9c.ocx file on normal account - i.e. after incorrect system reinstalation - after that, you can't format system disc in windows installer, you can not to install a newest flashplayer version.

Ok, finish of the entrance, now the receipe:

At first: You do nothing, if you have'nt got superadministrator password - the one, which windows sets during instalation - it's the password to account "Administrator", which one shows you only in the safe mode.

How to get to the self mode: when you PC is booting up, press and hold F8 key until you can see the text menu, at first place you can see: "self mode". Select it.

Ok, if you have got superadministrator password and you are logged-in to account "Administrator" in self mode, you must find the path to the file, just like at the picture:

How to find the flash9c.ocx file path (ścieżka do pliku flash9c.ocx)Now

Now you must select (press on) file "flash9C.ocx" (the name can have other letter after "9", or other number - earlier flashplayer version - it's all the same method). Select "Properties" form the right mouse button menu, go to the tab "Security" - select "Administrators" group - check, if all permissions are set on "allow":

Properties window of flash9c.ocx file

After that you must press "Advanced" in bottom right corner. A window pictured below should appear:

Advanced Security Settings for flash9c.ocx file

Then, in position "Delete" set "allow" and uncheck "Deny" for "Write attributes" (if you can't change this position, you may not to have changes saved).
If you did all okey, you can close all properties windows (but click first "Apply"). Now you can delete selected file without any trouble.

If you have problems with other files in this folder, you must repeat this instruction for every file.

To Patrick from retenor.com and Jakub Dec thanks for feedback (Jakub for fast reaction, Patrick for english system screens).

Powodzenia w usuwaniu problemu/Good luck in fixing this problem.

PS. Wiem, że w wersji angielskiej są błędy, jeżeli chcesz pomóc mi je poprawić, to napisz do mnie z prawidłową wersją tekstu - będę wdzięczny.

Komentarze (0)
[as2]Delegate.create ze wszystkimi argumentami
 Oceń wpis
   

Wiem, wszyscy to już mają... ale ja ćwiczę :D

Zacznijmy od początku: w mx.utils jest klasa Delegate, która pozwala na wywołanie danej metody w innym łańcuchu zasięgu - z innym niż jej własny this. Jak stosować i gdzie wiemy - było już u mnie na blogu.

Pomijając wersję z jednym argumentem, która po drodze "przeszła jak burza" (halo BurzaOne :D) tak że nie warto o niej wspominać, przyszła pora na uwolnienie się od include'ów. To znaczy: AS2 to nie tylko sztywne deklaracje typów zmiennych - to praca na klasach. A więc:

1. Swoje klasy "systemowe" trzymam w folderze "system", który jest... gdzieś tam na ścieżce zarejestrowanej w Acionscript2.0 settings/classPaths - by nie nadpisywać delegate znajdującego się w mx.utils.

2. Kod Delegate.as:

//****************************************************************************
//Extended Delegate - sends all parameters to the called function
//****************************************************************************
//
//
class system.Delegate {
 /**
 Creates a functions wrapper for the original function so that it runs
 in the provided context.
 @parameter obj Context in which to run the function.
 @paramater func Function to run.
 */
 static function create (obj:Object, fn:Function):Function {
  //
  var args:Array = arguments.splice (2);
  //
  var f = function () {
   trace ("Delegate " + arguments);
   arguments.callee.source = this;
   fn.apply (obj, args);
  };
  f.target = obj;
  return f;
 }
 //
 function Delegate (f:Function) {
 }
}

Przykładowy fla:

import system.Delegate;
var a = {};
a.onframe = function () {
 //
 trace(this.msg);
 trace(arguments);
}
a.msg = "Jesteś w A";
this.onEnterFrame = Delegate.create(a,a.onframe,"c","d","e");

i działa :)
Komentarze (0)
Lorem ipsum (ypsum ?) dolor sit amet
 Oceń wpis
   

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.  Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.  Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.  Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.  Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.  Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.  Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.  Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.  Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at.
Vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.  Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.  Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
Autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 

Jeżeli dużo projektujesz, to wiesz dobrze, że nie ma czasu na wymyślanie różnych tekstów - wypełniaczy. Co gorsza, zdarza się, że tekst, który musisz użyć, musi mieć conajmniej stronę...

Ktoś gdzieś kiedyś wymyślił, żeby zrobić taki uniwersalny tekst, właśnie celem użycia go jako wypełniacz. Jeśli jeszcze tego tekstu nie masz w swoich zbiorach - skopiuj go sobie, zapisz do pliku tekstowego, nazwij "loremipsum.txt" - będzie  Ci służył przez wiele lat.

//EDIT: superlink od ndb (w komentarzach): http://lipsum.pl/index.php - nowomowa i "Pan Tadeusz" (i nie tylko) także mogą być "wypełniaczami".

Komentarze (5)
Jazda po labelach
 Oceń wpis
   

O, długo mnie tutaj nie było... wiele się zmieniło :D

No, ale nie jestem z "przepraszaczy" - za co mam przepraszać ? Za to, że zarabiałem "na chleb" ? Każdy, kto ma jakąś tam hierarchię wartości, umie rozróżnić, co jest ważniejsze i bardziej potrzebne...

Do rzeczy. Jednym z braków, które nie zostały załatane we flashu to widoczność labeli w Actionscript. Można to naprawić - jedni stosują jsfl, aby przepisywał im aktualnie wprowadzoną nazwę (label) klatki kluczowej do zmiennej, inni wpisują z palca, a ja... ja należę to grupy tych całkiem innych.

Jeżeli uważasz, że korzystanie z timeline'u (tajmlajnu) we flashu jest niepotrzebne, jeżeli uważasz, że jest to zbędny przeżytek, to tak naprawdę daruj sobie flasha. I nie nazywaj siebie flashdeveloperem. Nie chcesz widzieć tajmlinu - przesiądź się na javę, tam są też naprawdę "fajne kawałki".

Narażę się tym conajmniej paru osobom czytającym mojego bloga (a niektórzy z nich są dla mnie naprawdę Guru AS), ale nie odpuszczę. Jedną ze ścieżek porozumień z flashdesinerem oraz flashanimatorem jest umiejętność korzystania z tajmlajnu.

Niektórzy - Ci mniej zorientowani z pożytku płynącego z używania tajmlajnu mnożą/każą mnożyć Bogu ducha winnym designerom lub animatorom obiekty w bibiotece bardziej niż króliki. Najczęściej po to, by mieć obraz tego, co jest w każdym stanie klipa/buttona.

Czy to jest potrzebne ? Czy musisz kochany kolego/koleżanko tak zaśmiecać bibliotekę ? Zapewne powiesz, że tak - no bo po co używać tajmlajnu i labeli, skoro nie możesz ich odczytywać z poziomu kodu ?

Skoro sam system Ci tego nie udostępnia, to może spróbowałbyś/spróbowałabyś to zmienić ?

Oto mój pomysł:

MovieClip.prototype._play_ = MovieClip.prototype.play;
MovieClip.prototype._stop_ = MovieClip.prototype.stop;
MovieClip.prototype._gotoAndStop_ = MovieClip.prototype.gotoAndStop;
MovieClip.prototype._gotoAndPlay_ = MovieClip.prototype.gotoAndPlay;
MovieClip.prototype.labels = {};
MovieClip.prototype.framelabels = [];
//
MovieClip.prototype.gotoAndStop = function (frame) {
 //
 var lastframe = this._currentframe;
 //
 if (frame instanceof String)
 {
  if (this.labels[frame] != undefined)
  {
   this._gotoAndStop_ (this.labels[frame]);
  }
  else
  {
   this._gotoAndStop_ (frame);
  }
  //
  if (lastframe != this._currentframe)
  {
   this._prevlabel = this._label;
   this._prevlabelframe = this._labelframe;
   this._label = frame;
   this.isStopped = true;
   this.isPlaying = false;
   this._labelframe = this._currentframe;
   this.labels[frame] = this._currentframe;
   this.framelabels[this._currentframe] = frame;
  }
 }
 else if (frame instanceof Number)
 {
  this._prevlabel = this._label;
  this._prevlabelframe = this._labelframe;
  this._gotoAndStop_ (frame);
  //
  if (lastframe != this._currentframe)
  {
   this.isStopped = true;
   this.isPlaying = false;
   this._label = this.framelabels[this._currentframe];
   this._labelframe = this.labels[this._label];
  }
 }
};
//
MovieClip.prototype.gotoAndPlay = function (frame) {
 //
 var lastframe = this._currentframe;
 //
 if (frame instanceof String)
 {
  if (this.labels[frame] != undefined)
  {
   this._gotoAndPlay_ (this.labels[frame]);
  }
  else
  {
   this._gotoAndPlay_ (frame);
  }
  //
  if (lastframe != this._currentframe)
  {
   this._prevlabel = this._label;
   this._prevlabelframe = this._labelframe;
   this._label = frame;
   this.isStopped = false;
   this.isPlaying = true;
   this._labelframe = this._currentframe;
   this.labels[frame] = this._currentframe;
   this.framelabels[this._currentframe] = frame;
  }
 }
 else if (frame instanceof Number)
 {
  this._prevlabel = this._label;
  this._prevlabelframe = this._labelframe;
  this._gotoAndPlay_ (frame);
  //
  if (lastframe != this._currentframe)
  {
   this.isStopped = false;
   this.isPlaying = true;
   this._label = this.framelabels[this._currentframe];
   this._labelframe = this.labels[this._label];
  }
 }
};
//
MovieClip.prototype.stop = function (framelabel) {
 //
 this.isStopped = true;
 this.isPlaying = false;
 //
 if (framelabel instanceof String)
 {
  //
  this.labels.framelabel = this._currentframe;
 }
 this._stop_ ();
};
//
MovieClip.prototype.play = function () {
 //
 this.isStopped = false;
 this.isPlaying = true;
 this._play_ ();
};
MovieClip.prototype.isPlaying = true;
MovieClip.prototype.isStopped = false;

Polega on na prostym zastąpieniu wbudowanej obsługi skoków między klatkami swoją własną - zanim klip przeskoczy do innej klatki, my sobie zdążymy troszeczkę w nim namieszać...

Wyżej podany kod dodaje kilka właściwości do klipa: isStopped - gdy klip się "nie rusza", isPlaying - gdy "chodzi"; _label  - nazwa bieżącej klatki kluczowej (uwaga! ustawiana jest także przy gotoAndPlay - ważne jest wtedy sprawdzenie właściwości isPlaying lub isStopped ); _prevlabel - przechowuje nazwę poprzedniego labela; _prevlabelframe - przechowuje numer klatki kluczowej przypisany do poprzedniego labela.

Podczas prac nad tymi prototypami wprowadziłem także dwie równoznaczne tablice - jedna w formie obiektu pozwalającego znaleźć numer klatki kluczowej danego labelu - labels, druga w formie tablicy zbierającej nazwy labeli i przypisującej je odpowiednim klatkom - framelabels.

Wirtualne labele klatek można ustawiać stosując albo poprzez metodę setLabel(frame_nm, frame_nr) albo poprzez rozszerzonego stop-a. Nie radzę ustawiać ich bezpośrednio w tabelach - co jedna metoda to nie ustawienie dwóch właściwości (choć niby to samo).

Mankamenty mojego rozwiązania są dwa - pierwszy: dopóki ręcznie nie ustawimy labeli poprzez setLabel lub nie przeskoczymy do istniejących labeli na tajmlajnie, nie będziemy ich widzieć. Drugi - to raczej nie mankament: te metody wymagają samodyscypliny. Kto nie rozumie dlaczego, niech spróbuje odpalić ten kod w klipie conajmniej paroklatkowym z użyciem frame By frame Graph:

function stop () {
 //
trace("zastopowałeś klipa ? a miało być play() - prawda ?");
 this.play ();
}
stop ();

Nie wszystko, co widzimy, jest tym, czym się wydaje...

Odpowiedź: używaj this.metoda() klip.metoda() with (klip.klipa) { metoda() } w stosunku do metod nadpisanych, żeby działały.

Komentarze (4)
[as1] Pseudo-klasa TIMER
 Oceń wpis
   

Gdzieś, kiedyś, ktoś rzucił parę słów nt. globalnej klasy Timer, która by obsługiwała wszystko, co chcemy - i oEFy i intervale - było to w kontekście as2.0 oczywiście, ale posiadając wcześniej wyprodukowaną metodę useAfterTime() pod potrzeby projektów używałem kolejną własną jej wersję, "bardziej usamodzielnioną" - zupełnie wystarczającą dla własnych projektów. Dlaczego używałem właśnie ją ? setInterval wymagał wg. mnie zbyt wielu skomplikowanych zabiegów, żeby nim manewrować - to po pierwsze, po drugie: useAfterTime() powstała pod flash 5 (!!!), po trzecie: zacytuję liveDocs Macromedii:

If interval is less than the movie frame rate (for example, 10 frames per second (fps) is equal to 100 milliseconds), the interval function is called as close to interval as possible. You must use the updateAfterEvent function to make sure that the screen refreshes often enough. If interval is greater than the movie frame rate, the interval function is only called each time the playhead enters a frame in order to minimize the impact each time the screen is refreshed.

Więc po co kruszyć kopie ? Poprawiłem useAfterTime i przez następne lata z coraz to nowymi elementami mógł dalej trwać...

W pewnym momencie ta "bardziej usamodzielniona wersja" zaczęła się do tego stopnia rozrastać, że... wypadało ją napisać ponownie :).

Oto i ona:

//
//wymaga Delegate
//
_global.TIMER = (_global.TIMER == undefined) ? {} : _global.TIMER;
//
TIMER.addListener = function (obj, time, todo, times) {
 //
 this._listeners[String (obj)] = {stepTime:time, FN:todo, times:times, nextTime:(getTimer () + time)};
 //
 if (this.MC.onEnterframe == undefined)
 {
  this.MC.onEnterframe = Delegate.create (this, this._OEF);
 }
};
//
TIMER.removeListener = function (obj) {
 //
 delete this._listeners[String (obj)];
};
//
TIMER._OEF = function () {
 //
 if (!this.enabled)
 {
  return;
 }
 trace ("oEF");
 //
 var isTime = getTimer ();
 var obj = {};
 var count = 0;
 //
 for (var name in this._listeners)
 {
  count++;
  obj = this._listeners[name];
  //
  if (obj.nextTime < isTime)
  {
   trace ([name, obj.nextTime, typeof (obj.FN)]);
   //
   obj.FN (eval (name));
   //
   obj.nextTime = obj.nextTime + obj.stepTime;
   //
   if (obj.times > 0)
   {
    if (--obj.times == 0)
    {
     this.removeListener (name);
    }
   }
  }
 }
 //
 if (count == 0)
 {
  trace ("koniec oEFa");
  delete this.MC.onEnterframe;
 }
};
//
TIMER.init = function (MC) {
 //
 TIMER._listeners = (TIMER._listeners == undefined) ? {} : TIMER._listeners;
 //
 if (this.MC == undefined)
 {
  this.enabled = true;
  this.MC = MC.createEmptyMovieClip ("_timer_", MC.getNextHighestDepth ());
  //
  trace ([this.MC, "tutaj timer"]);
 }
};

jak widać w nagłówku wpisu, działa pod as1, a więc będzie takze używać podanego we wcześniejszym wpisie Delegate.create dla as1.

Może jeszcze jedno wtrącenie: osoby używające flasha MX, potrzebują wbicia takiego prototypu przed odpaleniem TIMERu:

MovieClip.prototype.getNextHighestDepth = function () {
 var depth = 0;
 var MC_depth = 0;
 var name = "";
 var MC = "";
 for (name in this)
 {
  MC = this[name];
  if (typeof (MC) == "movieclip")
  {
   MC_depth = MC.getDepth ();
   depth = (depth < MC_depth) ? MC_depth : depth;
  }
 }
 return ++depth;
};

co zapewni im obsługę metody tworzącej klip użyczający oEFa na zawsze pustym poziomie (depth).

Na początku, aby klasa zaczęła działać należy użyć:

TIMER.init(klipdocelowy);

co spowoduje, że będziemy mogli za pomocą metod addListener i removeListener usuwać i dodawać klipy nasłuchujące. Dalsze działanie przedstawię na przykładach:

TIMER.addListener(klip_rysowany,5000,Delegate.create(this,this.rysujKwadrat),1);

^ To wywołanie spowoduje narysowanie za 5 sekund kwadratu w klipie klip_rysowany.

TIMER.addListener(klip_jakikolwiek,1000,Delegate.create(this,this.pokazCzas),10);

^ To wywołanie spowoduje 10 razy pokazanie czasu (wykonanie metody pokazCzas) co 1 sekundę.

TIMER.addListener(klip_kursora,0,Delegate.create(this,this.przesunKursor),0);

^ To wywołanie spowoduje co klatkę (a więc jak onEnterframe) przesunięcie kursora (bliżej określonego w metodzie przesunKursor)

TIMER.removeListener(klip_nasłuchujący);

^ To wywołanie spowoduje usunięcie klipu nasłuchującego ze "zgrai słuchaczy"

TIMER.enabled = false;

^ To wywołanie powoduje przejście w tryb "jałowy" - czas leci nadal, ale żaden ze słuchaczy się nie wykona.

Taka mała dygresja: standardowo addListener i removeListener odnoszą się do obiektów nasłuchujących i tam są wywoływane odpowiednie metody obsługi zdarzeń - w tym przypadku stwierdziłem, że wygodniejsze jest dla mnie zastosowanie Delegate.create i poruszanie się wewnątrz jednej "przestrzeni".

Aż prosi się, by do tej klasy dopisać metodę pause() zamiast używania enabled - no i wypadało by jeszcze napisać metodę usuwającą nasz TIMER po zakończeniu działania...

Komentarze (1)
1 | 2 |

Najnowsze komentarze
2014-01-06 19:33
najlepszeprezenty.com.pl:
Flash After Party czyli o flashu w realu [EDIT]
pozdrowienia :)
2013-12-25 22:07
Powiększanie penisa:
Warto blogować ?
Trudno się z tym nie zgodzić, przez to, że są bardzo ogólne to także są bardzo trafne.
2013-12-08 22:47
ets2:
Warto blogować ?
Wartościowych blogów jest na naprawdę mało, sam staram się coś stworzyć a czy wyjdzie to się[...]
O mnie
MaW: flash, gry i cała reszta
Po prostu flashmaniak.