Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Syötteet

Sivun loppuun

mika132 [31.10.2009 15:16:15]

#

Oli pakko kysyä, kun olen jo... 10h taistellut tämän kanssa ja eilen (oikeastaan tänään) meni ihan aamuyölle klo 4 asti kun koitin keksiä miten ratkaisen tämän. On kaksi huonetta joissa kummassakin on syötteenä tunnistettava ykkös nappula. Kun ensimmäisessä painaa ykköstä niin se lukee sen saman jo heti toisessa huoneessa. Eli apua tarvitsen.


Tällä kertaa mukana on kuitenkin oma yritys:

			if (tapahtuma_paalla == true)
			{

				if ( event.type == SDL_QUIT )
				{
					pois = true;
				}
				if ( event.type == SDL_KEYDOWN )
				{

				}
				if ( event.key.keysym.sym == SDLK_ESCAPE )
				{
					pois = true;
				}
				if ( event.key.keysym.sym == SDLK_RSHIFT )
				{
					huone=1;
				}
				if ( event.key.keysym.sym == SDLK_LSHIFT )
				{
					huone=1;
				}
				if ( event.key.keysym.sym == SDLK_1 )
				{
					saksa_liittolainen=true;
					huone=101;
				}
				if ( event.key.keysym.sym == SDLK_2 )
				{
					ranska_liittolainen=true;
					huone=101;
				}
				if ( event.key.keysym.sym == SDLK_3 )
				{
					venaja_liittolainen=true;
					huone=101;
				}
				if ( event.key.keysym.sym == SDLK_4 )
				{
					usa_liittolainen=true;
					huone=101;
				}
				if ( event.key.keysym.sym == SDLK_5 )
				{
					canada_liittolainen=true;
					huone=101;
				}
				if ( event.key.keysym.sym == SDLK_6 )
				{
					iso_britannia_liittolainen=true;
					huone=101;
				}
				if ( event.key.keysym.sym == SDLK_7 )
				{
					japani_liittolainen=true;
					huone=101;
				}
				if ( event.key.keysym.sym == SDLK_8 )
				{
					ruotsi_liittolainen=true;
					huone=101;
				}
			}
			if (tapahtuma_paalla == false)
			{
				SDL_Delay(500);
				tapahtuma_paalla=true;
			}

Legu [31.10.2009 15:32:01]

#

Ja mikähän on SDL_Delay(500):n idea?
Jos (ja kun) ohjelmasi ei ole monisäikeinen, niin ei tuosta odotuksesta ole mitään apua, koska ei sen toisen huoneen koodin suoritus jatku tuon odotuksen aikana, vaan koko ohjelma odottaa tuossa tuon puoli sekuntia ja jatkuu sitten kuin odotusta ei olisi ollutkaan.

Muutenkin koodi näyttää hyvin purkkamaiselta, joten kannattanee miettiä koodin rakennetta uudestaan.

mika132 [31.10.2009 15:45:07]

#

Tiedän sen olevan purkkamaista, mutta tämän hetken C++ taidoilla en pysty parempaan. Kuitenkin miten saan tuon ongelman korjatuksi. :)

Teuro [31.10.2009 15:52:21]

#

Voitko kertoa vielä tarkemmin mikä on ongelmana, koska tuosta koodista en ihan heti tajunnut mikä noiden kaikkien eri huoneiden tarkoitus on. Kovakoodaus on muutenkin kovin raskas tapa koodata...

mika132 [31.10.2009 16:06:42]

#

Huone 101 ilmoitetaan, että onnistuiko liiton luonti. Huone 1 on pää huone. ja tuo koodi on Huoneessa 2. Kun huoneessa yksi painetaan ykkös nappia se siirtyy huoneeseen kaksi ja jatkaa automaattisesti huoneeseen 101.

Teuro [31.10.2009 16:12:55]

#

Siis esimerkiksi jos painan kesken ohjelmaa (huoneessa 1) nappia yksi tulee pelaajan siirtyä huoneeseen 2? Silloin tuon tulisi kaiketi olla jotenkin näin:

if(event.key.keysym.sym == SDLK_1){
    lataa_huone(2);
}

lataa_huone(int huone_id); on nimensä mukaan huoneen latausfunktio. Se lukee tiedostosta sopivan huoneen, jonka tiedot se lataa muuttujiin ja olioihin / tietueisiin. Nuo erilaiset xxx_liittolainen kannattaa ehdottomasti laittaa taulukkoon, jolloin niiden käsittely muuntuu helpommaksi.

mika132 [31.10.2009 16:18:50]

#

kyllä minulla huoneen siirto toimii, mutta nyt on kyseessä, että C++ käsittelee välittömästi toisen huoneen tapahtumat ja tästä syystä huone 2 vain välähtää ja se ottaa toiminnon ykkösnappi joka siirtää huoneeseen 101.

Teuro [31.10.2009 16:40:58]

#

No eihän se huoneen vaihto silloin toimi ainakaan minusta. Tuolla minun tavalla ei tuollainen efekti ole mahdollista, koska siinä aidosti ladataan huoneen tiedot. Eli pelin koodi on kirjoitettu vain kerran ja jokainen huone käsitellään yhteisen käsittelijän kautta.

mika132 [01.11.2009 23:18:38]

#

Mites sen saa toimimaan, kun katselin muiden pelien tiedostoja ja siellä saattaa olla tiedostoja "car_physics.gf" niin miten itse saan jotain erillaisia päätteitä. Esim: Room_1.td eikä Room_1.cpp.

ByteMan [01.11.2009 23:38:00]

