Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: SDL Näppäinkoodit

Sivun loppuun

crafn [01.08.2005 12:02:00]

#

Elikkäs... Minä alottelin tota SDL:lää muutama päivä sitten
niin nyt on tullut semmonen ongelma että en tiiä näppäin koodeja (siis muita kuin [SDLK_ESCAPE] ja sitten nuolinäppäimet):D Yritin mennä sinne sivuille mikä oli tossa SDL oppaassa (täällä putkassa) niin se ei löydä sitä sivua mikä on sinne oppaaseen laitettu. Niin voisko joku laittaa niitä näppäin koodeja tähän? :)

Gaxx [01.08.2005 12:23:03]

#

Näppäinkoodi löytyvät myös SDL_keysym.h:sta. Ja tosiaan SDL:n documentaatiot ovat käsittääkseni siirtyneet tänne ja näppäinkoodit löytyvät siististi täältä.

crafn [01.08.2005 12:26:20]

#

Kiitti :D

Heikki [01.08.2005 12:34:18]

#

Tosiaan ovat poistaneet vanhan dokumentaation käyöstä tuolla libsdl.origssa ja siirtyneet wikiin, pitääkin päivittää oppaiden linkit...

crafn [01.08.2005 12:37:09]

#

Jep:P

crafn [02.08.2005 15:55:42]

#

Tänään tuli toinen ongelma... :D
Se ongelma on sellanen että peli alkaa nykimään kyn sitä on vähän aikaa pelannut.
Mistä vois johtua?

Zach [02.08.2005 18:03:41]

#

Pelissäsi voi olla muistivuotoja, eli varattua muistia ei vapauteta, kun sitä ei enää tarvita. Tarkista, että esim. SDL_surface:t tyhjennetään SDL_FreeSurface():lla. Jos kertoisit hieman pelistäsi tai vaikka näyttäisit koodia, ongelma voisi olla vähän lähempänä ratkaisua.

crafn [02.08.2005 18:07:42]

#

Tässä on:

 #include <SDL/SDL.h>


#pragma comment(lib, "SDLmain.lib")
#pragma comment(lib, "SDL.lib")

