Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Muutama kysymys

Sivun loppuun

mika132 [27.09.2009 21:29:56]

#

Käytän Visual C++. Windwos projektista on kyse. Olen pyrkinyt saamaan aikaiseksi pelienginen jossa voi yksinkertaisesti kirjoittaa tekstiä ja liikuttaa hahmoa. Onnistuin hahmon liikuttamisessa, mutta en tekstin kirjoittamisessa. Käytin niitä sdl_ttf kirjastoja, mutta ei auttanut se heitti aina kaiken maailman erroreita. Eli pyyntö olisi, että tekisikö joku minulle enginen jossa kirjoitetaan sdl_ttf:llä tekstiä? Nykyinen konsti tuntuu vaikealta. :O

Nykyinen:
Teen paintillä jokaisesta kirjaimesta ja numerosta kuvan jotka tallennan muuttujiin ja käytän miten haluan, mutta aloittelevan C++ koodaustaitoni takia koodi menee hieman mössöksi ja vaikea muutenkin toteuttaa, joten mieluusti haluaisin helpomman tavan.

Tazca [28.09.2009 15:34:17]

#

Valmista engineä täältä on turha hakea, voin kuitenkin ohjeistaa hieman.

SDL_ttf kirjastolla tekstin tuotto tapahtuu

TTF_RenderText_[Blended/Solid/jajoku](TTF_Font*, char[], SDL_Color)

funktiolla
Yksinkertaistettuna vaatii seuraavat toimenpiteet:

TTF_Font *font = NULL;
SDL_Color textcolor = {255, 255, 255}; // valkoinen teksti
SDL_Surface *teksti;
TTF_Init();
font = TTF_OpenFont("courbd.ttf", 12);     // fonttikoko 12, fontti courbd.ttf (eli courier).
teksti = TTF_RenderText_Blended(font, "hello world!", textcolor); // Renderöi teksti pinnalle.
// ja tähän sitten BlitSurfacella teksti -> screen.

Huomaa että melko karkea esimerkki, mutta nuo on ne pääaskeleet fontin saattamiseksi näytölle.

Myös error-viestien kertominen saattaisi auttaa, koska kristallipallo ollut huurussa viime aikoina.

mika132 [28.09.2009 16:01:00]

#

Oho. "Unhandled exception at 0x6f4c237b in bisnesmanager2.exe: 0xC0000005: Access violation reading location 0x00000000." :O

Tuo ei kerro minulle yhtään mitään.

Metabolix [28.09.2009 16:06:16]

#

Sen pitäisi kertoa sinulle, että käytät jossain tyhjää osoitinta.

mika132 [28.09.2009 16:25:52]

#

Mikseiköhän if lauseeni ei toimi?

if (valinta == 1)
{
    TTF_Font *loadFont(char *name, int size);
    TTF_Font *font = NULL;
    SDL_Color textcolor = {255, 0, 0};
    SDL_Surface *teksti;
    TTF_Init();
    font = TTF_OpenFont("courbd.ttf", 12);
    teksti = TTF_RenderText_Blended(font, "toimiiko!", textcolor);

    SDL_Rect alue;
    alue.x = 200;
    alue.y = 200;
    SDL_BlitSurface(teksti, NULL, naytto, &alue);

    SDL_Flip(naytto);
    SDL_Delay(5000);

    closeFont(game.font);

    TTF_Quit();
}

se ei tulosta mitään. Tein niin, että jos painaa talo_1.bmp kuvaa valinta muuttuu yhdeksi.

Toinen juttu on, kun ei googlella löytynyt miten kuvan saa piilotettua.

Metabolix [28.09.2009 16:51:50]

#

mika132 kirjoitti:

Toinen juttu on, kun ei googlella löytynyt miten kuvan saa piilotettua.

Piirtämällä siihen jotain muuta päälle. Mitään ei voi poistaa ruudulta, vaan aina piirretään lisää.

mika132 [28.09.2009 17:23:39]

#

Eikös se käy ihan perhanasti näytönohjaimen päälle? :O

Heikki [28.09.2009 17:27:25]

#

Ei, sillä näytönohjain ei pidä vanhoja kuvia (ruutuja) muistissa.

mika132 [28.09.2009 17:47:10]

#

Mutta niin takaisin tuohon suurempaan ongelmaan.
(Ongelma aiemmassa viestissä.)

Metabolix [04.10.2009 20:23:26]

#

