SDL-tutoriaali 2
Tässä toisessa osassa Mikko Nuotion SDL-tutoriaalisarjaa tutustutaan piirtofunktioihin ja näppäinkomentojen lukemiseen SDL:llä. Lisäksi asennetaan SDL_image-kirjasto, joka mahdollistaa .png-formaatin hyödyntämisen. Tämä on siis varsin hyödyllistä lukemista, jos SDL kiinnostaa.
29.9.2002 julkaistun artikkelin on kirjoittanut nuotimi1.
Aikaa pääsi edellisestä osasta vierähtämään, ja SDL-kirjastoista on ilmestynyt uusi versio (1.2.4), mutta kaiken pitäsisi toimia vanhemmallakin versiolla.
Edellisessä osassa emme juurikaan perehtyneet itse SDL-ohjelmointiin vaan lähinnä kirjastojen asentamiseen. Tässä osassa perehdytään piirtofunktioihin ja näppäinkomentojen lukemiseen. Käytämme myös lisäkirjastoa nimeltä SDL_image, joka mahdollistaa .PNG -formaatin hyödyntämisen esimerkissä.
Tarvitsemme SDL_image -kirjaston, joka löytyy osoitteesta: http://www.libsdl.org/projects/SDL_image...
Windowsille:
Binääri: SDL_image-1.2.2-win32.zip, joka puretaan esim. windowsin system (NT/2000/XP system32) -hakemistoon.
Develop: SDL_image-devel-1.2.2-VC6.zip, joka puretaan esim. c:\SDL-1.2.4\SDL_image -hakemistoon.
Linuxille (mandrake):
Binääri: SDL_image-1.2.2-1.i686.rpm
Develop: SDL_image-devel-1.2.2-1.i686.rpm
Paketit asennetaan linuxissa komenolla: rpm -ivh SDL_image-1.2.2-1.i686.rpm SDL_image-devel-1.2.2-1.i686.rpm
Windowsissa luodaan projekti samalla tavalla kuin tutoriaali ykkösessä, mutta lisäämme SDL_image -kirjaston konffeihin:
Valitse Tools/Options/Directories ja pudotusvalikosta include files ja lisää siihen hakemisto, jossa SDL_image:n header-tiedostot sijaitsevat (C:\SDL-1.2.4\SDL_image\include). Seuraavaksi valitse library files ja lisää hakemisto, jossa SDL-kirjastot ovat (C:\SDL-1.2.4\SDL_image\lib).
Linux:ssa nämä konffaukset tehdään makefile:een.
Tässä kohtaa pitäisi tehdä perusteelliset suunnitelmat mitä koodataan ja miten. Joku sanoo että suunnitelmat kirjoitetaan paperille ja että vain etukäteen tarkkaan suunniteltu koodi toimii.
Henkilökohtaisesti en ole koskaan tehnyt ainuttakaan suunnitelmaa paperille (kerran yritin hahmotella sql-skemaa paperille, mutta sain aikaiseksi vain ison kasan ruttuisia papereita). Eli jos ideat ja ratkaisut on päässä ei niitä kannata siirtää paperille. No juu.. kukin tehkööt miten parhaaksi näkee.
Asiaan.
Idea on piirtää ruudulle kuva ja liikutella sitä nuolinäppäimillä.
Aluksi tarvitaan headerit.
#include <stdio.h> #include <SDL.h> #include <SDL_image.h>
Luodaan muutama surface (näyttö ja bittikartta) ja alustetaan SDL_event, että voidaan lukea näppistä jne.
SDL_Surface *screen_surf, *pix_surf; SDL_Event event;
Funktio jolla ladataan kuva.
SDL_Surface *load_png(char *name)
{
SDL_Surface *pix;
//Ladataa kuva
pix = IMG_Load(name);
if ( pix == NULL ) {
fprintf(stderr,
"Kuvan lataaminen ei onnistu %s: %s\n",
"", name, SDL_GetError());
return(0);
}
return(pix);
}
Funktio kuvan piirtämiseksi screen surfaceen. Ensin luodaan kaksi maskia (rect), jotka määrittelevät alueita kuvasta. src= mistä siirretään dst= mihin siirrettän. Eli käytännössä leikkaamme kuvasta palan ja siirrämme sen toiseen surfaceen.
[DEFTABLE]
[D]x, y[/D]
[E]Kuvan x- ja y-koordinaatit ruudulla[/E]
[D]w, h[/D]
[E]Maskin koko ruudulla.[/E]
[D]x2, y2[/D]
[E]Kuvan x- ja y-koordinaatit kuvassa (pix_surf)[/E]
[D]w2, h2[/D]
[E]Maskin koko kuvassa (pix_surf)[/E]
[/DEFTABLE]
void drawSprite(SDL_Surface *screen,SDL_Surface *pix_surf,
int x, int y,int w,int h,int x2,int y2, int w2,int h2)
{
unsigned int rval;
SDL_Rect dst, src;
dst.x = x;
dst.y = y;
dst.w=w;
dst.h=h;
src.x = x2;
src.y = y2;
src.w=w2;
src.h=h2;
rval = SDL_BlitSurface(pix_surf, &src, screen, &dst);
}
Ohjelman pääfunktio.
int main(int argc, char *argv[])
{
Alustetaan SDL ja muutama apumuuttuja sekä annetaan ikkunalle nimi
SDL_Init(SDL_INIT_VIDEO);
int screen_width=640;
int screen_height=480;
Uint8 *keys;
int exit=0;
int x=0;
int y=0;
SDL_WM_SetCaption("SDL Tutorial 2",NULL);
Alustetaan näyttötila. SDL_HWSURFACE = hyödynnetään graffakortin tarjoamia 2D (ei 3D) kiihdytysominaisuuksia, SDL_DOUBLEBUF = kaksoispuskurointi
screen = SDL_SetVideoMode(screen_width, screen_height,
16,SDL_HWSURFACE | SDL_DOUBLEBUF);
Ladataan esim.png
pix_surf=load_png("esim.png");
Luodaan looppi, jossa luetaan eventtejä (esim näippäimen panalluksia, hiiren liikkeitä jne.), luetaan näppäimet ja maalataan ruutu mustaksi ja piirretään kuva kohtaan x,y ja flipataan koko hökötys ruudulle
while(!exit) //jatketaan kunnes exit=1
{
while ( SDL_PollEvent(&event) )
{
switch (event.type)
{
case SDL_QUIT: //jos painetaan X :ää ikkunan nurkassa
exit = 1;
break;
case SDL_KEYDOWN:
{
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE: //loopin lopetus
exit = 1;
break;
}
}
}
}
// luetaan näppäimet SDL_GetKeyState-
// funktiolla, nopeampaa kuin eventeillä
keys = SDL_GetKeyState(NULL);
if (keys[SDLK_DOWN]){if (y<(screen_height-32)){y++;} }
if (keys[SDLK_UP]){if (y>0){y--;}}
if (keys[SDLK_RIGHT]){if (x<(screen_width-32)){x++;}}
if (keys[SDLK_LEFT]){if (x>0){x--;}}
//Maalataan koko ruutu mustaksi
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0,0,0));
//piirrerään kuva ruudulle
drawSprite(screen,pix_surf, x,y,32,32,0,0,32,32);
SDL_Flip(screen); //Flipataan ruudulle (kaksoispuskuri)
}
//tyhjennetään surfacet ja lopetetaan main- funktio
SDL_FreeSurface(screen);
SDL_FreeSurface(pix_surf);
SDL_Quit();
return 0;
}
Tässä osassa emme siis vielä tehneet varsinaista sprite-engineä emmekä käsitelleet ääniä, mutta kenties seuraavassa osassa.. joskus.. ehkä. Kannattaa myös tutustua eestiläisen Marius Andran eriomaisiin SDL-tutoriaaleihin (siis englanniksi, http://cone3d.gamedev.net/cgi-bin/index.... ).
