Ebben a példában egy olyan programot fogunk készíteni, ami egy labdát pattogtat a képernyőn.
Először is indítsuk el a meg4
programot, és hozzuk be a [Szprájt szerkesztő]t (üsd le az F3-at). Válasszuk ki az
első szprájtot szerkesztésre jobbra, és rajzoljuk meg a labdát a bal oldali szerkesztőben.
A labda megrajzolása
Most menjünk a [Kód szerkesztő]be (üsd le az F2-őt). Elsőre a programunk egy üres váz lesz.
#!c
void setup()
{
/* Induláskor lefuttatandó dolgok */
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
}
Jelenítsük meg az újonnan rajzolt szprájtunkat! Ezt az [spr] hívással tehetjük meg. Menjünk a setup()
függvény törzsébe,
kezdjük el beírni, és alul a státuszsorban megjelennek a paraméterei.
Láthatjuk, hogy az első két paraméter az x, y
, a képernyő koordináta, ahová ki akarjuk rakni a szprájtot (ha nem lenne
egyértelmű a paraméter nevéből, hogy mit takar, akkor az F1 leütésével bejön a súgó részletes leírással, majd ott
Esc-et ütve visszakerülsz ide a kódszerkesztésre). A képernyő 320 pixel széles és 200 pixel magas, ezért ha középre
akarjuk elhelyezni, adjunk meg a 160, 100
értékeket. A következő paraméter a sprite
. Mivel a legelső, nulladik szprájtra
rajzoltunk, ezért ez 0
. Az ezt követő paraméterek az sw
(szprájt szélesség) és sh
(szprájt magasság). Mivel a labdánk
csupán egyetlen szprájtba belefér, azért írjunk 1, 1
-et. Ezt követi a scale
(átméretezés), de nem szeretnénk felnagyítani,
így ide is írjunk csak 1
-et. Végül az utolsó paraméter a type
(megjelenés típusa), amivel transzformálhatjuk a szprájtot.
Mivel ezt sem szeretnénk, azért adjunk csak meg 0
-át.
#!c
void setup()
{
/* Induláskor lefuttatandó dolgok */
<hl>spr(160, 100, 0, 1, 1, 1, 0);</hl>
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
}
Próbáljuk meg lefuttatni ezt a programot a Ctrl+R leütésével, és lássuk mi történik. Ha valamilyen hibát vétettél a begépeléskor, akkor alul a státuszsorban egy hibaüzenet fog megjelenni, és a kurzor a hibát kiváltó részre fog ugrani.
Ha minden rendben volt, akkor a szerkesztőképernyő el fog tűnni, és helyette egy fekete képernyő, közepén a labdával fog megjelenni. Azonban a labdánk nem teljesen középre került, mivel elfelejtettük kivonni a szprájt méretének felét a koordinátákból (egy szprájtot jelenítünk meg itt (sw = 1 és sh = 1), szóval 8 x 8 pixelt, aminek a fele 4). Üssük le az F2-őt, hogy visszatérjünk a szerkesztőbe, és javítsuk ki.
#!c
void setup()
{
/* Induláskor lefuttatandó dolgok */
spr(<hl>156, 96</hl>, 0, 1, 1, 1, 0);
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
}
Futtassuk le újra! A labdánk megjelenik a jó helyen, de a korábbi helyén is ottmaradt! Ez azért van, mert nem töröltük le a képernyőt. Ezt a cls paranccsal tehetjük meg, ezért ezt írjuk be a szprájtmegjelenítés elé.
#!c
void setup()
{
/* Induláskor lefuttatandó dolgok */
<hl>cls(0);</hl>
spr(156, 96, 0, 1, 1, 1, 0);
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
}
Most már minden rendben, pontosan a képernyő közepén megjelenik a labda.
Van egy kis probléma a kódunkkal. A labdát a setup()
függvényben jelenítjük meg, de ez csak egyszer fut le, amikor a programunk
elindul. Ahhoz, hogy mozogni lássuk a labdát, újra és újra ki kell rajzolnunk, mindig más pozícióra. Hogy ezt elérjük, tegyük át a
labdánk megjelenítését a loop()
függvénybe. Ez minden egyes alkalommal lefut, amikor a képernyő frissül.
#!c
void setup()
{
/* Induláskor lefuttatandó dolgok */
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
<hm> cls(0);
spr(156, 96, 0, 1, 1, 1, 0);</hm>
}
Ha most leütjük a Ctrl+R-t, akkor a labda pontosan ugyanúgy fog megjelenni, mint eddig. Amit nem látunk, az az, hogy most nemcsak egyszer, hanem újra és újra kirajzolódik.
Mozgassuk meg a labdát! Most mindig ugyanott jelenik meg, mivel konstans koordinátákat használtunk. Javítsunk ezen úgy, hogy bevezetünk két változót, amik a labda épp aktuális pozícióját fogják tárolni a képernyőn.
#!c
<hl>int x, y;</hl>
void setup()
{
/* Induláskor lefuttatandó dolgok */
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
cls(0);
spr(156, 96, 0, 1, 1, 1, 0);
}
Cseréljük le a koordinátákat a kirajzolásnál ezekre a változókra, és adjunk nekik induló értéket a program indulásakor.
#!c
int x, y;
void setup()
{
/* Induláskor lefuttatandó dolgok */
<hm> x = 156;
y = 96;</hm>
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
cls(0);
spr(<hl>x, y</hl>, 0, 1, 1, 1, 0);
}
Ha most lefuttatjuk a programunkat, akkor még mindig nem fogunk semmi változást látni. Azonban annak köszönhetően, hogy most már változókat használunk, futás közben tudjuk változtatni a pozíciót.
#!c
int x, y;
void setup()
{
/* Induláskor lefuttatandó dolgok */
x = 156;
y = 96;
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
cls(0);
spr(x, y, 0, 1, 1, 1, 0);
<hm> x = x + 1;
y = y + 1;</hm>
}
Futtasuk le így, és látni fogjuk a labdát mozogni!
Még nem vagyunk készen, mert a labdánk nagyon gyorsan eltűnik a képernyőről. Ez azért van, mert folyton növeljük a koordinátáit, és nem fordítjuk meg az irányát, amikor a képernyő szélére ér.
Akárcsak a koordináták esetében először, most is konstanst használunk, és szeretnénk az irányt dinamikusan változtatni. A megoldás most is ugyanaz, lecseréljük a konstansokat két új változóra.
#!c
int x, y<hl>, dx, dy</hl>;
void setup()
{
/* Induláskor lefuttatandó dolgok */
x = 156;
y = 96;
<hl>dx = dy = 1;</hl>
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
cls(0);
spr(x, y, 0, 1, 1, 1, 0);
x = x + <hl>dx</hl>;
y = y + <hl>dy</hl>;
}
Nagyszerű! Mint korábban említettük, a képernyő 320 pixel széles, és 200 pixel magas. Ez azt jelenti, hogy a lehetséges x
értékek 0 és 319 között vannak, y
esetén pedig 0 és 199 között. Azonban nem akarjuk, hogy a labdánk eltűnjön a képernyőről, így
ebből ki kell vonni a szprájt méretét (8 x 8 pixel). Így végül azt kapjuk, hogy az x
0 és 311 közötti, az y
pedig 0 és 191
közötti. Amikor a labdánk pozíciója eléri ezeket az értékeket, akkor meg fell fordítanunk az irányát, hogy mindig a képernyőn
belül maradjon.
#!c
int x, y, dx, dy;
void setup()
{
/* Induláskor lefuttatandó dolgok */
x = 156;
y = 96;
dx = dy = 1;
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
cls(0);
spr(x, y, 0, 1, 1, 1, 0);
x = x + dx;
y = y + dy;
<hm> if(x == 0 || x == 311) dx = -dx;
if(y == 0 || y == 191) dy = -dy;</hm>
}
Futtasuk le ezt a prgoramot a Ctrl+R-el. Gratulálunk, van egy mozgó labdád, ami megpattan a képernyő szélein!
Az a játék, amit nem tudunk befolyásolni, nem túl izgalmas. Ezért hozzáadunk egy ütőt, amit a játékos irányíthat.
Menjünk a [Szprájt szerkesztő]be (üsd le az F3-at), és rajzoljuk meg az ütőt. Ez most három szprájt széles lesz. Megrajzolhatod egyenként, vagy akár kijelölhetsz több szprájtot is jobbra, és együtt szerkesztheted őket.
Az ütő megrajzolása
Hasonlóan a labdához, ezt is az [spr] paranccsal fogjuk megjeleníteni. Azt azonban már tudjuk, hogy szükségünk lesz egy változóra, ami a pozícióját tárolja, így adjuk hozzá egyből ezt is.
#!c
int x, y, dx, dy<hl>, px</hl>;
void setup()
{
/* Induláskor lefuttatandó dolgok */
x = 156;
y = 96;
dx = dy = 1;
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
cls(0);
spr(x, y, 0, 1, 1, 1, 0);
<hl>spr(px, 191, 1, 3, 1, 1, 0);</hl>
x = x + dx;
y = y + dy;
if(x == 0 || x == 311) dx = -dx;
if(y == 0 || y == 191) dy = -dy;
}
Az x
paraméter helyére kerül a px
változó, az y
koordináta konstans 191
, mivel függőlegesen nem fogjuk mozgatni az ütőt,
csak vízszintesen. Mivel az ütőt az egyes szprájtra rajzoltuk, ezért a sprite
paraméter most 1
, és mivel három szprájt széles,
ezért az sw
pedig 3
, de továbbra is csak egy szprájt magas, tehát az sh
az 1
.
Eddig jó, de hogy fogja tudni mozgatni a játékos az ütőt az egérrel? Hát úgy, hogy az egér koordinátáját adjuk a px
változónak.
Ha megnézed a memóriatérképet, akkor a [mutató] fejezetben azt látod, hogy az egér X koordintája 2 bájton, a 00016
-os címen
található. Hogy ezt lekérdezzük, az [inw] függvényt fogjuk használni (word, azaz szó, mivel két bájtra van szükségünk). De arra
is figyelnünk kell, hogy az ütő a képernyőn maradjon, ezért csak azokat a koordinátákat engedjük, amik kissebbek, mint a
képernyő szélessége mínusz az ütő szélessége (ami három szprájtnyi, tehát 24 pixeles). Még egy dolog, a memóriatérképen minden cím
tizenhatos számrendszerben van megadva, így a 0x
előtagot kell használnunk, hogy jelezzük a fordítóprogramnak, egy hexadecimális
szám következik.
#!c
int x, y, dx, dy, px;
void setup()
{
/* Induláskor lefuttatandó dolgok */
x = 156;
y = 96;
dx = dy = 1;
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
cls(0);
spr(x, y, 0, 1, 1, 1, 0);
<hm> px = inw(0x16);
if(px > 296) px = 296;</hm>
spr(px, 191, 1, 3, 1, 1, 0);
x = x + dx;
y = y + dy;
if(x == 0 || x == 311) dx = -dx;
if(y == 0 || y == 191) dy = -dy;
}
Futtassuk le a programot! Megjelenik az ütő, és mozgatni is tudjuk az egérrel. Azonban akad egy kis bökkenő, a labdát nem érdekli, hogy hol van az ütő. Írjuk át a programot, hogy a képernyő alja helyett csak akkor pattanjon a labda, ha épp az ütőre esik. A labda magassága 8 pixel, ezért ennyivel feljebb kell az ellenőrzést elvégezni.
#!c
int x, y, dx, dy, px;
void setup()
{
/* Induláskor lefuttatandó dolgok */
x = 156;
y = 96;
dx = dy = 1;
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
cls(0);
spr(x, y, 0, 1, 1, 1, 0);
px = inw(0x16);
if(px > 296) px = 296;
spr(px, 191, 1, 3, 1, 1, 0);
x = x + dx;
y = y + dy;
if(x == 0 || x == 311) dx = -dx;
if(y == 0 || <hl>(y == 183 && x >= px && x <= px + 24)</hl>) dy = -dy;
}
Ez azt jelenti, hogy az y
koordináta nulla, vagy 183
és ugyanakkor az x
pedig px
és px + 24
közötti (ahol a px
az ütő
pozíciója).
Most, hogy átírtuk az alsó pattanást, szükségünk van egy újabb ellenőrzésre, hogy a labda alul kiment-e a képernyőről. Ez ugye a játék végét fogja jelenteni.
Először is ne felejtsük el, hogy a loop()
továbbra is többször lefut, ezért hogy a labda ne mozogjon tovább, a dx
és dy
változókat nullára állítjuk. Másodszor, meg akarunk jeleníteni egy vége a játéknak üzenetet.
#!c
int x, y, dx, dy, px;
<hm>str_t msg = "VÉGE A JÁTÉKNAK!";</hm>
void setup()
{
/* Induláskor lefuttatandó dolgok */
x = 156;
y = 96;
dx = dy = 1;
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
cls(0);
spr(x, y, 0, 1, 1, 1, 0);
px = inw(0x16);
if(px > 296) px = 296;
spr(px, 191, 1, 3, 1, 1, 0);
x = x + dx;
y = y + dy;
if(x == 0 || x == 311) dx = -dx;
if(y == 0 || (y == 183 && x >= px && x <= px + 24)) dy = -dy;
<hm> if(y > 199) {
dx = dy = 0;
text(184, (320 - width(2, msg)) / 2, 90, 2, 112, 128, msg);
}</hm>
}
Szöveget a [text] funkcióval lehet kiírni a képernyőre. Alul a gyorssúgó mutatja, milyen paraméterei vannak. A legelső a palidx
,
ami egy paletta index, a szöveg színe. Üssük le az F3 gombot, és palettán kattintsunk a kívánt színre. Alul meg fog
jelenni a sorszáma tizenhatos számrendszerben, illetve zárójelben tízesben.
Én egy piros színt választottam, aminek a sorszáma B8
, azaz 184
tízes számrendszerben. Menjünk vissza a kódszerkesztőbe az
F2 leütésével, és írjuk be a szín sorszámát. A következő két paraméter az x
és az y
, a képernyő pozíció. Megtehettük
volna, hogy megszámoljuk, mennyi pixel a szöveg, de lusták vagyunk, ezért inkább a [width] funkcióval kiszámoltatjuk. Ezt kivonva
a képernyő szélességéből és elosztva kettővel pont középen fog megjelenni a szöveg. Mivel ahhoz is listák vagyunk, hogy kétszer
írjuk be a szöveget, ezért azt egy msg
nevű sztring változóba raktuk. Így msg
-ként hivatkozunk rá egyszer, amikor a méretét
lekérjük, és akkor is, amikor a kiírásnak megadjuk, mit kell kiírni. A koordináták után jön a type
, ami a betűtípus, illetve
pontosabban itt most a mérete. Mivel nagy betűkkel szeretnénk kiírni, ezért 2
lett megadva, dupla méret. Ezt követi az shidx
,
ami megint egy szín sorszám, az árnyék színe. Ide egy sötétebb pirosat választottam. Az árnyéknál fontos azonban az is, hogy
mennyire átlátszó, ezt az sha
paraméterben adhatjuk meg, ami egy alfa csatorna érték 0-tól (teljesen átlátszó) 255-ig
(semennyire sem). Ide a 128
-at választottam, ami félúton van a két érték között, tehát félig átlátszó. Végezetül pedig str
-ben
kell megadni, hogy melyik szöveget szeretnénk kiíratni, ezt ugye az msg
változóban tároljuk.
Végezetül pedig, ha a játékos kattint egyet, akkor újra akarjuk indítani a játékot.
#!c
int x, y, dx, dy, px;
str_t msg = "VÉGE A JÁTÉKNAK!";
void setup()
{
/* Induláskor lefuttatandó dolgok */
x = 156;
y = 96;
dx = dy = 1;
}
void loop()
{
/* Minden képkockánál lefuttatandó dolgok, 60 FPS */
cls(0);
spr(x, y, 0, 1, 1, 1, 0);
px = inw(0x16);
if(px > 296) px = 296;
spr(px, 191, 1, 3, 1, 1, 0);
x = x + dx;
y = y + dy;
if(x == 0 || x == 311) dx = -dx;
if(y == 0 || (y == 183 && x >= px && x <= px + 24)) dy = -dy;
if(y > 199) {
dx = dy = 0;
text(184, (320 - width(2, msg)) / 2, 90, 2, 112, 128, msg);
<hl>if(getclk(BTN_L)) setup();</hl>
}
}
Hogy megtudjuk, kattintott-e a felhasználó, arra a getclk funkciót használjuk, egy BTN_L
(button left) paraméterrel,
azaz kattintottak-e a bal egérgombbal. A pattogó labda játékunk alapértékeit a setup()
függvényben állítottuk be, ami nagyon
kapóra jön, mivel ha itt most újra meghívjuk a setup()
-ot, akkor a játék egyszerűen visszaáll az alaphelyzetébe.