#

No yksi esimerkki on se, että sen sijaan että kovakoodaat kentän, niin laitat kentänmuodostukseen tarvittavat arvot ulkoiseen tiedostoon (esim seinien paikat) ja sitten vain luet sen ajon aikana.
[pilkunviilaus] ja eihän se pääte mitään vaikuta tiedoston sisältöön, voisit milloin tahansa korvata "Room_1.cpp":n "Room_1.huone" eikä se vaikuttaisi toimintaan mitenkään[/pilkunviilaus]

eli ajatuksen ydin on tiedostosta lukemisessa

mika132 [01.11.2009 23:51:44]

#

No mites, kun yritin tehdä näin:

Itse pää tiedostossa (main.cpp)
siellä pää silmukassa on koodi:

PiirretaanTekstia(teksti, naytto, 680, 20);
PiirretaanTekstia(teksti2, naytto, 600, 20);

Sitten samainen pää tiedosto pitää sisällään koodin:

void UusiHuone(int mihin_huoneeseen) {
huone=mihin_huoneeseen;
if (mihin_huoneeseen==1)
{
#include "room_1.cpp"
}
}

ja tiedostossa room_1.cpp oleva koodi:

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

teksti = TTF_RenderText_Blended(font, "(1) Diplomatia", textcolor);
teksti2 = TTF_RenderText_Blended(font, "(2) Tietoa maista", textcolor);

ja jos painetaan ykkös nappulaa tuo funktio UusiHuone toteutetaan, mutta debuggeria käyttäessäni se valittaa seuraavaa:

1>.\map_1.cpp(124) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\map_1.cpp(124) : error C2040: 'teksti' : 'int' differs in levels of indirection from 'SDL_Surface *'
1>.\map_1.cpp(125) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\map_1.cpp(125) : error C2040: 'teksti2' : 'int' differs in levels of indirection from 'SDL_Surface *'

Eli miten pitää koodi siistinä funktion sisällä, kun en saa tarvittavia muuttujia mukanani automaattisesti? :O

Teuro [02.11.2009 07:36:03]

#

Muuttujaa 'huone' ei ole esitelty, joten se tulkittaneen intiksi, joka taaseen aiheuttanee tuon C99 standardin mukaisen virheen käännöksen aikana. Lisäksi include ei ole oikein tuossa vaiheessa, koska se ei toimi kuten kuvittelet. include on esikääntäjän komento, jolla sisällytetään tiedostoja varsinaiselle kääntäjälle.

vehkis91 [02.11.2009 08:53:23]

#

Sulle taidettiin mainita jonkun aikaa sitten, että opettele käyttämään tiedostonhallintaa, niin onnistuu tietojen lataus tiedostoista.

https://www.ohjelmointiputka.net/keskustelu/19941-ulkoiset-tiedostot

Tuola on esimerkkejä miten tiedostoista pystyy lataamaan tietoa...

mika132 [02.11.2009 16:50:46]

#

Olen tottunut PHP:n includeen liikaa, kun se toimii hieman eri tavalla. :)

Teuro [02.11.2009 16:54:50]

#

Se toimii täsmälleen samalla tavalla, pitää vain muistaa, että PHP tulkitaan jokaisella kerralla uudelleen. Sen takia saattaa tulla illuusio, että se jotenkin liittäisi eri tiedoston käyttäjän valinnan mukaan. Tavallaan tuokin on ihan oikein, mutta C++ ohjelma tulisi kääntää ja linkittää jokaisella ajokerralla erikseen, jotta toiminta olisi samanlaista.

Tämän takia kentät olisi hyvä ladata ohjelman aikana erillisellä latausfunktiolla, jota tuolla ylempänä hiukan vihjailinkin. Tällä tavalla saat käyttäjän syötteisiin reagoivan ohjelman.

mika132 [02.11.2009 18:02:59]

#

Noniin. Nyt olen niin suuressa funktio umpparissa, että pakko taas kysäistä ja näyttää. :)


Tässä on nyt nämä kaksi funktiota. Joissa otetaan tekstin kirjoittamiseen muuttujat mukaan. Ensimmäisessä ladataan siis muutama tiedosto (niiden sisältö alapuolella)

void LadataanPeli(void) {
	#include "teksti_alustus.cpp"
	#include "room_1.cpp"
}
void UusiHuone(int mihin_huoneeseen)
{
	Huone_1(Oma_kaupunkit, Oma_alueet, Oma_teknologia, oma_sotilaita, oma_panssarivaunuja, oma_lentokoneita, oma_tykki, oma_pommeja, oma_ydinpommeja, oma_asukas_maara, oma_vero, puuta, rautaa, oljya, kivea, paiva, kk, vuosi);
	huone=mihin_huoneeseen;
}

teksti_alustus.cpp

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "windows.h"
#include <io.h>
#include "SDL_ttf.h"
#include <SDL.h>
#pragma comment(lib, "SDL_ttf.lib")
#pragma comment(lib, "SDLmain.lib")
#pragma comment(lib, "SDL.lib")
TTF_Init();
SDL_Surface *teksti2;
SDL_Surface *teksti3;
SDL_Surface *teksti4;
SDL_Surface *teksti5;

room_1.cpp