Jos nyt alkajaisiksi tekisit tuosta koodista edes jollain mittapuulla järkevän. Miksi tuolla on ylimääräinen loadFont-funktion esittely? Mikä ihme on closeFont(game.font)? Eihän sinulla ole tuota funktiota eikä game.font-muuttujaa. Miksi TTF_Init ja TTF_Quit ovat tuolla muun koodin seassa eivätkä ohjelman alussa ja lopussa kuten SDL_Init ja SDL_Quit? Miksi kutsut SDL_Flip-funktiot tuossa, jos tarkoituksesi on piirtää ruudulle muutakin?

Onnistuuvatko fontin lataus ja tekstin luonti? Tarkista, että (font != 0) ja (teksti != 0).

mika132 [06.10.2009 22:46:30]

#

Nykyinen koodi:

SDL_Surface *teksti;
TTF_Font *font = NULL;
SDL_Color textcolor = {255, 0, 0}; // punainen teksti
font = TTF_OpenFont("courbd.ttf", 12);     // fonttikoko 12, fontti courbd.ttf (eli courier).
teksti = TTF_RenderText_Blended(font, "Toimiiko!", textcolor); // Renderöi teksti pinnalle.
// ja tähän sitten BlitSurfacella teksti -> screen.

    SDL_Rect alue_tekstille;
    alue_tekstille.x = 200;
    alue_tekstille.y = 200;
    SDL_BlitSurface(teksti, NULL, naytto, &alue_tekstille); // koska toinen parametri on NULL, piirretään koko kuva
	TTF_Init();

Ongelma on nyt sellainen, että ei tule edes sitä ' merkkiä. Ei tule mitään muuta kuin kuvat.

Metabolix [06.10.2009 22:47:23]

#

Oli varmaan järkevä ratkaisu siirtää kirjaston alustus (TTF_Init()) tuonne koodin loppuun, vai mitä? ^^ Vaikka juuri neuvoin toisin.

Mikset laittanut koodiin tarkistuksia, jotka edellisessä viestissäni mainitsin? On melko todennäköistä, että vika löytyy niillä.

vehkis91 [06.10.2009 23:00:57]

#

Miks ton pitäis tulostaa ' merkki?

Ja miks toi TTF_Init() on tolla alhaalla, eikös sitä kutsuta ohjelman aluss.


Edit: metabolix ehti eka.

mika132 [07.10.2009 19:26:03]

#

Nyt kirjoitus toimii, mutta mikä aiheuttaa sen, että jos liikkuva kuva menee tekstin yli se peittää sen? :O

Ja miten muuttujan tulostus?
"Toimiiko!" rahaa
yritin, mutta ei oikein onnistunut. :D

tgunner [07.10.2009 19:37:08]

#

Jos kuva seilaa toisen kuvan yli, on kuvien piirtojärjestyksessä vikaa. Piirrät ensin tekstin ja sitten kuvan, mikä ei aiheuta haluttua tulosta.

Muuttujan tulostus on vähän kinkkisempi, sillä joudut luomaan char-muuttujan, johon kirjoitat haluamasi muuttujan arvon. Esim.

char mjono[10];
int numero = 88;

sprintf(mjono, "%i", numero); /* nyt mjono saa arvon "88" */

Metabolix [07.10.2009 19:38:58]

#

Koeta ymmärtää, että SDL:ssä ei ole mitään liikkuvia kuvia ja paikallaan pysyviä tekstejä, vaan SDL:ssä ruutu on kuin piirustuspaperi, johon voi piirtää aina päälle uusia asioita. Jos siis tekstin piirtämisen jälkeen piirrät siihen päälle kuvan, et voi millään kaivaa tekstiä takaisin esiin, vaan voit vain piirtää koko tekstin vielä uudestaan siihen päälle.

Kirjoitin jo toisessa keskustelussa näin:

Metabolix kirjoitti:

Kokonaisluvun muuttaminen tekstiksi ja päinvastoin on hyvää harjoitusta, joten voisit tehdä itse funktiot.

int str_to_int(std::string teksti) {
  int luku = 0;
  // Mitä tänne?
  return luku;
}
std::string int_to_str(int luku) {
  std::string teksti;
  // Mitä tänne?
  return teksti;
}

Funktioista ei tule kovin pitkiä: molempiin riittää pari ehtoa ja yksi silmukka. Yhden numeromerkin saa luvuksi ja päinvastoin vähentämällä tai lisäämällä siihen merkin '0' lukuarvon.

// Merkin '0' ASCII-lukuarvo on 48, ja muut numerot seuraavat tätä.
// Siispä '7':n ASCII-lukuarvo on 55.
char c = '7';
int i = c - '0'; // '7' - '0' = 55 - 48 = 7.
char d = i + '0'; // 7 + '0' = 7 + 48 = 55 = '7'

Tarvitset siis perustiedot string-olioista. Tehtävän kannalta olennaiset asiat kerrotaan oppaassa.

mika132 [07.10.2009 20:22:37]

#

juu, mutta tuo on hieman väärä muuttujan tulostus. (selitin varmaan väärin)

teksti = TTF_RenderText_Blended(font, "Toimiiko!", textcolor);

Miten se muuttujan tulostus lisätään tuohon?

tneva82 [07.10.2009 20:46:17]

#

mika132 kirjoitti:

juu, mutta tuo on hieman väärä muuttujan tulostus. (selitin varmaan väärin)

teksti = TTF_RenderText_Blended(font, "Toimiiko!", textcolor);

Miten se muuttujan tulostus lisätään tuohon?

Uskoakseni jotakuinkin näin:

int c=50;
char mjono[10];
sprintf(mjono, "%i", c);
teksti = TTF_RenderText_Blended(font, mjono, textcolor);

En tosin tiedä mitä tuo rendertext funktio tekee mutta jos toinen parametri hyväksyy char taulukon niin noin sen pitäisi mennä.

mika132 [08.10.2009 17:50:37]

#

Kiitos. =)

Kun kuulin, että goto on huono koodaus vaihtoehto muutin sitä, mutta tuhoisin seurauksin. :O

Pistin "valinta" muuttujan. Eli tarkistetaan jos valinta muuttuja on jotain tiettyä niin mennään pisteeseen jotain.

Ongelma:
Painan oikeaan kohtaa ykkösnapilla. Mitään ei tapahdu. Painan kolmoshiiren nappia ihan missä vain (sulkee pelin) niin katsoppas kuva välähtää taustalla joka piti tulla jo aikaisemmin. Pistin SDL_delayn(5000); ja kyllä haluaman ikuva tulee siihen. Okei yritys kaksi: En painanut lainkaan taloa, mutta painoin suoraan kolmosta. Peli sammui ilman viivettä. Ja kolmas yritys painoin kuvaa ykköshiirellä ja sitten painoin kolmosta niin kuva tuli taas viideksi sekuntiksi. Miksei se tule aikaisemmin?

if valinta jälkeinen tapahtuma on alapuolella ja niiden alla nuo nappula sörsselit. =)

if (valinta==1)
	{
	SDL_FreeSurface(kuva);
	SDL_FreeSurface(talo_1);
	SDL_FreeSurface(talo_2);

	SDL_Surface *Tausta;

	Tausta=SDL_LoadBMP("grafiikat/tausta.bmp");
	PiirraKuvaTausta(Tausta, naytto);

	TTF_Init();
	SDL_Surface *teksti;
	SDL_Surface *teksti2;
	TTF_Font *font = NULL;
	SDL_Color textcolor = {255, 0, 0};
	font = TTF_OpenFont("courbd.ttf", 20);

	int c=50;
	char mjono[10];
	sprintf(mjono, "%i", c);
	teksti = TTF_RenderText_Blended(font, mjono, textcolor);
	teksti2 = TTF_RenderText_Blended(font, "Rahaa: ", textcolor);


    SDL_Rect alue_tekstille;
    alue_tekstille.x = 200;
    alue_tekstille.y = 200;

    SDL_Rect alue_tekstille2;
    alue_tekstille2.x = 120;
    alue_tekstille2.y = 200;

    SDL_BlitSurface(teksti, NULL, naytto, &alue_tekstille);
    SDL_BlitSurface(teksti2, NULL, naytto, &alue_tekstille2);

    SDL_Flip(naytto);
    SDL_Delay(5000);

}
void TarkastaOnkoPisteSuorakulmiossa(int hiiren_x, int hiiren_y, int taloKuvanX, int taloKuvanY, int taloKuvanLeveys, int taloKuvanKorkeus)
{
	int talon_viimeinen_X = taloKuvanX + taloKuvanLeveys;
	int talon_viimeinen_y = taloKuvanY + taloKuvanKorkeus;
	if ((hiiren_x >= taloKuvanX) && (hiiren_x <= talon_viimeinen_X))
	{
		if ((hiiren_y >= taloKuvanY) && (hiiren_y <= talon_viimeinen_y))
		{
		valinta = 1;

		}
	}
}

hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y);
if (SDL_GetMouseState(&hiiren_x, &hiiren_y) & SDL_BUTTON(1))
{
	TarkastaOnkoPisteSuorakulmiossa(hiiren_x, hiiren_y, taloKuvanX, taloKuvanY, taloKuvanLeveys, taloKuvanKorkeus);
}

	if(hiiri & SDL_BUTTON(3))
        pois=true;
        //koodia muutama rivi ja sitten
SDL_Flip(naytto);

Sivun alkuun

Vastaus

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

Tietoa sivustosta