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; }
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.
Tiedän sen olevan purkkamaista, mutta tämän hetken C++ taidoilla en pysty parempaan. Kuitenkin miten saan tuon ongelman korjatuksi. :)
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...
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.
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.
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.
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.
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.
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
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
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.
Sulle taidettiin mainita jonkun aikaa sitten, että opettele käyttämään tiedostonhallintaa, niin onnistuu tietojen lataus tiedostoista.
https://www.ohjelmointiputka.net/keskustelu/
Tuola on esimerkkejä miten tiedostoista pystyy lataamaan tietoa...
Olen tottunut PHP:n includeen liikaa, kun se toimii hieman eri tavalla. :)
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.
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ä. :)
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...
Ei se auta jos muutan niiden sijaintia vaan samat errorit tulee edelleen.
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/
Ja tosiaan katso niitä muitakin esimerkkejä tuolta, ku sitä ensimmäistä.
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); }
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ää.
Öö 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.
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.
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.
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.
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?
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?
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ä.
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.
#include <iostream> int main() { std::cout << "Hei maailma!"; return 0; }
Tuosta liikkeelle! ;)
Siis kyseessä on puoligraaffinen peli, jossa valikot ovat tekstipohjaisia, mutta en koskaan saanut PDCursesia asennettua niin teen sen SDL:llä.
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.
Niin, mutta tekstit pitää saada sijoittaa X, Y akselissa ja tietää mitä painikkeita painellaan.
"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?
Taulukon alustusta ja sen verran olen ohjelmoinut, että en ala 3D:tä tekemään vielä moneen vuoteen. :O
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.
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."
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...
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.
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?
Nettiohjelmointi on vielä paljon vaikeampaa kuin yksinkertainen grafiikkaohjelmointi. Grafiikassa harvoin tulee virhetilanteita, kun taas nettiyhteys on aika useinkin poikki tai aiheuttaa muulla tavalla harmia.
Teen ensimmäisen pelin yhteen tiedostoon ja toisen pelin eri tiedostoihin, jotta opin erillaisia tapoja.
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ä.
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.
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?
ÖÖ 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.
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ä!
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
Aihe on jo aika vanha, joten et voi enää vastata siihen.