void PiirraKuva(SDL_Surface *kuva, SDL_Surface *naytto, int kuvax, int kuvay, int leveys, int korkeus, int nayttox, int nayttoy)
{
    SDL_Rect kuvaalue;
    kuvaalue.x = kuvax;
    kuvaalue.y = kuvay;
    kuvaalue.h = korkeus;
    kuvaalue.w = leveys;

    SDL_Rect nayttoalue;
    nayttoalue.x = nayttox;
    nayttoalue.y = nayttoy;
    SDL_SetColorKey(kuva, SDL_SRCCOLORKEY, SDL_MapRGB(kuva->format,0,255,0));
    SDL_BlitSurface(kuva, &kuvaalue, naytto, &nayttoalue);
}
int main(int argc, char *argv[]) {

    if( SDL_Init(SDL_INIT_VIDEO) < 0 )
    {
        fprintf(stderr, "SDL:n alustus ei onnistunut: %s\n", SDL_GetError());
        return 0;
    }
    SDL_WM_SetCaption("UFO",NULL);

    SDL_Surface * naytto;
    SDL_Surface * kuva;
    SDL_Surface * tausta;

    naytto = SDL_SetVideoMode(500, 400, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
    float x = 140, y = 180;
    int tx = 0;

    while (1)
    {

    SDL_Event tapahtuma;
    SDL_PollEvent(&tapahtuma);

    Uint8* nappain;
    nappain=SDL_GetKeyState(NULL);

    tx -= 1;

    if (tx + 500 <= 0) tx = 500;


    tausta=SDL_LoadBMP("Taivas.bmp");
    PiirraKuva(tausta, naytto, 0, 0, 500, 400, 0, 0);

    if (nappain[SDLK_RIGHT])x += 1;
    if (nappain[SDLK_LEFT])x -= 2;
    if (nappain[SDLK_UP])y -= 2;
    if (nappain[SDLK_DOWN])y += 2;

    if (nappain[SDLK_ESCAPE]) break;

    y += 0.5;

    kuva=SDL_LoadBMP("UFO.bmp");
    PiirraKuva(kuva, naytto, 0, 0, 40, 20, x, y);

    tausta=SDL_LoadBMP("Pilvi.bmp");
    PiirraKuva(tausta, naytto, 0, 0, 500, 400, tx, 0);

    SDL_Flip(naytto);
    SDL_Delay(1);
    }
    SDL_Quit();
    return 0;
}

Zach [02.08.2005 19:10:16]

#

Pienillä muutoksilla saat paljon aikaan. Tuossa koodissasi kolme kuvatiedostoa ladataan while(1) -silmukan jokaisella kierroksella, ja tiedostosta kokoaikainen lukeminen on todella hidasta. Tee sen sijaan kolmas SDL_Surface - vaikka "pilvi" - ja lataa kaikki kuvat valmiiksi ennen pääsilmukkaa. Kuvan hakeminen keskusmuistista on paljon nopeampaa kuin tiedostosta...

crafn [02.08.2005 19:15:16]

#

Jep, kiitos :D

crafn [03.08.2005 16:49:49]

#

No...Miten tuota musiikkia saa tuohon peliin:D(ei mitään hajua)

Zach [03.08.2005 18:40:21]

#

Heikin SDL-oppaassa on hyvät ohjeet SDL_mixer -kirjaston peruskäytöstä. Sillä saat aaltoäänitiedostoja soitettua; jos kuitenkin haluat toistaa esim. mpkolmosia, kokeile vaikka SDL-sound:ia.

hohoo [03.08.2005 20:28:10]

#

Zach kirjoitti:

Heikin SDL-oppaassa on hyvät ohjeet SDL_mixer -kirjaston peruskäytöstä. Sillä saat aaltoäänitiedostoja soitettua; jos kuitenkin haluat toistaa esim. mpkolmosia, kokeile vaikka SDL-sound:ia.

Eikö pelkällä SDL:llä pysty soittamaan musiikkia? SDL_mixer.dll on "kauhean" iso (1,68 MB), sdl.dll on 224 kB.

crafn [03.08.2005 20:32:56]

#

Njoo... Täytyy kattoo...
Kiitti :D

Heikki [04.08.2005 12:36:24]

#

hohoo kirjoitti:

Eikö pelkällä SDL:llä pysty soittamaan musiikkia? SDL_mixer.dll on "kauhean" iso (1,68 MB), sdl.dll on 224 kB.

SDL:ssä on tosiaan itsessäänkin ääniin liittyviä toimintoja (voi katsoa dokumentaatiosta[, kohta 16. Audio), mutta itse olen niitä tutkiessani tullut sellaiseen tulokseen että mieluummin käytän erillistä lisäkirjastoa.

Ja SDL_mixer hallitsee muutkin kuin WAV-tiedostot, lainaus oppaasta:

opas kirjoitti:

Tuo koodi lataa aani-nimiseen tietueeseen polku\musiikkifiluun.wav-nimisen äänitiedoston. Tiedosto voi olla jossakin seuraavista muodoista: WAV, AIFF, RIFF, OGG ja VOC.

MP3-tiedostotkin toistuvat SDL_Mixerillä käytettäessä sen MIX_Musicia (dokumentaatio. Tällöin voi käyttää seuraavia tiedostomuotoja: WAVE, MOD, MIDI, OGG ja MP3.

crafn [07.08.2005 18:49:10]

#

Kiitos :)

crafn [12.08.2005 10:47:58]

#

Noniin...
Uusia ongelmia tulee koko ajan vastaan...
Tässä olisi yksi...

#include <SDL/SDL.h>

#pragma comment(lib, "SDLmain.lib")
#pragma comment(lib, "SDL.lib")

void PiirraKuva(SDL_Surface *kuva, SDL_Surface *naytto, int kuvax, int kuvay, int leveys, int korkeus, int nayttox, int nayttoy)
{
    SDL_Rect kuvaalue;
    kuvaalue.x = kuvax;
    kuvaalue.y = kuvay;
    kuvaalue.h = korkeus;
    kuvaalue.w = leveys;

    SDL_Rect nayttoalue;
    nayttoalue.x = nayttox;
    nayttoalue.y = nayttoy;

    SDL_SetColorKey(kuva, SDL_SRCCOLORKEY, SDL_MapRGB(kuva->format,0,255,0));
    SDL_BlitSurface(kuva, &kuvaalue, naytto, &nayttoalue);
}

int main(int argc, char *argv[]) {

    if( SDL_Init(SDL_INIT_VIDEO) < 0 )
    {
        fprintf(stderr, "SDL:n alustus ei onnistunut: %s\n", SDL_GetError());
        return 0;
    }
    SDL_WM_SetCaption("Peli",NULL);

    SDL_Surface * naytto;
    SDL_Surface * omppu;
    SDL_Surface * tausta;
    SDL_Surface * hiiri;

    naytto = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE|SDL_FULLSCREEN|SDL_DOUBLEBUF);

    omppu=SDL_LoadBMP("Omppu.bmp");
    tausta=SDL_LoadBMP("Tausta2.bmp");
    hiiri=SDL_LoadBMP("Hiiri.bmp");

    int mouse, mx, my;

    while(1)
    {
        SDL_Event event;
        SDL_PollEvent (&event);

        Uint8* keyboard;
        keyboard=SDL_GetKeyState(NULL);

        PiirraKuva(tausta, naytto, 0, 0, 800, 600, 0, 0);

        mouse=SDL_GetMouseState(&mx, &my);
        PiirraKuva(hiiri, naytto, 0, 0, 30, 30, mx, my);

        if(mouse & SDL_BUTTON(1))
        {
                 PiirraKuva(omppu, naytto, 0, 0, 30, 30, mx, my);
        }
        if(keyboard[SDLK_ESCAPE])break;

        SDL_Flip(naytto);
        SDL_Delay(1);
    }
    SDL_Quit();
    return 0;
}

Eli miten olisi mahdollista saada se "omppu" jäämään siihen mihin sen on napsauttanut ja saada uusi omppu jäämään taas seuraavaan paikkaan. Ilman taustaahan se onnistuisi mutta meinaan että se tekisi aina uuden ompun tai jotain... :D

Esimerkki olis hyvä :)