void Huone_1(int Oma_kaupunkit, int Oma_alueet, int Oma_teknologia, int oma_sotilaita, int oma_panssarivaunuja, int oma_lentokoneita, int oma_tykki, int oma_pommeja, int oma_ydinpommeja, int oma_asukas_maara, int oma_vero, int puuta, int rautaa, int oljya, int kivea, int paiva, int kk, int vuosi) {

	#include "teksti_alustus.cpp"
	TTF_Init();
		TTF_Font *font = NULL;
		TTF_Font *font1 = NULL;
		SDL_Color textcolor = {255, 0, 0};
		font = TTF_OpenFont("courbd.ttf", 20);
		font1 = TTF_OpenFont("courbd.ttf", 30);

		char Oma_kaupunkitt[10];
		char Oma_alueett[10];
		char Oma_teknologiat[10];

		char Oma_sotilaitat[10];
		char Oma_panssarivaunujat[10];
		char Oma_lentokoneitat[10];
		char Oma_tykkejat[10];
		char Oma_pommejat[10];
		char Oma_ydinpommejat[10];
		char oma_asukas_maarat[10];
		char oma_verot[10];

		char puutat[10];
		char rautaat[10];
		char oljyt[10];
		char kivet[10];

		char paivat[10];
		char vuosit[10];
		char kkt[10];

		sprintf(Oma_kaupunkitt, "%i", Oma_kaupunkit);
		sprintf(Oma_alueett, "%i", Oma_alueet);
		sprintf(Oma_teknologiat, "%i", Oma_teknologia);

sprintf(Oma_sotilaitat, "%i", oma_sotilaita);
sprintf(Oma_panssarivaunujat, "%i", oma_panssarivaunuja);
sprintf(Oma_lentokoneitat, "%i", oma_lentokoneita);
			sprintf(Oma_tykkejat, "%i", oma_tykki);
			sprintf(Oma_pommejat, "%i", oma_pommeja);
			sprintf(Oma_ydinpommejat, "%i", oma_ydinpommeja);
			sprintf(oma_asukas_maarat, "%i", oma_asukas_maara);
			sprintf(oma_verot, "%i", oma_vero);

			sprintf(puutat, "%i", puuta);
			sprintf(rautaat, "%i", rautaa);
			sprintf(oljyt, "%i", oljya);
			sprintf(kivet, "%i", kivea);

			sprintf(paivat, "%i", paiva);
			sprintf(kkt, "%i", kk);
			sprintf(vuosit, "%i", vuosi);


char mjono[10];
sprintf(mjono, "%i", rahaa);
teksti2 = TTF_RenderText_Blended(font, "Rahaa: ", textcolor);
teksti3 = TTF_RenderText_Blended(font, "(1) Diplomatia", textcolor);
teksti4 = TTF_RenderText_Blended(font, "(2) Tietoa maista", textcolor);
teksti5 = TTF_RenderText_Blended(font, "(3) Käy kauppaa", textcolor);
PalataanTakaisin(teksti, teksti2, teksti3, teksti4, teksti5);
}

Tässä on palaamis funktio (eli tämä on pää tiedostossa main.cpp)

void PalataanTakaisin(int teksti2, int teksti3, int teksti4, int teksti5) {
huone=1;
			PiirretaanTekstia(teksti2, naytto, 600, 20);
			PiirretaanTekstia(teksti3, naytto, 20, 40);
			PiirretaanTekstia(teksti4, naytto, 20, 60);
			PiirretaanTekstia(teksti5, naytto, 20, 80);
}

Ja piirto funktio eli PiirretaanTekstia joka on tiedostossa main.cpp eli pää tiedostossa.

void PiirretaanTekstia(SDL_Surface *teksti, SDL_Surface *naytto, int tekstin_x, int tekstin_y) {


			SDL_Rect alue_tekstille;
			alue_tekstille.x = tekstin_x;
			alue_tekstille.y = tekstin_y;

			SDL_BlitSurface(teksti, NULL, naytto, &alue_tekstille);
}

ja tässä osa erroreista:

1>.\World Leaders 2 - The wolrd.cpp(173) : error C2065: 'naytto' : undeclared identifier
1>.\World Leaders 2 - The wolrd.cpp(173) : error C3861: 'PiirretaanTekstia': identifier not found
1>.\World Leaders 2 - The wolrd.cpp(174) : error C2065: 'naytto' : undeclared identifier
1>.\World Leaders 2 - The wolrd.cpp(174) : error C3861: 'PiirretaanTekstia': identifier not found


Eli se väittää ettei löydä piirto funktiota.


Eli todellisuus on se, että teksti2, teksti3 jne. On ihan teksti52 asti, mutta hienonpana pitämisen johdosta pistin vain osan niistä. :)

vehkis91 [02.11.2009 18:13:19]

#

hmmm, musta tuntuu, että oot jotenkin ymmärtäny väärin ton koodin jakamisen tiedostoihin...

EDIT: laita nyt vaikka ens alkuun kaikki includet sinne main tiedoston alkuun, niin onnistuu paremmin ja kato viel ne pari aiheesta kertovaa koodivinkkiä uudelleen läpi.

Ja laita noi teksti muuttujat tähän tyyliin:

//taulukko teksteille
SDL_Surface* teksti[TEKSTIEN_MÄÄRÄ];
//pistetään jotain tekstiä
teksti[0] = TTF_RenderText_Blended(font, "Rahaa: ", textcolor);
teksti[1] = TTF_RenderText_Blended(font, "(1) Diplomatia", textcolor);
teksti[2] = TTF_RenderText_Blended(font, "(2) Tietoa maista", textcolor);
teksti[3] = TTF_RenderText_Blended(font, "(3) Käy kauppaa", textcolor);
etc...

mika132 [02.11.2009 21:23:01]

#

Ei se auta jos muutan niiden sijaintia vaan samat errorit tulee edelleen.

vehkis91 [02.11.2009 22:01:53]

