moi.
Minulla olisi sellainen kysyymys, että mitenkä voisi tehdä koodin, joka piirtää napista painattaessa uuden kuvan ruudulle ja liikuttaa sitä ylöspäin?
No teet niin, että luot silmukan, joka piirtää kuvan kohtaan (kuvax, kuvay). Piirtämisen jälkeen sitten luet näppäinpainallukset -> jos painetaan ylöspäin niin vähennetään kuvay:n arvoa. Yksinkertaista.
Ohjeet tähän löydät Putkan SDL-oppaasta.
Ilmeisesti ymmärsit asian väärin :D. Kyllä minä tuon nyt osaan. Tarkoitus olisi, että se piirtää aina uuden kuvan ja alkaa liikuttamaan sitä ylöspäin. Siis ainakun nappia painetaan piiretään uusi kuva.
https://www.ohjelmointiputka.net/oppaat/opas.
Tuossahan on tuollainen esimerkki, jonka kaltaista ilmeisesti yrität toteuttaa?
Ai siis niin. mörr, epäselvä kysymys, buu
Ei todellakaan tarkoita mitään tuolaista :P. Noh, tätä ajamaani tekniikkaa voisi käyttää vaikka ammuttaessa. Eli aina kun painetaan ampumis nappia luodaan uusi panos ja asetetaan se tiettyy paikkaan ja sitten se sitä aletaan liikuttamaan eteenpäin.
Öh, aletaan liikuttamaan eteenpäin? o_O
Mites ajattelit liikuttaa sitä josset muuttamalla sen koordinaatteja ja piirtämällä sen aina uudestaan?
Luo oma ammusluokka. Jokaisella ammus-luokan instanssilla on oma nopeusvektorinsa, paikkavektorinsa sekä osoitin pintaan, joka halutaan piirtää paikkavektorin kohtaan. Luot ensiksi ns. "masterpinnan", jonka osoitteen jokainen ammus-luokan instanssi ottavat. Aina kun haluat luoda uuden ammuksen, luot uuden instanssin dynaamisesta muistista ja linkität sen ammuksille tarkoitettuun linkitettyyn listaan. Joka loopinkierrolla käyt listan läpi päivittäen ammuksien sijainnin (paikkavektorin) sen nopeusvektorin avulla sekä sen jälkeen piirrät ammus-olion osoittaman pinnan näytölle (yms.. muut tarkistukset, esim. ammuksen törmäys). Kun ammus-olio halutaan poistaa, poistat vain kyseisen instanssin listasta (sekä varatusta muistista).
(Toivottavasti menivät termit oikein... :P instanssi == olio (ainakin) minun kielelläni.. :D )
Voisitteko tehdä minulle esimerkki koodin?
Paljon parempi on, jos teet koodin itse. Siinä oppii mukavasti asioita, kun taas toisten koodeja kopioimalla menee pää sekaisin eikä ohjelmoinnista tule mitään. Vinkkinä kuitenkin neuvoisin käyttämään noiden linkitettyjen listojen sijasta taulukoita, koska se on aluksi helpompaa.
Luot siis ammustaulukon, jossa on vaikkapa 1000 paikkaa, ja sitten aina kun uusi ammus luodaan, sijoitat sen tuohon taulukkoon. Sitten onkin helppo käydä kaikki ammukset läpi ihan tavallisella for-silmukalla. Aluksi kannattaa ehkä tehdä koodi, joka vain luo ammuksia tasaisin väliajoin tiettyyn paikkaan ja liikuttaa niitä kaikkia sitten samaan suuntaan. Kun saat tuon toimimaan, voit yrittää saada ammuksia liikkumaan eri suuntiin (tarvitset siinä trigonometriaa).
Tässä yksinkertainen päästä heitetty esimerkki siitä, miten ammusluokka kannattaa toteuttaa:
class Ammus { public: Ammus(float x,y,suunta,nopeus); void Liikuta(); int TormaysTarkistus(); void Piirra(); private: float vx, vy; // Nopeusvektori float x,y; // Sijainti // Jne jne }; // Varsinaisessa koodissa sitten vector<Ammus> kudit; kudit.push_back(Ammus(5,2,4.4,2); kudit.push_back(Ammus(2,1,1.34,2); kudit.push_back(Ammus(78,4,6.34,2); // Liikutetaan pateja for (int i=0; i < kudit.size(); i++) { kudit[i].TormaysTarkistus(); kudit[i].Liikuta(); }
Mitä tuossa koodissa tarkoittaa kohdat
kudit.push_back(Ammus(5,2,4.4,2); kudit.push_back(Ammus(2,1,1.34,2); kudit.push_back(Ammus(78,4,6.34,2);
Edit: Meinaako tuo sitä, että tuossa työnetään kaikki data?
Siinä lisätään vektoritaulukkoon(?) nimeltä "kudit" uusia ammuksia.
Jos et osaa käyttää luokkia, suosittelen opettelemaan niiden käytön.
Ja kannattaa opetella myös STL:n juttujen käyttöä, esimerkiksi juuri nuiden vektorien käyttöä.
Heitetään nyt pari linkkiä hassun hauskasta C++-oppaasta
Oliot: http://ftp.funet.fi/index/c opas/oliot.html
Jotain STL:stä http://ftp.funet.fi/index/c opas/stl.html
Lisäksi tämä sivu toimii kätevänä kunhan osaa tarpeeksi (?) http://www.cppreference.com/
Joo, luokat ovat ennestäänkin tuttuja mutta tuo vectroi on minulle täysin uusi...
Eli siis tuo tulisi toetuttaa SDL:ssä vaikka.
if(nappi[SDLK_SPACE]){kudit.push_back(Ammus(Pelaaja1.x,Pelaaja1.y,Pelaaja1.suunta,2);}
Löytyisikö jostain jotain listaa kaikist vectroi komennoista kuten (".size()")? Mitä tuo edes meinaa tuo ("kudit.size();");
Jos i on pienempi kuin kudit.koko i plussataan? Minkä koko? Koko = vectori luokan koko?
FaCo kirjoitti:
Löytyisikö jostain jotain listaa kaikist vectroi komennoista kuten (".size()")?
cppreference.com on aika näpparä referenssi C:n ja C++:n standardikirjastoille.
FaCo kirjoitti:
Mitä tuo edes meinaa tuo ("kudit.size();");
kudit-olion size-metodi.
FaCo kirjoitti:
Jos i on pienempi kuin kudit.koko i plussataan? Minkä koko? Koko = vectori luokan koko?
Kuinka monta kutia siinä vektorissa on sisällä.
Eikös for lopeta suorituksen kunnes i = kudit.size(), eikös tämän taas johda siihen että patejen liikutus/törmäyksentunnistuksen suoritus lakkaa?
Tuohan on vain esimerkki, miten niitä liikutellaan. Tollaisenaan se sitten jonnekin ohjelman päälooppiin laitettais.
jaa niimpä tietenkin, olimpas taas tyhmä. Sitä kun ottaa tämän noobin aseman sitä sattuu kysymään todella tyhmiäkin kysymyksiä :D.
Tarvisisin taas apua. Kun luon uuden panoksen painamalla Spacea, niin asetan ensiksi sille x = Pelaaja1.x ja Pelaaja1.y. Tämän jälkeen padille pitäisi saada täysin oma x ja y, koska muuten se ei lähtisi liikkelle vaan olisi täysin riippuvainen Pelaaja1.x ja y:tä. Eli miten tämä tulisi toteuttaa parhaiten taulukollako? Miten tämä laittaa liikutus funktioon?
Siis tuota??
Jos käytät tuota Heikin tekemää Ammus-luokkaa, niin siellähän on muuttujat "x" ja "y". Tietysti konstruktorin ja muiden metodeiden toteutukset puuttuvat. Vasta ne laittavat panokset liikkeelle.
Elikkäs Elikkäs, tarkoitatko näitä?
private: float vx, vy; // Nopeusvektori float x,y; // Sijainti
luodaanko vai jokaiselle panokselle tuossa täysin yksityinen x ja y sekä nopeus??
Tuo luokka ei tosiaan ole mikään lopullinen, laitoin tuon vain suuntaa-antavaksi vinkiksi.
Tarkoitin että x ja y kertovat ammuksen sijainnin (2D-)koordinaatistossa. Lisäksi vx ja vy ovat padin nopeus (eli liikutettaessa ajetaan komennot x+=vx; y+=vy;).
Tietysti jokaisella ammuksella pitää olla oma paikka ja nopeus, sillä kentällä voi olla samaan aikaan monia ammuksia liikkumassa eri suuntiin eri paikoissa.
Siis eli..Miten tuo nyt tulisi toteutta? Eli tuo kun painetaan ampumis nappia piirretään uusi ammus ja asetetaan sen alku x ja y:ksi pelaajan x ja y tämän jälkeen ammusta alettaisiin liikuttaa...
Lähinnä tarkoitin sellaista systeemiä, että aina kun ammutaan, luodaan uusi ammus-olio Ammus-luokasta:
if (OnPainettuAmpumisNappia()) { Ammus uuskuti (pelaaja.x(), pelaaja.y(), pelaaja.kulma(), PERUS_AMMUKSEN_NOPEUS); ammusvektori.push_back(uuskuti); }
Kulman ja nopeuden perusteella on sitten mahdollista laskea trigonometrialla x- ja y-suuntaiset nopeudet:
vy = sin(kulma)*nopeus; vx = cos(kulma)*nopeus;
Nyt sitten pääsilmukassa voidaan kutsua jokaisella suorituskerralla voidaan ensin liikuttaa ammuksia ja sitten piirtää ne:
for (int i=0; i < ammusvektori.size(); i++) { ammusvektori[i].Liikuta(); ammusvektori[i].PiirraItsesiRuudulle(); }
Selvensikö yhtään?
Tein nopsaan tälläisen kantaluokan ammuksille suurimpaan hätään. Mitään mullistavia juttuja se ei tarjoa, mutta ainakin tekee sen mitä tarvitaan: liikuttaa ja piirtää ammusta. http://koti.mbnet.fi/masa_89/koodit/ammus.h
Käyttö on hyvin yksinkertaista:
#include "SDL.h" // sisällytetään kantaluokka ohjelmaan #include "ammus.h" // luodaan oma ammusluokka periyttäen se kanta::Ammuksesta class Ammus : public kanta::Ammus { public: // luodaan oma konstruktori Ammus(SDL_Surface* mS, float x, float y, float kulma) { Alusta(mS,x,y,kulma); } // voitaisiin luoda omia metodeita, mutta mitäpä tässä // esimerkissä turhia... }; ............. ............. // pääkoodissa ammusta luodessa esimerkiksi: Ammus luoti(padin_kuva, lähtö_x, lähtö_y, kulma); ...... // ja ammuksen päivitys hoituu: luoti.Liikuta(haluttu_arvo); luoti.Piirra(näyttö_pinta); ............. .............
Toivottavasti auttoi edes ensi hätään.
Mitä tämä meinaa?
"(Linker error) undefined reference to 'Ammus::Ammus(int,int,int)'"
Sitä, että olet käyttänyt tuollaista funktiota muttet ole kirjoittanut sen koodia minnekään (ainakaan oikeaan paikkaan, koska se ei siis ole päätynyt linkkerille asti).
Kyllä tietääkseni olen..
class Ammus { public: Ammus(int x,int y ,int nopeus); } //pää koodissa Ammus uuskuti (pelaaja.x, pelaaja.y, pelaaja.kulma,2); ammusvektori.push_back(uuskuti);
No, sinulla on esittely tuolle Ammus::Ammukselle, mutta sinulla ei ole sen runkoa missään.
Eli sinun pitää tehdä johonkin
Ammus::Ammus(int x, int y, int nopeus) { //jotain hassua tähän konstruktoriin }
Muista myös linkittää se mukaan.
Joo kiitos paljon sinulle Mazzimo, mutta haluaisin eka yrittää saada "itse" tämä kehiteltyä jotenkin pystyyn ja jos en onnistui sitten käytän tuota sinun tekelettäsi.
Elikkäs..Nyt olisi sellanen problema, että miten pääsen käsiksi panosten x:ään ja y:hyn ? Tarvitsisin tätä kun teen Liikuta() funktiota.
Menepä lukemaan jotakin opasta, nyt ovat kyseessä sellaiset perusasiat, ettei niitä ole oikein järkeä täällä puida. Google kyllä auttaa sanoilla "C++ tutorial" tai "C++-opas".
Jäseniin pääsee käsiksi pisteen avulla, kuten lukuisissa esimerkeissä tässäkin ketjussa näkyy.
Noh, osaan kyllä ottaa dataa ulos, mutta ei ole mitään havaintoo miten niiten dataa voi muutta jälkeen päin.
Datan ulosotto tapahtuu näin, eikö?
typedef vector<Ammus>::iterator pati_iter; pati_iter da = pati.begin(); cout << *da++ ; }
Öö, nyt on kyllä erittäin monimutkainen systeemi sinulla (eikä tuo edes toimi)
Jos vaikka toteutat oliolle GetX()-metodin, joka palauttaa x-koordinaatin, saat x-koordinaatin koodilla
cout << padit[numero].GetX();
Nytten se valittaa ettei Ammus luokassa ole sen nimistä jäsentä kuin GetX,pitääkö se jotenkin määritelläkkin?
'class Ammus' has no member named 'GetX'
Tietenkin pitää määritellä, ja toteuttaa, jos haluat käyttää sitä.
Ja suosittelen tekemään kuten Metabolix sanoi, eli ota opas, ja harjoittele perusteita.
Kokeilepa vaikka tätä:
http://www.funet.fi/c opas/
Se on vissiinkin jonkin sortin klassikko ja ikävä kyllä myöskin osittain jo vanhentunut, mutta itse pidän siitä silti, sillä asiat on esitetty melko hauskasti(?) ja mielenkiintoisesti ja vieläpä suomeksi. Jonkun aikaa voi lueskellessa mennä, mutta kyllä se kannattaakin. Siitähän voi sitten jatkaa vaikkapa tuolla ylempänäkin mainituun osoitteeseen
http://www.cppreference.com
"Tyvestä puuhun!" sanoo vanha latteuskin.
Mut en vieläkään tajua mitä hittoa teen tiedolla, että mikä on padin x??? Meinaan eikös minun pitäisi justiinsa saada syötettyä dataa x:ään, jotta voisin liikuttaa sitä???
Jos käytät minun tekemää ammusluokkaa kantaluokkana, niin ei tarvitse. Ainoa ammuksen liikuttamiseen ja piirtämiseen tarvittava rivimäärä on:
kuti.Liikuta(0.5f); kuti.Piirra(naytto_pinta);
Tietysti joudut muuttamaan muuttujanimet oikeiksi.
hmm, noh voisinhan minä sitä käyttääkkin :P...Tosin minulla se alkaa vinnettää heti kun includetan kyseisen ammus.h:n koodiin "In file included from main.c"
Tämä kysely menee nyt jo aivan yli. Niin alkeellisia virheitä kuin suinkin. Et ole tainnut minkäänlaista opasta lukea eikä taida olla minkäänlaista käsitystä siitä, miten koko homma toimii. Jonkin verran pitäisi sitä perusideaa pystyä itsekin keksimään, ei ohjelmoinnista tuollaisella menolla tule yhtikäs mitään. Tässä nyt kysellään sellaisia perusasioita, jotka löytyvät jo ties kuinka monesta oppaasta ja kirjasta, eikä tässä tapauksessa ongelmana ole edes se, että ohjelmassa olisi virhe, vaan se, ettei koko ohjelmaa ole olemassakaan! Rajansa kaikella. Otapa nyt kynä ja paperia ja mieti, miten homma toimii, ja katsele sitten jostakin oppaasta, miten sellaisen saa tehtyä, tule kysymään uudestaan, kun on jokin kunnollinen ongelma edessä eikä vain yleistä en-osaa-apua-auttakaa-ongelmaa.
Viimeisessä viestissäsi on vain virheen alku, joka kertoo, missä virhe on: main.c:hen liitetyssä ammus.h:ssa.
Tässä tälläinen minun tekemäni yksinkertainen ammus järjestelmä...
#include <SDL/SDL.h> using namespace std; class Ammukset { public: int x; int y; void Piirra(SDL_Surface *kuva,SDL_Surface *naytto,int x,int y); }; Ammukset padit[99999]; int etu = 0; int taka = 0; void Ammukset::Piirra(SDL_Surface *kuva,SDL_Surface *naytto,int x,int y) { SDL_Rect alue; alue.x = x; alue.y = y; SDL_BlitSurface(kuva,NULL,naytto,&alue); } int main(int argc,char *argv[]) { if(SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL:än alustaminen epäonnistui!",SDL_GetError()); SDL_Quit(); return 0; } SDL_Surface *naytto,*patik; naytto = SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF); patik = SDL_LoadBMP("pati.bmp"); bool pois = false; SDL_Event tapahtuma; Uint8 *nappi; while(pois == false) { SDL_PollEvent(&tapahtuma); nappi = SDL_GetKeyState(NULL); if(tapahtuma.type == SDL_QUIT){SDL_Quit(); return 0;} if(nappi[SDLK_ESCAPE]){SDL_Quit(); return 0;} if(nappi[SDLK_SPACE]){etu++;} if(taka < etu) { padit[taka].x = 50; taka++; } if(taka >= etu) { for(int i = 0;i < etu;i++) { padit[i].y++; SDL_FillRect(naytto,NULL,0); padit[i].Piirra(patik,naytto,padit[i].x,padit[i].y); } } SDL_Flip(naytto); } SDL_FreeSurface(patik); SDL_Quit(); return 0; }
Ööh, tuosta on todella vaikea saada selvää, joten suosittelen että sisennät koodiasi.
Eihän tuo edes toimi? aina kun painetaan SPACE nappia vanha pati häviää ruudusta...
Hoops...Taisin laittaa vanhan version, eli sen joka ei toimi :) SORI!..
Aihe on jo aika vanha, joten et voi enää vastata siihen.