Heikki [12.08.2005 12:21:41]

#

En nyt jaksa alkaa koulussa esimerkkiä vääntämään joten annan vain ohjeita miten se onnistuu.

Tapoja on useita. Ehkä helpoin tapa on tehdä taulukko, johon tallennat omppujen koordinaatit ja sitten käyt tämän läpi silmukassa ja piirrät omput. Pätkä koodia päästä:

struct SPaikka {     // Tietotyyppi koordinaateille
int x, y;
}


SPaikka Ompot[OMPPOJEN_LKM];


Ompot[0].x=3; Ompot[0].y=3;
Ompot[1].x=300; Ompot[1].y=200;


// Piirrettäessä sitten näin
for (int i=0; i<OMPPOJEN_LKM; i++) {
 PiirraKuva(omppu, naytto, 0, 0, 30, 30, Ompot[i].x, Ompot[i].y);
}

Sitten klikattaessa laitat ompon tiedot taulukkoon.

Tässä on toki muutamia ongelmia, esimerkiksi se että taulukon kaikki ompot piiretään (ja muuttuja voi sisältää vaikka millaisen arvon). Parempi olisikin oikeastaan käyttää vektoria johon tallennat tiedot, pistän vielä vähän esimerkkiä vektoreista jos ei ole tuttua:

#include <vector>
using namespace std;

vector<int> luvut;
luvut.push_back(3);
luvut.push_back(99);

for (int i=0; i<luvut.size(); i++) {
 cout << luvut[i] << "\n";
}
// Tulostaa 3 [rivinvaihto] 99

Ja vektorin tietotyyppi voi sitten olla tuo koordinaatti. Tai sitten vaikka voit tehdä Omppo-luokan jossa on piirtometodi ja koordinaattitiedot ja tallentaa oliot vektoriin.


Koita saada jotain selvää, ja typojakin voi olla, en testaillut mitään.

Tomppu [12.08.2005 12:46:38]

#

En jaksanu lukea, mitä noi sanoo, joten jos tää tulee uudestaan, nii sori.

SDLK_a
SDLK_b
SDLK_c
SDLK_d
SDLK_e
SDLK_f
.
.
.

Noi pitäis toimia. Huom. kirjaimet on pienellä!

crafn [12.08.2005 13:19:24]

#

Sanoo tämmöstä tosta ekasta neuvosta:
Building Makefile: "D:\Documents and Settings\Tuukka\Työpöytä\omat\Makefile.win"
Executing make...
make.exe -f "D:\Documents and Settings\Tuukka\Työpöytä\omat\Makefile.win" all
g++.exe -c main.cpp -o main.o -I"lib/gcc/mingw32/3.4.2/include" -I"include/c++/3.4.2/backward" -I"include/c++/3.4.2/mingw32" -I"include/c++/3.4.2" -I"include" -I"C:\dev\dev-cop\\include\SDL" -Dmain=SDL_main

main.cpp: In function `int SDL_main(int, char**)':
main.cpp:61: error: `SPaikka' does not name a type
main.cpp:64: error: `Ompot' undeclared (first use this function)
main.cpp:64: error: (Each undeclared identifier is reported only once for each function it appears in.)
main.cpp:68: error: `OMPPOJEN_LKM' undeclared (first use this function)

make.exe: *** [main.o] Error 1

Execution terminated

Mikä on vikana? (En tota Tompun selitystä oikee tajunnu) :D

Heikki [12.08.2005 14:32:51]

#

