Tečaj
:: Predavatelj: Žiga Hajduković. e-mail. .
:: Organizator: Dane Šoba. e-mail. Študentska organizacija FRI (ŠOFRI).
:: Domača stran tečaja: www.tetris1d.org/game/dev/tecaj/.
:: game/dev.si forum: www.tetris1d.org/game/dev/forum_si/.
:: Študentski info sistem FRI: http://www.student-info.net/fri/.
Čestitam vsem sodelujočim v velikem nagradnem tekmovanju za najboljšo mobilno igro, ki jo je sponzoriralo priznano podjetje Cocoasoft!
V zelo kratkem času vam je uspelo prekositi same sebe in ustvariti igre, ki so presegle vsa pričakovanja!
Objavili smo galerijo vseh sodelujočih iger, kjer si lahko ogledate posnetke akcije iz samih iger, pa tudi fotografije iz podelitve bogatih nagrad!
Ne pozabite na gd.si forum, kjer si bomo še naprej izmenjevali mnenja in pomagali drug drugemu na poti k izdelovanju najboljših mobilnih iger!
Lekcija 05 |
lekcija 04 :: domov :: lekcija 06 |
Epsilon 04 eclipse workspace project (sfx)
Odpri povezavo:
http://www.tetris1d.org/gdwap/na svojem mobilnem telefonu in si naloži Epsilon_04.
GameCanvas.java (izvorna datoteka)
GameSprite.java (izvorna datoteka)
Datoteka stage1.txt:
public static final byte SPRITE_ID_PLAYER = 0; // 'P'
public static final byte SPRITE_ID_ENEMY1_SHOOTING = 1; // 'A'
public static final byte SPRITE_ID_ENEMY1 = 2; // 'a'
public static final byte SPRITE_ID_ENEMY2_SHOOTING = 3; // 'V'
public static final byte SPRITE_ID_ENEMY2 = 4; // 'v'
public static final byte SPRITE_ID_ENEMY3 = 5; // 'O'
public static final byte SPRITE_ID_ENEMY3_SINUS = 6; // 's'
public static final byte SPRITE_ID_ENEMY3_SINUS_SHOOTING = 7; // 'S'
public static final byte SPRITE_ID_ENEMY4_SHOOTING = 8; // 'T'
public static final byte SPRITE_ID_BOSS1 = 9; // 'B'
public static final byte SPRITE_ID_BOSS2 = 10; // 'C'
OOOOOOOOOOOOOOOO; ;
OOvvvvvvvvvvvvOO; ;
O/ \O; ;
> <; B ;
> <; ;
> <; ;
> <; ;
> <; ;
OL JO; ;
OGL JGO; ;
OOGL JGOO; V V ;
\OOGL JGOO/; ;
\OG/ \GO/ ; ;
\/ \/ ; ;
; ;
JL ; A A ;
JOOL ; ;
L <OOG ; O O O ;
> <GG> J; ;
/ <OO> <; ;
GOO> \; ;
\GG/ ; V V ;
\/ ; ;
J; ;
J^^L JO; ;
JOvvOL \O; ;
JG/ O> \; A A ;
<> J>/ J; A A ;
J/ <G JO; ;
J> JO/ JOG; ;
J/ JO/ JOGO; ;
GO^^^/ OOOG; ;
GOGG/ OOGO; ;
OGOO OGOO; O O ;
vvvv Ovvv; ;
; ;
JL JL ; V V ;
JOOL JOOL ; ;
JOOGO OGOOL; ;
OOGO> <OGOO; O O ;
\GOGO OGOG/; ;
OOO> <OOO ; O O ;
vvvv vvvv ; ;
OOOO OOOO ; O O ;
\vv/ \vv/ ; ;
; O O ;
L J; ;
> <O; ;
/ \; ;
; a a ;
JL ; ;
JOOL ; ;
L <OOG ; v v ;
> <GG> J; v v ;
/ <OO> <; v v ;
GOO> \; ;
\GG/ ; ;
\/ ; ;
J; ;
J^^L JO; ;
JOOOOL \O; ;
JOOGOO> \; ;
<OOOGO/ J; P ;
JOOOOG JO; ;
Datoteka stage2.txt:
J^L J^L ; ;
<G> <G> ; T T ;
\v/ \v/ ; C ;
; ;
J^L J^L ; ;
<G> <G> ; T T ;
\v/ \v/ ; ;
; s ;
; S S ;
J^L ; s ;
JOGOL ; S T S ;
^^OGOGO^^ ; T T ;
GO> <OG ; T T ;
\OO^^^OO/ ; ;
\vOGOv/ ; A T A ;
\v/ ; ;
; S S S ;
; ;
; ;
; ;
; v v ;
J^L J^L ; ;
^^OGO^^^^^OGO^^^; T T ;
vvvvvvOGOvvvvvvv; T ;
\v/ ; ;
; S S ;
; s s ;
J^L ; S ;
<G> ; T ;
\v/ J^L ; ;
<O> ; s ;
\v/ ; ;
; s s ;
J^L ; ;
<O> ; ;
\v/ J^L ; ;
<G> ; T ;
\v/ ; ;
; V V V V ;
; ;
JL ; ;
^^^^^^^GG^^^^^^^; TT ;
vvvGGvvvvvvGGvvv; TT TT ;
\/ \/ ; ;
; a a ;
; ;
; a a ;
; S S ;
; ;
^^^L J^^^; ;
OOG> <GOO; T T ;
vvv/ \vvv; ;
; s s ;
; ;
J^L ; ;
OGO ; T ;
\v/ ; ;
; ;
; ;
J^L ; ;
<O> ; ;
\v/ ; P ;
; ;
Pod pojmom optimizacija se običajno skriva izboljšanje hitrosti, kar bomo podrobneje pogledali tudi mi. Pri telefonih pa ta pojem pomeni tudi prilagajanje sposobnostim in lastnostim naprave (npr. drugačna razporeditev tipk, boljše sposobnosti predvajanja zvoka, velikost ekrana)
Pri hitrosti pa velja dobro znano prvo pravilo: 10% kode se izvaja 90% časa, zato je prava umetnost optimizacije poiskati tistih 10%, ne pa optimizirati ostalih 90% kode. Pogledali si bomo nekaj metod, ki pomagajo pri sami optimizaciji kode, ne bodo pa povzročile revolucionarnih sprememb, če je že sam algoritem v zasnovi počasen. Drugo pravilo optimizacije je, da najprej poskušaj na novo zasnovati algoritem, šele nato se loti podrobnejših optimizacij.
static String reverse(String s)
{
String t = "";
for (int i = s.length()-1; i >= 0; --i)
t += s.charAt(i);
return t;
}
Ker je String "immutable", koda znotraj zanke zgoraj vsakokrat kopira vrednost t, ki ji doda nov znak, in tako po nepotrebnem kreira s.length() objektov "za v smeti". Obstaja pa "mutable" različica String objekta, in sicer - StringBuffer:
static String reverse(String s)
{
StringBuffer t = new StringBuffer(s.length());
for (int i = s.length()-1; i >= 0; --i)
t.append(s.charAt(i));
return t.toString();
}
Seveda je vredno razmisliti o uporabi StringBuffer-ja v primeru, da se dogaja zanka po 100x na sekundo. Ne optimiziraj prekmalu in napačnih stvari!
for (int i = 0; i < vec.size(); i++)
{
Object obj = vec.elementAt(i); // Process the Object obj.
}
rajši:
int VecSize = vec.size();
for (int i = 0; i < VecSize; i++)
{
Object obj = v.elementAt(i); // Process the Object obj.
}
Bolj pomembna od optimizacije hitrosti je optimizacija porabe delovnega spomina, saj tu obstaja vprašanje delovanja. Npr. Nokia telefoni serije 40 imajo običajno 200kb delovnega pomnilnika v svojih "najcenejših" izvedbah Nekaj nasvetov:
Runtime runtime = Runtime.getRuntime(); long beforeMemory, afterMemory; System.gc(); beforeMemory = runtime.freeMemory(); Object newObject = new String(); afterMemory = runtime.freeMemory(); long size = beforeMemory - afterMemory;
Tudi velikost JAR paketa povzroči vprašanje o delovanju, saj imajo nekateri telefoni fiksne omejitve za velikost le tega. Npr. na Nokiah serije 40 ta omejitev znaša 64kb.
Obfuscator za začetek vsa imena spremenljivk, metod, class-ov skrajša na enočrkovne.
Običajno se sicer uporablja za onemogočanje razumevanja dekompajlirane kode, vendar pri majhnih MIDletih to ne pride toliko do izraza. Bolj je pomembno dejstvo, da obfuscator optimizira velikost kode. Ponavadi se obfusciranje pozna za do 10% velikosti JAR paketa.
V Eclipse-u naredimo obfusciran paket s pomočjo opcije "Create obfuscated package" v J2ME meniju. Večinoma so potrebne še dodatne nastavitve parametrov obfuskatorja (Window - Preferences - J2ME - Packaging), in sicer pri uporabi nokiaui in podobnih zunanjih api-jev je potrebno dodati parameter: "-libraryjars c:\..POT_DO_DATOTEKE..\nokiaui.zip".
Kot smo že omenili je pomembno najti tistih 10% kode, ki je najbolj "problematičnih". To si ponavadi zelo olajšamo z uporabo "Profiler" orodij. Ker nam tako orodje ni na voljo (je, za emulatorje, kar nam ne pomaga v realnosti).
Zato uporabimo funkcijo System.currentTimeMillis(); in merimo čas funkcij npr. takole:
long startTime = System.currentTimeMillis(); doSomething(); // the thing you want to time long timeTaken = System.currentTimeMillis() – startTime;
Bodi pozoren na to, da je test dovolj dolg, da preseže "resolucijo" procesorjeve ure, ki je tipično 10-16ms na telefonih.
Nekaj podatkov o uporabi HTTP in Socket povezav:
Zelo pomemben je za uporabnika že samo občutek hitrosti! To lahko dosežemo na več načinov, čeprav je v resnici naš midlet lahko (tudi zaradi tega) počasnejši:
Če se na ekranu dalj časa nič ne spremeni, bo uporabnik to opazil, in bo pomislil, da se je midlet ustavil/zablokiral Uporabi indikatorje, progress bare in podobno (kot v Web browser-jih pri nalaganju strani), da uporabnika prepričaš o živosti.
Koliko časa traja, da se kaj zgodi, ko uporabnik pritisne tipko.
1 sekunda je že več kot preveč, ponavadi pa uporabnik pričakuje da se midlet odziva podobno hitro, kot meniji in ostali programi v teleofonu.
Poskrbi, da bo imel vsak pritisk tipke vidne ali slišne rezultate. Ni dovolj, da se nekaj izvede zelo hitro, če uporabnik ni prepričan, da se je sploh izvedlo.
Pri nalaganju npr. s splash sliko uporabniku krajšamo čas.
Pri daljših čakanjih npr. na odziv HTTP strežnika rišemo kakšno krožno animacijo.
Visible property dodan v GameSprite class, za optimizacijo paint in update. Zaenkrat aktivirano za enemy sprite-e.
Dodan števec Frames Per Second, viden ob pritisku na tipko * (KEY_STAR).
Omogočene tipke 1, 3, 7 in 9 za diagonalno premikanje.
Dodan SHIFT_FACTOR in uporabljen na vseh pozicijah (x,y) in hitrostih (vx,vy) sprite-ov ter na tiles_scroll x,y ter vy.
Level.paint() uporabljeno "shift-anje" namesto množenja in deljenja (* in /).
Spremljanje porabe časa (profiling) določenih klicev večjih funkcij, ki se izvajajo v paint(). Za vklop prikaza časov pritisni tipko * (KEY_STAR).
Novi menu ekrani:
Novi tipi nasprotnikov:
Generator za sin[] array si lahko naložite tukaj: Java sin[] generator :: (c) zigah.2005
Dodan nuke efekt (tipka KEY_NUM0 med igro), ki uniči vse nasprotnike na ekranu. Igralec ima na voljo 3 nuke-e, količino preostalih pa mu kaže indikator spodaj desno, Ob sprožitvi se zgodi tudi eksploziven efekt z ozadjem (zasluge za idejo pripadajo organizator-ju Dane-tu : ) ).
Dodana glasba s pomočjo MMAPI-ja, za telefone, ki ga podpirajo.
Podporo igranju glasbe v ozadju sestavljajo tri nove funkcije: playMusic(), loadMusic() in stopMusic()
Dodan je klic na stopMusic() ob hideNotify()
Dodan je showNotify(), za ponovno sprožitev igranja glasbe.
Epsilon, dodatna grafika (by geci)
Grafika za igro Axion Space, Cocoasoft
| game/dev.si | :: predlogi ? pišite: Žiga Hajduković |