#

NO kuten sanoin, sulla on noi #include rivit ihan väärissä paikoissa. Ainakin mitä tuosta nopeesti katsoin. On paljon selvempää, jos kaikki #include rivit ovat tiedoston alussa. Tsiigaas vielä sitä koodivinkkiä kys.aiheesta.

https://www.ohjelmointiputka.net/koodivinkit/25046-c-koodin-jakaminen-eri-tiedostoihin

Ja tosiaan katso niitä muitakin esimerkkejä tuolta, ku sitä ensimmäistä.

mika132 [02.11.2009 22:55:53]

#

No vaikka muuttaisin ne niin alkuun, mistä maailma alkaa niin ei auta tämä funktio kusee:

void PalataanTakaisin(int teksti, int teksti2, int teksti3, int teksti4, int teksti5, int teksti6, int teksti7, int teksti8, int teksti9, int teksti10, int teksti11, int teksti12, int teksti13, int teksti14, int teksti15, int teksti16, int teksti17, int teksti18, int teksti19, int teksti20, int teksti21, int teksti22, int teksti23, int teksti24, int teksti25, int teksti26, int teksti27, int teksti28, int teksti29, int teksti30, int teksti31, int teksti32, int teksti33, int teksti34, int teksti35, int teksti36, int teksti37, int teksti38, int teksti39, int teksti40, int teksti41, int teksti42, int teksti43, int teksti44, int teksti45, int teksti46, int teksti47, int teksti48, int teksti49, int teksti50, int teksti51, int teksti52) {
huone=1;
			PiirretaanTekstia(teksti, naytto, 680, 20);
			PiirretaanTekstia(teksti2, naytto, 600, 20);
			PiirretaanTekstia(teksti3, naytto, 20, 40);
			PiirretaanTekstia(teksti4, naytto, 20, 60);
			PiirretaanTekstia(teksti5, naytto, 20, 80);
			PiirretaanTekstia(teksti6, naytto, 20, 100);
			PiirretaanTekstia(teksti7, naytto, 20, 120);
			PiirretaanTekstia(teksti8, naytto, 20, 140);
			PiirretaanTekstia(teksti9, naytto, 20, 200);
			PiirretaanTekstia(teksti10, naytto, 20, 220);
			PiirretaanTekstia(teksti11, naytto, 740, 40);
			PiirretaanTekstia(teksti12, naytto, 780, 60);
			PiirretaanTekstia(teksti13, naytto, 800, 100);
			PiirretaanTekstia(teksti14, naytto, 600, 40);
			PiirretaanTekstia(teksti15, naytto, 600, 60);
			PiirretaanTekstia(teksti16, naytto, 600, 100);
			PiirretaanTekstia(teksti17, naytto, 600, 140);
			PiirretaanTekstia(teksti18, naytto, 600, 180);
			PiirretaanTekstia(teksti19, naytto, 600, 200);
			PiirretaanTekstia(teksti20, naytto, 600, 220);
			PiirretaanTekstia(teksti21, naytto, 600, 240);
			PiirretaanTekstia(teksti22, naytto, 600, 260);
			PiirretaanTekstia(teksti23, naytto, 600, 280);
			PiirretaanTekstia(teksti24, naytto, 720, 180);
			PiirretaanTekstia(teksti25, naytto, 790, 200);
			PiirretaanTekstia(teksti26, naytto, 755, 220);
			PiirretaanTekstia(teksti27, naytto, 700, 240);
			PiirretaanTekstia(teksti28, naytto, 700, 260);
			PiirretaanTekstia(teksti29, naytto, 745, 280);
			PiirretaanTekstia(teksti30, naytto, 600, 320);
			PiirretaanTekstia(teksti31, naytto, 830, 320);
			PiirretaanTekstia(teksti32, naytto, 600, 340);
			PiirretaanTekstia(teksti33, naytto, 780, 340);
			PiirretaanTekstia(teksti34, naytto, 600, 380);
			PiirretaanTekstia(teksti35, naytto, 600, 420);
			PiirretaanTekstia(teksti36, naytto, 600, 440);
			PiirretaanTekstia(teksti37, naytto, 600, 460);
			PiirretaanTekstia(teksti38, naytto, 600, 480);
			PiirretaanTekstia(teksti39, naytto, 700, 420);
			PiirretaanTekstia(teksti40, naytto, 700, 440);
			PiirretaanTekstia(teksti41, naytto, 700, 460);
			PiirretaanTekstia(teksti42, naytto, 700, 480);
			PiirretaanTekstia(teksti43, naytto, 20, 2);
			PiirretaanTekstia(teksti44, naytto, 160, 2);
			PiirretaanTekstia(teksti45, naytto, 185, 2);
			PiirretaanTekstia(teksti46, naytto, 210, 2);
			PiirretaanTekstia(teksti47, naytto, 160, 2);
			PiirretaanTekstia(teksti48, naytto, 185, 2);
			PiirretaanTekstia(teksti49, naytto, 210, 2);
			PiirretaanTekstia(teksti50, naytto, 20, 400);
			PiirretaanTekstia(teksti51, naytto, 20, 420);
			PiirretaanTekstia(teksti52, naytto, 20, 440);
}

Legu [02.11.2009 23:00:12]

#

mika132 kirjoitti:

No vaikka muuttaisin ne niin alkuun, mistä maailma alkaa niin ei auta tämä funktio kusee:

...

Joo, funktiosi todellakin kusee.
Sinulla on ohjelmoinnin perusidea ilmiselvästi hakusessa, kun tuollaista 52-parametristä funktiota lähdet työstämään.
Ehkä kannattaa aloittaa perusteista, eikä heti alkuun yrittää tehdä mitään liian ylevää.

vehkis91 [02.11.2009 23:22:54]

#

Öö miten noi sun tekstis on int muodoss???? Mää ymmärsin ett piti olla SDL_Surface* muodoss.

Mut tosiaan, en oo koskaan aikaisemmin nähny funkkaria, jossa on noin monta parametria.

eli opettele käyttämään taulukoita!!!!!!

EDit:

SDL_Surface* tekstit[52];
teksti[0] = TTF_RenderText_Blended(font, "Rahaa: ", textcolor);
teksti[1] = TTF_RenderText_Blended(font, "(1) Diplomatia", textcolor);
etc...

void PalataanTakaisin(SDL_Surface **tekstit)
{
   huone = 1;

   PiirretaanTekstia(teksti[0], naytto, 680, 20);
   PiirretaanTekstia(teksti[1], naytto, 600, 20);
   etc...
}

Tämä on ehkä vähän parempi ratkaisu.

mika132 [03.11.2009 16:07:24]

#

Ok eli tein näin tekstien alustkusen:

		SDL_Surface *teksti[54]

Ja funktioissa

void Huone_1(SDL_Surface *teksti[54]) {

jne.

Mutta errorit menevät nyt SDL_video.h tiedostoon:

1> (polku)\room_1.cpp(15) : error C2144: syntax error : 'void' should be preceded by ';'
1> (polku)\room_1.cpp(18) : error C2146: syntax error : missing ';' before identifier 'TTF_Init'
1> (polku)\room_1.cpp(18) : error C2082: redefinition of formal parameter 'teksti'
1> (polku)\room_1.cpp(71) : error C2065: 'rahaa' : undeclared identifier
....

Ja tuon saman errorin toistaminen jatkuu eli alapuolella oleva errori tulee noin 100 kertaa, koska erroreita on 104.

Metabolix [03.11.2009 16:31:09]

#

Luepa ensimmäinen virhe: "Ennen void-sanaa pitäisi olla puolipiste." Kyseinen void-sana on kyllä SDL:n otsikkotiedostossa, mutta puolipiste puuttuu aivan omasta koodistasi hieman ennen SDL-otsikon sisällytystä.

Monissa osissa koodiasi ei ole yhtikäs mitään järkeä. Olet selvästi aivan pihalla aivan perusasioista, joten suosittelen, että palaat C++:n alkeisiin (erityisesti oppaan osiin 1–6), kunnes kykenet edes tuollaisia perusasioita ratkomaan itse. Selvitä, miten saat koodivinkit 1770 ja 1901 toimimaan. Ota niistä mallia tiedoston jakamisen suhteen. Asian teoriapohja kerrotaan C++:n kannalta C++-oppaassa ja include-rivin kannalta C:n esikääntäjästä kertovassa oppaassa.

Onko perusteiden opettelussa oppaiden avulla jokin ongelma, vai onko sinulla vain liian kiire "hienoihin" tuloksiin, jotta viitsisit tehdä järjestelmällisesti töitä ohjelmoinnin oppimiseksi? Olisit jo nyt säästänyt (ja säästäisit jatkossakin) tuntikausia aikaa, jos olisit opetellut aluksi perusasiat tarpeeksi hyvin. Unohda SDL, unohda PDCurses, käytä cin- ja cout-olioita ja tee ensiksi niillä tuo pelisi.

mika132 [03.11.2009 17:03:12]

#

Alan pääsemään jo jyvälle näistä tilanteista ja sain joa 39 erroria pois ja huomasin, että en missään vaiheessa funktiossani suorittanut koodia:

SDL_Surface *naytto

tein sen niin huomasin, että mikä errori/koodi panttaa tekstin kirjoitusta vastaan ja se on tässä:

Tiedossa tekstin_alustus.cpp

SDL_Surface *teksti[54];

Ja errorit.

1> (polku)\teksti_alustus.cpp(14) : error C2086: 'SDL_Surface *teksti[54]' : redefinition
1> (polku)\teksti_alustus.cpp(14) : see declaration of 'teksti'

Eikö SDL ymmärrä tuota vai mistä homma kiikastaa, kun tein teksti[1]; teksti[2]; jne tuohon tilalle, mutta se hetti erroria sen jälkeen niistä kaikista.

PS. En ole ylpeä vaan tyhmä. En opi mitä luen vaan mitä teen/kysyn. PHP:n opein myös sillä tavalla kun kyselin.

Metabolix [03.11.2009 21:35:15]

#

Luepa taas ne virheilmoitukset. "Muuttuja teksti määritellään uudestaan tiedostossa ... rivillä 14." Toisin sanoen ohjelmassasi on nyt useita teksti-nimisiä muuttujia, vaikka pitäisi olla vain yksi.

Koska kääntäjä mainitsee saman rivin kahteen kertaan (virheessä ja vinkkinä aiemman määrittelyn paikasta), aavistelen, että teet edelleenkin jotain kummallista includeilla. Toivottavasti jossain vaiheessa toteutat ohjelman jakamisen oikein, kuten moneen kertaan mainituissa koodivinkeissä ja oppaissa neuvotaan.

mika132 kirjoitti:

En opi mitä luen vaan mitä teen/kysyn.

Ei sitä ensimmäisellä lukukerralla tarvitsekaan oppia. Oletko kokeillut tehdä harjoituksena sellaisia asioita, joihin voisit sitten ongelmatilanteissa itse etsiä vastaukset? Samalla etsiessäsi törmäisit moneen muuhunkin asiaan, jolloin seuraavalla kerralla etsiminen kävisi entistä nopeammin. Jatkuva kysely osoittaa, että tavoitteesi ovat liian korkealla omien taitojesi yläpuolella. Ikävän suuri osa vastauksista on mennyt aivan hukkaan, kun et ole ymmärtänyt tai noudattanut neuvoja. Omat korjauskokeilusi (kuten tuo teksti[1], teksti[2]) osoittavat, että olet aivan hukassa C++:n alkeista (osa 4, #taulukot). Miksi silti yrität väkisin tehdä graafista peliä, johon tarvitset useaa apukirjastoa ja jota tehdessä täytyisi C++:n perusasioiden muistua mieleen automaattisesti?

C++-oppaassa on kokonaisia esimerkkejä, jotta niitä voisi kokeilla ja muunnella itse. Ymmärrätkö kaikkien esimerkkien toiminnan? Niiden pohjalta voi myös tehdä kaikenlaista: Oletko kokeillut lisätä ohjelmiin toimintoja tai muunnella niiden toimintaa, jotta oppisit asian paremmin? Osaatko itse tehdä vastaavat ohjelmat puhtaalta pöydältä? Osaatko tehdä oppaan alkupuolella esitettyjä ohjelmia uudelleen niin, että käytätkin jotain myöhemmin esiteltyä rakennetta?

Edit: Hukkaan menneistä neuvoista: Sanoin jo kuukausi sitten, että TTF_Init pitäisi sijoittaa ohjelman alkuun, ja tuolla se sinulla yhä komeilee aivan väärässä paikassa, keskellä peliä.

Metabolix kirjoitti:

Miksi TTF_Init ja TTF_Quit ovat tuolla muun koodin seassa eivätkä ohjelman alussa ja lopussa kuten SDL_Init ja SDL_Quit?

mika132 [04.11.2009 17:07:30]

#

Eli pitääkö minu tehdä tälläinen systeemi:

string teksti[54] = (SDL_Surface *teksti[1], SDL_Surface *teksti[2], SDL_Surface *teksti[3], SDL_Surface *teksti[4], SDL_Surface *teksti[5], SDL_Surface *teksti[6], SDL_Surface *teksti[7], SDL_Surface *teksti[8], SDL_Surface *teksti[9], SDL_Surface *teksti[10]); //jatkaa teksti[54] asti?

Vai selviääkö tästä jollain muulla tavalla?

Metabolix [04.11.2009 17:23:31]

#

Mitä ihmettä yrität edes kysyä? Rivissäsi ei ole rakenteellisesti yhtikäs mitään järkeä, ja muutenkaan SDL_Surfacella ja string-olioilla ei ole mitään tekemistä keskenään.

Oletko ollenkaan katsonut, miten taulukot toimivat ja miten niitä välitetään funktioille?

On myös hankala antaa kovin täsmällisiä neuvoja, kun et ole missään vaiheessa kertonut, mitä edes yrität teksteilläsi tehdä.

Teuro [04.11.2009 17:26:01]

#

Eli tuossa kysymyksessä konkretisoituu Metabolixin arvio taidoistasi. Et yksinkertaisesti ole vielä valmis tekemään graafista peliä, koska perusasiat ovat kovasti paljon hakusessa. Ja tuohon kysymykseesi vastaus on ei tarvitse tehdä noin. Ohjelmoinnissa pätee ihan hyvä nyrkkisääntö: jos kirjoitat samanlaista asiaa monta kertaa teet jotakin väärin.

Tuossa yrität muodostaa 55 alkion taulukkoa SDL_Surface taulukoille. Auki kirjoitettuna tuon pitäisi kertoa sinulle heti, että väärin menee ja lujaa. SDL_Surface* on siis osoitin piirtopintaan, eikä osoitin osoittimeen. Oikeasti päsrjäät ihan hyvin yhdellä piirtopinnalla, johon kirjoitat kaiken tarvittavan datan. Tämän pinnan piirrät sitten varsinaiselle piirtopinnalle ja käännät esiin.

Mitä jos ihan oikeasti teet tuon pelisi ensin tekstimuodossa, jolloin ei tarvitse käyttää aikaa epäoleelliseen.

Mazzimo [04.11.2009 18:04:25]

#

#include <iostream>

int main()
{
   std::cout << "Hei maailma!";
   return 0;
}

Tuosta liikkeelle! ;)

mika132 [04.11.2009 18:48:00]

#

Siis kyseessä on puoligraaffinen peli, jossa valikot ovat tekstipohjaisia, mutta en koskaan saanut PDCursesia asennettua niin teen sen SDL:llä.

Teuro [04.11.2009 18:52:57]

#

Mikäs vika perinteisissä valikoissa muka on? Ne on paitsi paljon helpompia, mutta myös merkittävästi nopeampi koodata, kuin SDL:n vastaavat viritelmät. Lisäksi aikaa jää itse pelin tekemiseen ja uusien asioiden oppimiseen.

mika132 [04.11.2009 19:15:10]

#

Niin, mutta tekstit pitää saada sijoittaa X, Y akselissa ja tietää mitä painikkeita painellaan.

Metabolix [04.11.2009 19:21:55]

#

"Joo ja lisäksi pitäisi olla 3D-maailma, jossa voisi lennellä erilaisilla lentokoneilla ja helikoptereilla, eli en voi millään tehdä tästä tekstipeliä."

Ei ohjelmointia opita hetkessä eikä myöskään yrittämällä liian vaikeita asioita. Luulenpa, että jos olisit käyttänyt aikasi fiksummin, saattaisit nyt jo osatakin tehdä tuollaisen SDL-pelin, mutta koska yrität liian vaikeita asioita, et pääse juurikaan eteenpäin.

Selvä, et voi tehdä tuota peliä standardikirjastolla, joten tee ensin jokin muu peli, johon standardikirjasto riittää. Ei tuollaisesta vääntämisestä tule mitään, kun et ymmärrä monia yksinkertaisiakaan asioita.

Haluaisitko jo selittää, mitä tuon edellisen koodirivisi oli tarkoitus tarkoittaa?

mika132 [04.11.2009 19:25:00]

#

Taulukon alustusta ja sen verran olen ohjelmoinut, että en ala 3D:tä tekemään vielä moneen vuoteen. :O

Teuro [04.11.2009 19:33:25]

#

Katsopa, mitä teuro ohjelmointikokemus 3-vuotta kysyi tällä hetkellä ei edes kehtaa oikein avata noita ketjuja, mutta noista ajoista on vaan kehitytty, kun vaan jaksaa opetella riittävän helppoja asioita.

Metabolix [04.11.2009 20:12:36]

#

Jatkokysymyksiä (pohdintaa ja opettelua varten; itse toki osaan nämä asiat):
1. Voiko SDL_Surface-rakenteen sijoittaa string-olioon?
2. Voiko SDL_Surface*-tyyppisen osoittimen sijoittaa string-olioon?
3. Voiko taulukollisen SDL_Surface*-tyyppisiä osoittimia sijoittaa string-olioon?
4. Mitä sulkuja (kaari-, aalto-, haka- vai kulma-) käytetään taulukon alkuarvojen ympärillä?
5. Mitä tarkoittaa SDL_Surface *teksti[5]?
6. Voiko koodi SDL_Surface *teksti[5] toimia alkuarvona? (Perustele.)
7. Voiko samassa koodissa olla SDL_Surface *teksti[5] ja SDL_Surface *teksti[10]? (Perustele.)
8. Montako SDL_Surface-rakennetta sisältää SDL_Surface *teksti[5]? (Perustele.)
9. Montako SDL_Surface*-tyyppistä osoitinta sisältää SDL_Surface *teksti[5]?
10. Kun määritellään SDL_Surface *teksti[5], mikä on teksti[1] tyypiltään?
11. Kun määritellään SDL_Surface *teksti[5], mikä on *teksti[1] tyypiltään?
12. Kun määritellään SDL_Surface *teksti[5], mitkä ovat kelvolliset indeksit (teksti[1], teksti[2], muita)?

Kaikki kysymykset ovat todella helppoja. Montako osaat? Kauanko joudut miettimään? Tiedätkö jo vastauksen vai selvitätkö sen jostain, ja kauanko etsiminen kesti? Jotta voisit sujuvasti ohjelmoida SDL:llä, oikea vastaussarja on tämä: "Osaan kaikki. Mietin enintään pari sekuntia. Ei tarvinnut etsiä, vaan tiesin kaikki."

Teuro [04.11.2009 20:28:26]

#

Mikäli etsit tapaa sijoitella noita tekstejä tietorakenteeseen, niin alla olevasta voisi olla apua. Tässä siis survotaan SDL_Surface * -tyyppiseen vektoriin noita tekstejä. Lopuksi ne tulostetaan hauskasti yksitellen näytölle allekain. Koodi takuulla kommentoi itsensä.

#include <SDL/SDL.h>
#include <SDL_ttf.h>
#include <vector>

int main (int argc, char **argv){
    SDL_Init(SDL_INIT_VIDEO);
    TTF_Init();
    TTF_Font *font = TTF_OpenFont("C:\\windows\\Fonts\\ariali.ttf", 12);

    atexit(SDL_Quit);

    SDL_Surface *ruutu = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);
	std::vector <SDL_Surface *> tekstit;

	SDL_Color tv = {60, 220, 35};

	tekstit.push_back(TTF_RenderText_Solid(font, "Terve", tv));
	tekstit.push_back(TTF_RenderText_Solid(font, "Moikka", tv));
	tekstit.push_back(TTF_RenderText_Solid(font, "Herne", tv));
	tekstit.push_back(TTF_RenderText_Solid(font, "Moooi!", tv));
	tekstit.push_back(TTF_RenderText_Solid(font, "Howdy", tv));
	tekstit.push_back(TTF_RenderText_Solid(font, "Moroo", tv));

	for(int a = 0; a < tekstit.size(); a++){
		SDL_Rect paikka = {200, a * 20 + 5};
		SDL_BlitSurface(tekstit[a], 0, ruutu, &paikka);
		SDL_Flip(ruutu);
		SDL_Delay(800);
	}

    return EXIT_SUCCESS;
}

Muuta yllä olevaa koodia siten, että joka toinen rivi tulostetaan alkamaan 150 pikseliä vasemmasta reunasta ja joka toinen 20 pikseliä enemmän vasemmalta kuin edellinen. Siis 0 = 150 1 = 170 2 = 150 3 = 190 jne...

mika132 [04.11.2009 21:09:58]

#

Ok. Teen sen helpomman projektin, mutta pitäisi saada tietää yksi juttu. Miten saan pelin ns. Netin kanssa yhteyteen. Eli jos on korjauspäivitys niin se ilmoitetaan pelin käynnistyessä? Kyseessä on perus tekstiseikkailu.

Teuro [04.11.2009 21:17:37]

#

Unohda netti ja kaikki muukin turha. Väitän, että kukaan ei aio pelata peliäsi, joten tuolla ominaisuudella ei ole mitään lisäarvoa. Tuolla olisi ainoastaan lisäarvo sinulle, jos opettelisit noita asioita. Tällä hetkellä suosittelen sinulle yksinkertaisen tekstipelin tekemistä.

Pienikin projekti on (liian) iso, jos on pientäkään epäselvyyttä perusasioissa. Olitko ajatellut toteuttaa pelin tiedostoilla, jossa jokainen kenttä ladataan erikseen vai kirjoitella koko pelin (juoni + toimintalogiikka) samaan?

Metabolix [04.11.2009 21:25:13]

#

Nettiohjelmointi on vielä paljon vaikeampaa kuin yksinkertainen grafiikkaohjelmointi. Grafiikassa harvoin tulee virhetilanteita, kun taas nettiyhteys on aika useinkin poikki tai aiheuttaa muulla tavalla harmia.

mika132 [04.11.2009 21:27:06]

#

Teen ensimmäisen pelin yhteen tiedostoon ja toisen pelin eri tiedostoihin, jotta opin erillaisia tapoja.

vehkis91 [04.11.2009 21:31:35]

#

Ymmärsitköhän oikein, Teuro varmaan tarkoitti, että meinaatko ladata tiedostoista ne kentät peliin, vai kovakoodata suoraan koodiin mukaan kaiken.

PS:
Pahoittelut jos mää olin väärässä.

Metabolix [04.11.2009 22:05:18]

#

Ensimmäisen tekstipelin juonen voi tehdä suoraan lähdekoodiinkin. Sitten kannattaa opetella käyttämään datatiedostoja, jotta pelin tekstejä ja toimintaa voisi muokata koskematta enää koodiin. Tiedostoista sait muistaakseni jo esimerkkejä toisessa keskustelussa, joten loppu hommasta onkin kiinni omasta kekseliäisyydestäsi.

Muista: mutkikkaimmatkin ohjelmat voi koota muuttujista, lausekkeista, ehtolauseista ja silmukoista. Ohjelmoimaan voit oppia vain sillä, että käytät omia aivojasi ja keksit ratkaisuja ongelmiin; kopioitu ratkaisu ei opeta paljonkaan, koska et joudu ajattelemaan asiaa. Et tarvitse tätä foorumia. Saattaisit jopa oppia alkeet paremmin, jos vain kokeilisit ja yrittäisit itse. Siinä ajassa, jonka kysymyksen lähettäminen kestää, ehtii kokeilla jo useita erilaisia ratkaisuja. Jokaisesta kokeilusta oppii jotain: oppii, mikä toimii, ja oppii, mikä ei toimi. Molemmat ovat tärkeitä tietoja. Kysymyksen vastauksesta oppii usein enintään yhden asian, tai jos vain kopioi koodin, ei opi sitäkään.

mika132 [04.11.2009 22:16:54]

#

Juu tiedän kyllä, että itse tekemällä oppii esimerkiksi ensimmäiset selainpelini PHP:llä olivat melko koodi sössöä. Tein saman pelin ajankuluksi toiseen kertaan ja selvisin jopa 40% vähemmällä koodi määrällä ja 100% puhtaammalla koodilla ja nykyään osaan PHP:llä pitää koodin puhtaana. C++ vain vaikuttaa niin laajalta ohjelmalta, että menee aikansa tottua, mutta joo. Yritän nyt itse ratkaista ongelmia ja tehdä. Erillaisia tiedostoja yms. :)

Yksi kysymys on kuitenkin vielä jäljellä, mikä tulee ennemmin tai myöhemmin vastaan. :P

Miten voin kryptata lähdekoodin?

vehkis91 [04.11.2009 22:20:25]

#

ÖÖ täh? Miks se pitäis cryptata? Kukaan ei voi saada sun lähdekoodias, ellet itse sitä niille anna. exe tiedoston voi disassembloida, jolloin siitä tuleee assemblya, tätä lähemmäksi ei sun koodias päästä.

Ja c++ on kieli, eikä mikään ohjelma ja vieläpä syntaxiltaan melkein täysin samanlainen kuin php.

Metabolix [04.11.2009 22:50:12]

#

Ihan oikeasti, keskity nyt niihin olennaisiin asioihin. Tällä hetkellä koodisi on jo henkisellä tasolla kryptattu: itse en ainakaan kehtaisi väittää sitä omakseni. Joskus vuosien päästä ehkä osaat koodata niin hyvin, että koodillasi on arvoa muillekin kuin itsellesi, ja siinä vaiheessa osaat ehkä itsekin selvittää, mitkä ovat koodin ja datan suojaamisen mahdollisuudet ja mahdottomuudet.

Kaikkein paras vaihtoehto siinä vaiheessa on saada sen verran mainetta, ettei kryptaukseen ole tarvetta: maailmassa on monia vapaan lähdekoodin ohjelmia, ja mitä parempi ohjelma on, sitä vaikeampi kenenkään on luvattomasti väittää sitä omakseen.

Vai uskoisitko, jos väittäisin, että minä olen itse asiassa kirjoittanut koko Linux-kernelin (käyttöjärjestelmän ytimen)? Voin antaa lähdekooditkin: lataa täältä!

Grez [04.11.2009 23:14:11]

#

Vitsi oot kyllä niin guru jätkä Metabolix että oon aina epäillytkin että oot koodaillut ton kernelin kokonaan itse, mutta useilla eri salanimillä... :D


Sivun alkuun

Vastaus

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

Tietoa sivustosta