Antamani koodi ei tietenkään ole tarkoitettu copypastettavaksi vaan sijoiteltavaksi sopivaan paikkaan.

Ensinnäkin tuli pieni typo, structin määrittelyn loppuun tulee }:n jälkeen puolipiste, eli

struct SPaikka {
  int x,y;
};

Tuo structi voisi olla kaikkien funktioiden ulkopuolella ja vaikka myöskin tuo Ompot-taulukonkin määrittely (vaikka globaalit muuttujat/taulukot ovatkin pahoja).

Ja tuo OMPPOJEN_LKM heittää tietenkin virheen sillä olin tarkoittanut sen vaikkapa vakioksi (#define OMPPOJEN_LKM 4), mutta suosittelen tuota vektorisysteemiä.

crafn [15.08.2005 12:20:42]

#

Kiitti... Tästä on kyllä puhuttu, mutta kysyn silti :D
Siis se pikselin piirto ja sitten sen värin tarkistus... :)
Miten se homma hoituu? :D

TeeVee [15.08.2005 15:36:30]

#

Tutustu SDL:n wikistä putpixeliin ja getpixeliin. Siellä on valmiit funktiot.

crafn [15.08.2005 16:18:11]

#

OK :) Kiitti...

crafn [20.08.2005 17:51:07]

#

Nyt on ongelma... :D

#include <SDL/SDL.h>

#pragma comment(lib, "SDLmain.lib")
#pragma comment(lib, "SDL.lib")

void DrawPixel(SDL_Surface *Surface, int x, int y,Uint8 R, Uint8 G,Uint8 B)
{

        Uint32 color = SDL_MapRGB(Surface->format, R, G, B);
        Uint8 *  bufp= (Uint8 *)Surface->pixels + y*Surface->pitch + x*Surface->format->BytesPerPixel;
        switch (Surface->format->BytesPerPixel) {
                case 4:
                        bufp[3] = color >> 24;
                case 3:
                        bufp[2] = color >> 16;
                case 2:
                        bufp[1] = color >> 8;
                case 1:
                        bufp[0] = color;
        }
        return;
}

struct Piste{
int x, y;
};
#define PISTE_LKM 1

Piste P[PISTE_LKM];

int main(int argc, char *argv[]) {

    if( SDL_Init(SDL_INIT_VIDEO) < 0 )
    {
        fprintf(stderr, "SDL:n alustus ei onnistunut: %s\n", SDL_GetError());
        return 0;
    }
    SDL_WM_SetCaption("",NULL);

    SDL_Surface * naytto;
    SDL_Surface * kuva;

    naytto = SDL_SetVideoMode(100, 100, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);

    int mouse, mx, my;
    int x, y;

    for(int i=0; i <= 100; i++)
    {
    for(int i2=0; i2<= 100; i2++)
    {
    P[i].x = 0;
    P[i2].y = 0;
    }
    }
    while(1)
    {
        SDL_Event event;
        SDL_PollEvent (&event);

        Uint8* keyboard;
        keyboard=SDL_GetKeyState(NULL);

        mouse=SDL_GetMouseState(&mx, &my);

        Uint32 color;

        color = SDL_MapRGB (naytto->format, 0, 0, 0);
        SDL_FillRect (naytto, NULL, color);

        if(mouse & SDL_BUTTON(1))
        {
                 for(int i=0; i<=100; i++)
                 {
                 for(int i2=0; i2<=100; i2++)
                 {
                         if(mx == i && my == i2)
                         {
                               P[i].x = 1;
                               P[i2].y = 1;
                         }

                 }
                 }
        }
        for(int i=0; i<=100; i++)
        {
        for(int i2=0; i2<=100; i2++)
        {
                if(P[i].x == 1 && P[i2].y == 1)
                {
                     DrawPixel(naytto, i, i2, 255, 255, 255);
                }
        }
        }
        if(keyboard[SDLK_ESCAPE]) break;

        SDL_Flip(naytto);
        SDL_Delay(10);
    }
    SDL_Quit();
    return 0;
}

Mitä pitäisi tehdä että saisin piirrettyä PELKÄSTÄÄN yhden pikselin while silmukan jokaisella kierroksella. Mitä pitäisi muuttaa, että ei tulisi noita viivoja joka paikkaan :D

rndprogy [20.08.2005 18:59:25]

#

Laita se SDL_Flip heti sen pikselinpiirtofunktion perään.

crafn [20.08.2005 20:43:07]

#

Meinasin että pikseli piirretään hiiren kohdalle :D

rndprogy [20.08.2005 20:44:36]

#

No katopa vaikka noista uusimmista koodivinkeistä kohta 2


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta