On muuten hyvä tapa tuo, että siirtää peli tiedostoja funktioihin, nimittäin itsekkin huomasin, että paljon yksinkertaisempaa.
Nyt on kuitenkin jo puolisen tuntia mennyt arvokasta koodaus aikaa, kun tulee erroria. SDL_Mixeriä käyttäessäni.
Syyliset:
int Mix_PlayChannel(int kanava, Mix_Chunk *aani, int toistokerrat); void AlkuValikko(void) { if(Mix_PlayChannel(0, aani, 1)==-1) fprintf(stderr, "Virhe : %s ", Mix_GetError()); }
Tuo aani on jo alustettu, mutta sitä en jaksanut heittää tähä. :)
Errori:
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\war in world\war in world\main.cpp(77) : error C2059: syntax error : '-'
Ps. Kiitos kärsivällisyydestänne jaksaa opastaa, mutta vihdoin tajusin hieman Kirjastoita sun muita ja uskoisin, että kysymykset vähenevät. ;)
Onko tuo varmasti oikea rivi? Minusta siinä ei ole mitään vikaa. On tietysti mahdollista, että olet onnistunut tekemään vääränlaisen viivan (esim. jonkin hienon typografisen viivan), joten kokeilepa pyyhkiä se ja kirjoittaa uudestaan.
mika132 kirjoitti:
On muuten hyvä tapa tuo, että siirtää peli tiedostoja funktioihin, nimittäin itsekkin huomasin, että paljon yksinkertaisempaa.
Olet ymmärtänyt aivan väärin. Kuuluisi siirtää funktioita toisiin tiedostoihin, ei toisin päin. Jokaisen funktion pitää kokonaisuudessaan sijaita samassa tiedostossa, ja yhtäkään cpp-tiedostoa ei pidä liittää includella.
mika132 kirjoitti:
uskoisin, että kysymykset vähenevät
Tämän kysymyksen taso ei minusta viittaa lainkaan siihen suuntaan. Syntaksivirheet ovat virheistä yksinkertaisimpia, ne pitäisi ehdottomasti osata etsiä itse.
Juu yritin itsekkin tuota, kun luulin, että siinä oli jokin eri viiva, mikä näytti samalta, mutta ei ollut. Heittää edelleen samaa erroria ja errori rivi on:
int Mix_PlayChannel(int kanava, Mix_Chunk *aani, int toistokerrat);
Ei voi olla, eihän tuossa edes ole viivaa. Ja ilmeisesti et ole niistä kirjastoistakaan vielä ymmärtänyt mitään, nimittäin ohjelmassasi ei edes pitäisi olla tuollaista riviä.
Oletko siis kirjoittanut tarkalleen noin tuonne koodiin? Sen pitäisi aiheuttaa tupladeklaraatiovirhe, koska SDL_mixer määrittelee tarkasti tuon nimisen ja noilla argumenteilla olevan funktion. Toivon, että tajusin vain väärin tuon koodirivisi merkityksen.
Teuro kirjoitti:
Sen pitäisi aiheuttaa tupladeklaraatiovirhe
Itse asiassa ei, koska vastaavia esittelyjä saa olla useita. Virhe tulee vain, jos esittelyt ovat ristiriidassa.
Tuota opasta katselin ja luin ja tein mikä ohjelmointiputkassa oli ja siellä sanottiin, että tuolla rivillä soitetaan ääntä? :O
Juu siis samasta esittelystä saa kirjoittaa vain yhden määrittelyn, mutta samanlaisia esittelyjä saa olla useita.
mika132 kirjoitti:
Siellä [oppaassa] sanottiin, että tuolla rivillä soitetaan ääntä
Ei sanota. Lue paremmin. Siinä sanotaan, että kyseisen funktion esittely on tällainen. Et myöskään ole ilmeisesti ymmärtänyt kovinkaan paljon C++-oppaan funktioista ja esittelyistä, kun edes tuollaista voit luulla.
Olen lukenut kummatkin, mutta tuolla esittelyssä puhutaan vain floatista ei int:stä.
Arvaa kaksi kertaa, toimivatko esittelyt eri tyyppien kanssa samalla vai eri tavalla.
C++ ei selvästi ole sinulle sopiva kieli, koska et näköjään osaa ollenkaan yleistää ja soveltaa asioita.
Ihme, että olet edes onnistunut tekemään funktion nimeltä AlkuValikko, eihän missään oppaassa kerrota siitäkään mitään.
Funktioiden tekeminen on tullut muista kielistä minulle.
Antaa sen mixeri systeemin olla nyt toistaiseksi.
Tiedän miten hahmoa liikutetaan, mutta en tiedä miten sen saa katsomaan kohti hiirtä:
Yrityksiä:
Tämä ei edes kääntänyt yhtä astetta hahmoa.
int hiiren_x, hiiren_y; hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y); temp = rotozoomSurface(hahmo, hiiri, 2, 1);
Tämä käänsi, mutta ylhäältä alas tullessa hahmo pyöri väärään suuntaan (luonnollisesti, kun se katsoo kulman hiiren_x:stä)
int hiiren_x, hiiren_y; hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y); temp = rotozoomSurface(hahmo, hiiren_x, 2, 1);
Tämäkään ei kääntänyt hahmoa edes sitä yhtä astetta.
int hiiren_x, hiiren_y; hiiri=SDL_GetMouseState(&hiiren_x && hiiren_y,&hiiren_y); temp = rotozoomSurface(hahmo, hiiren_x, 2, 1);
E:
Koitin myös:
temp = rotozoomSurface(hahmo, hiiren_x, 1, 1); temp = rotozoomSurface(hahmo, hiiren_y, 1, 1);
mutta nyt ukkeli pyöri joka suuntaan samaan aikaan. :O
Kysymyksiä (opettelua varten):
1. Mitä SDL_GetMouseState-funktion parametrit ovat tyypiltään?
2. Mitä rotozoomSurface-funktion eri parametrit ilmoittavat?
3. Mitä muuttuja hiiri sisältää?
4. Miksi se on väärä muuttuja rotozoomSurface-funktion parametriksi?
5. Mitä muuttuja hiiren_x sisältää?
6. Miksi se on väärä muuttuja rotozoomSurface-funktion parametriksi?
7. Mitä muuttuja hiiren_y sisältää?
8. Miksi se on väärä muuttuja rotozoomSurface-funktion parametriksi?
9. Miten lasketaan koordinaattien perusteella jokin tässä mielekäs kulma?
10. Voiko kulman laskea pelkästään hiiren sijainnin perusteella?
11. Mitä muuta laskuun sitten tarvitaan kuin hiiren sijainti?
12. Mikä pinta sisältää pyöritetyn kuvan?
13. Mitä tapahtuu, jos kuvaa pyöritetään useasti eikä luotuja pintoja vapauteta?
14. Mitä temp-pinnalle pitää siis tehdä, kun se on piirretty ruudulle?
Lue matematiikkaoppaasta lisää kulmista ja kolmioista. Tarvitset sellaista matematiikkaa, ettei sitä kai peruskoulussa nykyään opeteta.
Edit: eiku vähä muistin väärin, siis kulmat saa atan2...
11. Mitä muuta laskuun sitten tarvitaan kuin hiiren sijainti?
ja tästä en ole varma alapuolella vastaus:
12. Mikä pinta sisältää pyöritetyn kuvan?
Temp.
Tuo oli ainoa johon en osannut vastata, joten voisitko auttaa.
Hienoa. Voisit yrittää ihan itsekin harrastaa samanlaista päättelyä, nimittäin on silkkaa tyhmyyttä kokeilla sattumanvaraisesti eri muuttujia funktion parametreiksi, jos tietää, että ne ovat vääriä.
Hiiri on ikkunassa kohdassa (36, 93). Mikä on oikea kulma? Mieti asiaa kynän ja paperin kanssa.
1. Piirrä tilanne.
2. Merkitse kuvaan kulma, jonka suuruus pitäisi selvittää.
3. Muodosta kulman jatkoksi kolmio, jossa on sekä vaakasuora että pystysuora sivu.
4. Laske kolmion vaakasuoran ja pystysuoran sivun pituus.
5. #include <cmath>
6. kulma = std::atan2(pystysivu, vaakasivu)
Aiempaan sarjaan jatkokysymys:
15. Mitä tapahtuu viimeisessä koodissasi, jossa on kaksi pyöritystä peräkkäin?
3. Muodosta kulman jatkoksi kolmio, jossa on sekä vaakasuora että pystysuora sivu.
Tuota piirrosta en ihan ymmärtänyt. Voisitko hieman selventää?
Oletko saanut jonkinlaisen kulman aikaan? Missä kulman kärki on ja minnepäin sen kyljet menevät? Toinen kulman kyljistä on toivottavasti pystysuora tai vaakasuora, joten piirrä kulman poikki vielä kolmas viiva (pystysuora tai vaakasuora) niin, että muodostuu kolmio. Piirrä se viiva järkevään kohtaan, jotta saat jotenkin laskettua kolmion sivujen pituudet.
Luulisin, että Metabolix tarkoittaa kohdassa 2, että pitäisi piirtää jana, eikä kulma. Tai ainakaan minä en keksi mitä hyötyä on piirtää yksi kolmio, jonka muut sivut on koordinaatiston suuntaisia. Toki kahden sellaisen kolmion piirtämisellähän sen kulman voisi laskea...
Muutenkin kohdassa 1 puhutaan hiiren (yksistä) koordinaateista, mutta janan piirtämiseen tarvittaisiin kahdet koordinaatit ja kulman piirtämiseen kolmet....
Edit: Jah, Metabolix ehtikin tuohon väliin vastaamaan.
Grez kirjoitti:
Luulisin, että Metabolix tarkoittaa kohdassa 2, että pitäisi piirtää jana, eikä kulma.
Kyllä ihan kulmaa tarkoitan. Kulman yksi sivu on siis se, minne päin hahmo pitäisi saada katsomaan, ja toinen taas se, mihin hahmo perustilassa katsoo.
Ja siinähän se paljastuikin. :( Oli tarkoitus saada kysyjä itse tajuamaan, että hahmo on se toinen olennainen asia tässä laskussa. Kyseessä on siinä määrin perustavanlaatuinen asia peliohjelmoinnissa, että ei ilman tuon tasoista ajattelua voi minusta kuvitellakaan saavansa mitään aikaan.
No, silloin mielestäni ei riitä välttämättä yhden koordinaatistokylkisen kolmion piirtäminen.
Edit: Tietysti hyvä pyrkiä herättelemään omaa ajattelua, mutta minusta tuo monivaiheinen opastus johti jossain 3-kohdassa jo harhaan..
Tuossa yläpuolella on tämän hetken kuva.
Voisiko tuohon vähän saada lisäselvennystä..?
Eli siinä on harmaa kolmio. Mitä se esittää?
Sitten siinä on punainen 35° kulma, musta avaimenreikä oikealla. Mitä nämä esittää?
Tarkoittaako koordinaatit punaisen kulman kärkeä vai sitä harmata kolmiota?
Sitten on teksti 90° kääntymisestä. Mihin se liittyy?
Mietin vähän ja tulin tulokseen, että harmaa kolmio esittää hiiren kursoria ja koordinaatit on sen koordinaatit. Muut jutut kuviosta jäi edelleen arvoitukseksi.
Harmaa kolmio = hiiri
Kulma kuvaa sitä mihin käännytään ja musta avainmenreikä on nopeasti piirretty hahmo. 90 asteen kääntyminen on se, että paljonko hahmon pitää tuossa tilanteessa kääntyä.
Selvennän:
2. Piirrä kulma, jossa yksi sivu osoittaa hahmon alkuperäisen suunnan ja toinen halutun suunnan.
Loput ohjeet ovat entisellään.
Jos hahmon perussuunta on jommankumman koordinaattiakselin suuntainen, yksi kolmio riittää. Muuten laskettavaa on kaksinkertaisesti.
Eli katsotaan ymmärsinkö nyt oikein:
Älkää välittökä siitä 90 astetta kääntymistä sillä siinä pitäisi olla 180, mutta unohdin kummata sen pois. Alempana on kuitenkin tuo selitettynä.
Valitse mieluiten jokin muu tapaus kuin 90 tai 180 astetta, koska niistä on vaikea piirtää selkeää kuvaa. Esimerkiksi 120 astetta on paljon parempi.
Piirrä kaksi pitkää viiva, jotka kulkevat kuvan laidasta laitaan hahmon keskikohdan poikki. (Hahmon koolla ja muodolla ei ole tässä väliä, joten suosittelen pienempää hahmoa.) Piirrä molempiin viivoihin yhteen päähän nuolenkärki. Viivoista toisen pitää osoittaa sinne, minne hahmo katsoo, ja toisen sinne, minne hahmon pitäisi katsoa. Kuvaan muodostuu jonkinlainen X-kirjain. Tästä varmaan onnistut muodostamaan sen pyydetyn kolmion yhdellä pysty- tai vaakaviivalla.
(Onko koulussa vielä opetettu geometriaa? Tiedätkö esimerkiksi, mitä ovat vieruskulmat ja ristikulmat? Jos et tiedä, kannattaa ehdottomasti ottaa selvää.)
Piirtelin tässä vaihtoehtoisen havainnekuvan..
Tässä voi sitten arvailla mihin niitä viivoja voi piirrellä :D
http://grez.info/putka/mika132/koord.gif
Esimerkkikuvassani pelihahmon silmän pupilli on siis koordinaateissa (50,17) ja hiiren kursori koordinaateissa (555,157) (Käytössä tietokonetyylinen koordinaatisto, jossa origo ylävasemmalla)
Silmää on siis tuossa tapauksessa käännetty 15,49 astetta myötäpäivään.. (Ihan vaan jos haluaa tarkistaa sitten kun keksii laskukaavan)
Matikka oli vahvin alani koulussa sain jopa kasin, olisi ollut mahdollisuus ysiin jos olisin tehnyt kotitehtävät, mutta päässyt hieman aivot ruostumaan. :P
Ihan mielenkiinnosta, mistä/miten laskit 120° kun hahmon koordinaatit on (230,363) ja hiiren (36,93) ?
Itse laskisin vastaavassa tilanteessa 125,7°
laskin sen niin, että käänsin ukon 120 asteen kulmaan piirsin suoran janan. Käänsin hahmon takaisin asteeseen 0 ja kummasin vanhan viivan ja vedin tilalle tuon toisen viivan. =)
Onko piirrustus edelleen väärin?
Ei kun mua vaan kiinnosti tietää, miten laskit 120°... Siis käsittääkseni halusit laskea paljonko ukkoa pitäisi kääntää, eikä sitä missä kursorin pitäisi olla jos ukkoa käännettäisiin 120°...
Mutta siis joo, kuvahan on sinänsä ihan järkevä, mutta luulin tuon 120° olevan laskun tulos.. Siihen voisi laittaa kysymysmerkin tilalle, kun se ei ole valmiiksi tiedossa vaan se pitäisi selvittää.
Ai. Ajattelin, että pitää katsoa, jos kuvan asento on 0 ja hiiri laitetaan koodinaatteihin 36, 93 se kääntää kuvaa 120 astetta, mutta ilmeisesti tein väärin. Ja tähän väliin huomasin, että hiiren koodinaatit ovat väärin minulla. Oikeat koodinaatit:
28,80
Well, koordinaateilla (230,363) ja (28,80) saisin tulokseksi 125,5°
Mutta siis, haluatko nyt laskea
a) missä hiiren pitää olla, että ukko kääntyy g astetta
vai
b) paljonko ukon pitää kääntyä jos hiiri on koordinaateissa (x,y)
?
Siis haluan laskea, miten saan ukon kulman pelissäni seuraamaan hiirtä ja sain vain tietää, että noilla piirustuksilla se lasketaan jollain tavalla.
Taidan tietää jo miten saan sen tietääkin.
Miten lasket astemäärän katsoessasi hahmon sijainnin ja hiiren sijainnin. Sen tuloksen laitan muuttujaan kulma ja se laitetaa rotozoom funktioon kulmaksi. Kerrotko mikä matemaattinen laskutoimitus tuohon suoritetaan?
Ja vastaus kysymykseesi:
b) paljonko ukon pitää kääntyä asteina jos hiiri on koordinaateissa (x,y)
Korjailin vähän kuvaa ja lisäsin suunnan laskemisen kannalta mielestäni olennaiset viivat siihen (ne ohuet punaiset)
http://grez.info/putka/mika132/koord2.gif
mika132 kirjoitti:
Miten lasket astemäärän katsoessasi hahmon sijainnin ja hiiren sijainnin. Sen tuloksen laitan muuttujaan kulma ja se laitetaa rotozoom funktioon kulmaksi. Kerrotko mikä matemaattinen laskutoimitus tuohon suoritetaan?
Metabolix kirjoitti:
6. kulma = std::atan2(pystysivu, vaakasivu)
Aaaaa. :P
Seli oli noin helppo juttu.
Mutta:
kulma = std::atan2(282, 200)
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\war in world\war in world\main.cpp(180) : error C2668: 'atan2' : ambiguous call to overloaded function
1> c:\program files\microsoft visual studio 9.0\vc\include\math.h(547): could be 'long double atan2(long double,long double)'
1> c:\program files\microsoft visual studio 9.0\vc\include\math.h(499): or 'float atan2(float,float)'
1> c:\program files\microsoft visual studio 9.0\vc\include\math.h(110): or 'double atan2(double,double)'
Tuohan ihan selvällä perusenglannilla kertoo mikä on ongelma.
Btw, mikä toi kulma muuttuja on tyypiltään? Ja huomaathan, että toi palauttaa vastauksen radiaaneina eikä asteina.
Juu, mutta en ymmärtänyt miten tuo muka ylikurmittuu. :)
Ylikuormitettu funktio tarkoittaa, että samalle funktionimelle on määritelty useita erilaisia parametrilistoja ja kääntäjä päättelee annettujen parametrien määrästä ja tyypistä, mitä niistä halutaan käyttää.
Ja miten tämä korjataan, kun ei ole aikaisemmin tullut vastaan, koska en löytänyt mitään kahta samallaista. :O
No sun pitää olla yksiselitteisempi. Eli siis sehän sanoi sulle että "sä et nyt kerro mitä tarkalleen ottaen haluat tehdä, kun tää sun pyyntö voi tarkoittaa kolmea eri asiaa". Sitten se vielä kertoi sulle ystävällisesti mitkä ne vaihtoedot on.
Eli yksi vaihtoehto on antaa sille kaksi long doublea, jolloin se palauttaa long doublen.
Toinen vaihtoehto on antaa sille kaksi floattia, jolloin se palauttaa floatin.
Kolmas vaihtoehto on antaa sille kaksi doublea, jolloin se palauttaa doublen.
Nyt annoit sille kaksi intiä ja intinhän voi kastata miksi vaan noista.
Eli kerro sille mitä tyyppiä noi sun antamat parametrit on.
Juu, mutta jos laitan siihen:
kulma = std::atan2(long 282, long 200);
Tai
kulma = std::atan2(double 282, double 200);
Tulee nämä errorit:
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\war in world\war in world\main.cpp(180) : error C2144: syntax error : 'long' should be preceded by ')'
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\war in world\war in world\main.cpp(180) : error C2661: 'atan2' : no overloaded function takes 0 arguments
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\war in world\war in world\main.cpp(180) : error C2059: syntax error : ')'
ja merkit ) on? ja tuota keskimmäistä en ymmärrä, kun puhutaan argumenteista.
Merkki ) on kiinni menevä sulku. C++:ssä castaus toiseen muuttujatyyppiin tapahtuu laittamalla haluttu tyyppi suluissa ennen muuttujaa tai vakiota. Eli esim: (double)muuttuja
Mun mielestä hieman huolestuttava tyyli koodata näin niinkuin merkki kerrallaan kyselemällä. C/C++ oppaita kuitenkin löytyy netistäkin vaikka kuinka. Eli jotain perusasioita voisi kyllä itsekin selvitellä.
Juu, mutta ei löytynyt mitään tähän liittyen kun etsein tai sitten väärä hakusana. Nyt toimii, mutta hahmo ei pyöri:
int hiiren_x, hiiren_y; hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y); kulma = std::atan2((float)282, (float)200); temp = rotozoomSurface(hahmo, kulma, 1, 1); PiirraKuva(temp, naytto, hahmo_sijainti_x, hahmo_sijainti_y); SDL_FreeSurface(temp);//tämä oli flipin kummallakin puolella ja myös kokonaan pois koodista SDL_Flip(naytto);
Teen luultavasti vieläkin jotain pahasti väärin?
No sen verran voisin ainakin sanoa, että rotozoomSurface ottaa angle -parametrin asteina ja atan2 palauttaa sen radiaaneina (kuten aikaisemmin mainitsikin). Eli jos hahmo ei käänny tippaakaan niin sitten en äkkiseltään osaa sanoa mikä on vikana, mutta jos se kääntyilee vähän, niin veikkaan tuota väärää skaalaa.
Ei käänny ei ede spientä milli suurensin kuvan 8 kertaiseksi, jotta näkisin liikahtaako jokin pikseli, mutta ei.
Kääntyykö se jos kirjoitat tuohon rotozoomSurface kutsuun kulma tilalle vaikkapa 30 ?
Jos ei käänny niin vika on varmaankin rotozoomSurface kutsussa tai sen jälkeen.
Jos kääntyy, niin vika voisi olla esimerkiksi kulman tietotyypissä (kysyin sitä tuossa 10 viestiä sitten, mutta et vastannut)
Eiköhän siinä ole vikana, että atan2-funktion parametreina on valmiit luvut eikä niitä kolmion oikeita sivuja (jotka tietenkin muuttuvat hiiren ja hahmon sijaintien mukaan). Ja kuten yritin jo pitkään selittää, oikea arvo ei myöskään ole vain hiiren x-koordinaatti tai y-koordinaatti tai edes näistä laskettu kulma, vaan kulman laskemiseen tarvitaan myös hahmon sijaintia.
Kai muuttujasi ovat varmasti liukulukuja (float tai double)? Toinen ihan näkyvä vika on, kuten Grez jo mainitsi, tuo kulman yksikkö, joka on atan2-funktion jäljiltä radiaani. Kulman voi muuttaa asteiksi seuraavalla kaavalla:
asteet = 180 * radiaanit / pii
mika132 kirjoitti:
ei löytynyt mitään tähän [tyypin muuttamiseen] liittyen
C++-opas kirjoitti:
Joskus on tarpeen muuttaa luvun tyyppiä kesken laskulausekkeen. Merkinnät
(tyyppi) muuttuja
jatyyppi(muuttuja)
muuttavat muuttujan arvon määrättyyn tyyppiin. Itse muuttuja ei muutu miksikään, vaan kyseessä on yhtä irrallinen laskutoimitus kuin vaikkapa yhteenlasku.
Jos kerran C++:aa kirjoitetaan, niin tehdään ne tyyppimuunnoksetkin sitten C++:lla.
(uusi_tyyppi)muunnettava on C-kielen tyyppimuunnos, jota toki C++ yhteensopivuussyistä edelleen tukee. Käytännössä tuo c-kielen tapa vastannee c++:n reinterpret_castia.
C++:lla muunnoksen voit tehdä näin:
static_cast<double>(500)
Eli jos vaikka hahmon sijainti on {200, 100}, ja hiiri on pisteessä {60, 80}. Mikä luku annetaan tuolle rotozoomSurface funktiolle? Kulman laskemiseen tarvitaan kaksi janaa, joiden välinen kulma on haluttu tieto.
#include <iostream> #include <cmath> double rad2deg(double rad){ return ((rad * 180) / 3.1415927); } struct olio{ int x; int y; }; int main(){ olio otus = {200, 100}; int hiiri_x = 60; int hiiri_y = 80; int x_jana = (hiiri_x - otus.x); /* (60 - 200) = -40 */ int y_jana = (hiiri_y - otus.y); /* (80 - 100) = -20 */ /* Kulma saadaan tan funktiolla */ double kulma = std::atan2((double)x_jana, (double)y_jana); std::cout << "Kulma = " << kulma << " rad" << std::endl; std::cout << "Kulma = " << rad2deg(kulma) << " astetta" << std::endl; return EXIT_SUCCESS; }
Teuro kirjoitti:
Kulman laskemiseen tarvitaan kaksi janaa
Mikäs tossa sun esimerkissä muuten on se toinen jana?
Kahden pisteen välinen kulma siis yksi jana
Nyt mä oon kyllä vahvasti eri mieltä. Pelkän kahden pisteen välille ei voida muodostaa kulmaa.
Sinänsähän jos haluttaisiin laskea kahden suunnan virittämän kulman suuruus, niin tarvittaisiin ne kaksi suuntaa. Tällöin voitaisiin laskea atan2 molemmista suunnista ja vähentäät toinen toisesta. Jos toinen suunta on suoraan ylös, josta saataisiin nolla atan2:lla, niin se voidaan jättää huomiotta.
Toinen puolisuora (ei jana) on tietenkin se, jonka kulma on nolla, eli yleensä x-akseli. Sitä ei tarvitse erikseen mainita, vaan trigonometristen funktioiden kanssa se tulee automaattisesti mukaan.
Torgo kirjoitti:
Jos kerran C++:aa kirjoitetaan, niin tehdään ne tyyppimuunnoksetkin sitten C++:lla.
Tuo on aika hassusti sanottu, kun C++:n standardi kuitenkin esittelee kaikki tavat eikä mitenkään ilmaise, että yksi olisi toista huonompi. Ne ovat siis kaikki yhtä lailla C++:aa, vaikka vanhojen tapojen rinnalle on tullut rajoittavampia vaihtoehtoja, jotka pyrkivät estämään tyhmiä muunnoksia, jotka yleensä johtaisivat vain ohjelman kaatumiseen. Ymmärrän hyvin näiden käytön esimerkiksi virtuaalisen moniperinnän yhteydessä, mutta luvuille perinteiset muunnokset sopivat aivan hyvin ja ovat minusta selkeämpiäkin.
Tyypinmuunnosmerkintä (T)x
tekee saman muunnoksen kuin operaattori reinterpret_cast, static_cast tai const_cast. Funktiomainen merkintätapa T(x)
taas periaatteessa luo väliaikaisen T-tyyppisen muuttujan, tosin lukujen kanssa periaate on usein aika kaukana käytännöstä, jos kääntäjä optimoi järkevästi.
Metabolix kirjoitti:
Toinen suora on tietenkin se, jonka kulma on nolla, eli yleensä x-akseli.
Miksi minusta, jos käytetään ihan funktion määrittelyn mukaisessa järjestyksessä atan2(dx,dy) noita koordinaatteja, niin nollasuunnaksi tulee y-akseli (ylös, jos koordinaatit kasvaa ylöspäin)
Muutenkin sanoisin, että suora, jonka "suunta" on .. Toisaalta suorallakin on aina kaksi (vastakkaista) suuntaa.
Grez: niin siitä tuleekin 0-akseliksi y-suunta. Ihan niinkuin tuosta esimerkistä nähdään kulmaksi tulee -98 astetta (noin). Kuvan piirtämällä selviää, että kohde on hiirestä oikealle ja alas. Tässä mielessä täysin mielekäs tulos.
No tämänpäiväisillä kommenteilla en ole hakenutkaan vastauksia kysymyksiini, vaan yrittänyt saada ihmiset huomaamaan miten (joltakin osin) puuta heinää tuli kirjoitettua.
Ja kyllähän tuon atan2:n saa antamaan suoraan nollasuunnan oikealle, jos vaan antaa sille koordinaatit "käännettynä" eli tyyliin atan2(-dy,dx) Ja tuokin miinus (vai plus) riippuu siitä, kumpaan suuntaan y-akseli osoittaa (matematiikassa ylös, tietokoneissa usein alas) Kannattaa myös huomata, että toisessa tapauksessa suunta kiertyy myötäpäivään ja toisessa vastapäivään.
Tuossa esimerkiksi kun kirjoitin:
lainaus:
Mikäs tossa sun esimerkissä muuten on se toinen jana?
Niin siihenhän tulikin vastaus tuossa myöhemmin (eli ylös), vaikka se ensimmäinen vastaus olikin taas puuta heinää). Jos ihan tarkkoja termeistä ollaan, niin ei ole ihan perusteltua puhua janoista, koska jana voi yhtä hyvin osoittaa kumpaan vaan suuntaan. Itse puhuisin mielelläni vektoreista, mutta ymmärrän kyllä, että janat opetetaan ennen vektoreita. Vektorihan on ikäänkuin jana, jossa on toisessa päässä nuoli. Eli sillä on yksiselitteinen suunta. (Tosin sillä ei ole yksiselitteistä alkupistettä, mutta voimme sijoittaa sen haluamaamme alkupisteeseen, jolloin sen pitäisi osoittaa haluamaamme kohteeseen)
Toki kahden janan tai suoran välinen kulma voidaan ilmoittaa, mutta vakiintuneen käytännön mukaan se on [0,180[ ° ei [180,360[ °
Samasta syystä käytämme atan2-funktiota, joka osaa palauttaa suunnan välillä [0,360[ °, kun perus arkustangentti palauttaa vain [0,90[ , ]90,180[ °
Grez, funktion määrittelyssä ne ovat kylläkin järjestyksessä atan2(y, x), jolloin varmaan sinustakin nollasuunta on x-akselin suuntaan (oikealle), kuten matematiikassa on tapana. Jos matemaattisella linjalla jatketaan, niin y-akselin suuntaan (ylös) on 90 astetta, vasemmalle 180 ja alas 270.
Kannattaa muuten opetella käyttämään matematiikassa yleisempää oikeakätistä koordinaatistoa, jossa x kasvaa oikealle ja y kasvaa ylös. Useimmat oppaissa ja muualla esitettävät kaavat olettavat näin, ja väärin päin samat kaavat eivät toimikaan. Peilauksen ylösalaisin voi tehdä yleensä aika helposti piirtovaiheessa, jos tarvitsee. (Esimerkiksi OpenGL:llä ei edes tarvitse.)
Ok, niinpäs näkyy olevan. Hyvä korjaus.
Katsoin Teuron esimerkkikoodia ja lisäksi onnistuin googlettamaan jonkin sivun, jossa se oli määritelty toisin päin. Hmm, täytyykin katsoa löytäisinkö sen, niin voisi pistää palautetta.
Eli saisinko suomenkielisen vastauksen siihen miksi koodi ei toimi:
int hiiren_x, hiiren_y; hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y); kulma = std::atan2((float)282, (float)200); temp = rotozoomSurface(hahmo, kulma, 5, 1); PiirraKuva(temp, naytto, hahmo_sijainti_x, hahmo_sijainti_y); SDL_FreeSurface(temp); // tämä oli flipin kummallakin puolella ja välillä poissa. SDL_Flip(naytto);
Eli laitoin kulma kohdan tilalle rotozoomSurfacessa 30 ja hahmo kääntyi 30 astetta, mutta kun laitoin takaisin tuon kulma muuttujan se ei käänny mihinkään. Ja 5 kertainen zoomi o sitä varten, että näin pikseleiden liikkumisen jos sitä sattu tapahtumaan.
Olet saanut jo monta suomenkielistä vastausta. Toistetaan nyt vielä uudestaan:
1. Vaihda kulma-muuttuja liukuluvuksi, jos se ei ole jo.
2. Muuta atan2-funktion palauttama kulma radiaaneista asteiksi.
3. Laske kulma oikeista luvuista. 282 ja 200 ovat oikeat aika harvoin.
Et ole noudattanut ohjeita etkä ilmeisesti ymmärrä oppaista tai neuvoista mitään. Taas ollaan samassa tilanteessa kuin ennenkin. Yrität tehdä jotain, mutta et ymmärrä itse ollenkaan, mistä on kyse. Et myöskään ymmärrä C++:n ja matematiikan perusasioita, ja sen sijaan, että opettelisit niitä kunnolla, yrität vain tehdä sitä projektiasi. Kaiken kukkuraksi väität, ettet ole saanut kunnollisia ohjeita, kun taas on kyse vain siitä, ettet yksinkertaisesti ymmärrä, koska pohjatietosi eivät riitä. Tuolla asenteella et pääse ikinä eteenpäin.
2. Muuta atan2-funktion palauttama kulma radiaaneista asteiksi.
3. Laske kulma oikeista luvuista. 282 ja 200 ovat oikeat aika harvoin.
Noita en ymmärtänyt? Ja jos oikein muistan eikö ikuluku ole:
float kulma=0;
2. Ota matematiikkaopas käteen ja etsi kohta, jossa puhutaan asteista ja radiaaneista. Jos et kykene itse opettelemaan tarpeeksi matematiikkaa kulmien laskemiseen, ei valitettavasti auta kuin odottaa, että koulussa (lukiossa) käsitellään nämä.
3. Koodissasi annat atan2-funktiolle aina luvut 282 ja 200. Mitä tekemistä näillä on hiiren sijainnin ja hahmon sijainnin kanssa?
float on liukuluku. Mitä osaa et tuosta 2. ohjeesta ymmärrä? tässä keskustelussa on mainittu jo useampaan otteeseen se, että atan2() palauttaa kulman radiaaneina ja rotozoom ottaa parametrina kulman asteina!!!
Juu juu, mutta tuleeko radiaani muuttuja tässä kohtaa automaattisesti vai pitääkö sekin jollakin tavalla määrittää (int radiaani=0)
float rad2deg(float rad){ return ((rad * 180) / 3.1415927); } float kulma=0; kulma = atan2(xxxxxxx); rotozoom(hahmo, rad2deg(kulma),xx,xx);
Löi muutamia erroreita eteen joista kolme sain pois ja jäljellä on:
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\war in world\war in world\main.cpp(175) : error C2601: 'rad2deg' : local function definitions are illegal
1> c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\war in world\war in world\main.cpp(170): this line contains a '{' which has not yet been matched
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\war in world\war in world\main.cpp(179) : error C3861: 'rotozoom': identifier not found
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\war in world\war in world\main.cpp(176) : warning C4244: 'return' : conversion from 'double' to 'float', possible loss of data
1
Enkä näe itse koodi riveissä mitään.
if (huone==2) { //yksi errori rivi int hiiren_x, hiiren_y; hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y); float rad2deg(float rad) { return ((rad * 180) / 3.1415927); //yksi errori rivi } kulma = std::atan2((float)282, (float)200); temp = rotozoom(hahmo, rad2deg(kulma), 1, 1); //yksi errori rivi PiirraKuva(temp, naytto, hahmo_sijainti_x, hahmo_sijainti_y); SDL_FreeSurface(temp); SDL_Flip(naytto); if (button[SDLK_w]) { hahmo_sijainti_x=hahmo_sijainti_x+1; } }
No mitäs jos et määrittelis tuota rad2deg() funktiota toisen funktion sisällä?
Edit: ja se funktio on rotozoomSurface eikä rotozoom, kirjoitin noin vain esimerkiksi.
edit eli:
float rad2deg(xxxxx); int main(xxx) { xxxx rad2deg(kulma); } float rad2deg(xxxxx) { xxxx }
Yksi errori enää, kun hieman vilkaisin koodia läpi sain kaksi pois, mutta tätä yhtä en saa.
1>c:\documents and settings\mika.koti-8fec3c6ef1\omat tiedostot\visual studio 2008\projects\war in world\war in world\main.cpp(175) : error C2065: 'rad' : undeclared identifier
Ja viittaa riville:
return ((rad* 180) / 3.1415927);
kaikki tuohon liittyvät koodit:
float rad2deg(float rad); int hiiren_x, hiiren_y; hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y); kulma = std::atan2((float)282, (float)200); return ((rad* 180) / 3.1415927); temp = rotozoomSurface(hahmo, rad2deg(kulma), 1, 1); PiirraKuva(temp, naytto, hahmo_sijainti_x, hahmo_sijainti_y); SDL_FreeSurface(temp); SDL_Flip(naytto);
no voiha nyt h******!!!!
Miks et voi kattoo tosta mun ylemmäst viestistä, että miten sen funktion pitää olla? taitaa tosiaan olla liian vaikee kieli tää c++ sulle, jos et kerta yhtä funktiota osaa tehdä.
Olet ehkä toivottomin tapaus, jonka olen täällä viiden vuoden aikana nähnyt. Eiköhän palata asiaan joskus vuoden tai parin päästä – sitä ennen voisit vähitellen yrittää ymmärtää jotain muuttujista (esim. miksei se radiaanit-muuttuja tule itsekseen ja miten kyseisen laskulausekkeen edes voisi toteuttaa) ja funktioista (esim. mitä return-lause tekee ja miksei tuo ole oikea paikka sille). Voisit myös noudattaa neuvoja ja pitää näppisi erossa grafiikasta ja äänistä ja muista erikoisaiheista, kunnes olet oppinut muuttujat, ehdot, silmukat, funktiot ja osoittimet kunnolla.
Tässä alla pieni esimerkikoodi, joka tuottaa virheitä melko paljon. Mikäli luet virheet, niin korjaaminen saattaa tuntua melko ylivoimaiselta tehtävältä. Koodin saa kuitenkin toimivaksi muuttamalla tarkalleen kahta riviä koodissa. Molemmat selviävät lukemalla pelkästään virheilmoituksia ja ymmärtämällä ne.
#include <iostream> void funktio(int a = 2, int b){ return (a * b); } int main(){ std::cout << funktio(3) << std::endl; return EXIT_SUCCESS; }
Eli koko projekti kaatui, kun en saa tehtyä kääntymistä.
mika132 kirjoitti:
Eli koko projekti kaatui, kun en saa tehtyä kääntymistä.
No se nyt tuskin kuitenkaan olisi ollut se ainoa asia, jota et olisi osannut.
Helpompien projektien pariin siis. "Huipulta" on aika vaikea aloittaa.
mika132 kirjoitti:
Eli koko projekti kaatui, kun en saa tehtyä kääntymistä.
Ei projektisi ei kaatunut siihen, että et saanut kääntymistä tehtyä. Projektisi kaatui siihen, ettet opetellut perusasioita kunnolla / ollenkaan. Tässä on kuitenkin sinulle mahdollisuus oppia jotakin. Huomaat ehkä itsekin, että tuli haukattua liian suuri pala.
(Edit: Oho, kaksi aikaisempaakin vastausta samaan kommenttiin)
Joo, no, jos et tosiaan saa sitä tehtyä vaikka jokaiseen ongelmaan on kerrottu vastaus jo vähintään kahteen kertaan, niin veikkaan kyllä vahvasti että se tulisi kaatumaan sataan muuhunkin asiaan.
Ei millään pahalla, mutta sivun ensimmäisessä viestissä on toteutettu toimiva deg2rad funktio ja silti se ei onnistu vaikka yritetään rautalangasta vääntää monenkin kirjoittajan toimesta. Kääntäjän antamat virheilmoitukset on kohtuullisen selkeitä, mutta niistä ei tule mitään ideoita, jne..
Jotenkin tässä tulee sellainen fiilis että on pakko nostaa kädet ylös, kun ei edes valmista koodia antamalla saada hommaa toimimaan.
Jos opiskelisit C++:n perusteet niin saisit itse ratkaistua tuon ongelman 15 minuutissa. Nyt sitten taas tällä tyylillä että hakataan päätä seinään on omaasi ja muiden aikaa on mennyt tuntikaupalla ja siltikään ei ole mitään näkyvää tulosta.
Oli kokonaan ensimmäinen viesti jäänyt kokonaan ohitse. Kiitos. Sen verran tahtoisi kysäistä, että miten saan hiirtä tarkemmaksi vielä, kun nyt se on liikaa vasemmalla.
Öö siis täh?
Tarkoitan, että hiiri on hahmon katseesta hieman liikaa vasemmalla.
tarkoitatko n 90 astetta? Itsellä ainakin pitää aina joko lisätä tai poistaa 90 astetta suunnasta.
Juu. Selvittelin hieman tuota ja ongelma on siinä, että ukko pyörii liian nopeasti ja välillä taas liian hitaasti. Yleensä hiiren ollessa lähellä hahmoa, hahmo pyörii miten sattuu. Ja taas kaukana ollessa liian hitaasti. Jännä juttu. :O
tietenkin niin tapahtuu, koska peliukko katsoo kokoajan hiirtä kohti.
Kun ei katso. Jos hiiri liikahtaa millin alas päin ukko liikahtaa millin oikealle, mutta ei todellakaan katso hahmoa. Eli taas jokin meni pieleen.
E:
double rad2deg(double rad){ return ((rad * 270) / 3.1415927); //270 kohdalla oli myös 90 ja 180. } struct olio{ int x; int y; };
olio otus = {200, 100}; int hiiren_x, hiiren_y; hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y); int x_jana = (hiiren_x - otus.x); int y_jana = (hiiren_y - otus.y); double kulma = std::atan2((double)x_jana, (double)y_jana); temp = rotozoomSurface(hahmo, rad2deg(kulma), 1, 1); PiirraKuva(musta_kuva, naytto, 0, 0); //Tämä siksi ettei hahmosta jää "vanaa" PiirraKuva(temp, naytto, hahmo_sijainti_x, hahmo_sijainti_y); SDL_FreeSurface(temp); SDL_Flip(naytto);
no miinusta siitä suunnasta ennen rotozoom funkkaria 90, jos ei auta koita +90 siihen.
EDIT: ÄLÄ MISSÄÄN NIMESSÄ MENE muuttamaan rad2deg() funktion sisältöä, sillä se on ihan oikein!!!
Editoin ylempään viestiini tuon tämän hetken koodini.
mika132 kirjoitti:
double rad2deg(double rad){ return ((rad * 270) / 3.1415927); //270 kohdalla oli myös 90 ja 180. }
Älä korjaa toimivaa!
//Miten olisi tämä double kulma = std::atan2((double)x_jana, (double)y_jana); kulma += 90; temp = rotozoomSurface(hahmo, rad2deg(kulma), 1, 1);¨ //TAI TÄMÄ double kulma = std::atan2((double)x_jana, (double)y_jana); kulma -= 90; temp = rotozoomSurface(hahmo, rad2deg(kulma), 1, 1);
Grez osoittikin jo tuolla ylhäällä, miksi tuo on väärin. Mulle on vaan sattunut ajatuskatko tuon kirjoituksen yhteydessä. Yleinen tapa on tosiaan merkitä 0-akseli x-akseliksi kasvamaan vasemmalta oikealle. y-suunta pitäisi kaiketi merkitä myös negatiiviseksi, koska näytöllä luvut kasvaa toisaalta vasemmalta oikealle ja ylhäältä alas. Eli siis std::atan2(-y_jana, x_jana);
Tein taas lisätutkimuksia tuosta kuvasta ja nyt huomasin, että mahtaako Jana koodissani olla jokin vika.
olio otus = {200, 100}; int x_jana = (hiiren_x - otus.x); /* (60 - 200) = -40 */ int y_jana = (hiiren_y - otus.y); /* (80 - 100) = -20 */
Havaittu ongelma:
Hahmo ei katso hiirtä jos hiiri pysää ja jos kävelen tällä tyylillä hiiren ohitse niin, että kylki on päin hiirtä ja käännän hieman kuvaa niin kuva liikkuu asteita vaikka hiiri ei ole sen edesseä vaan takana. hieman lisää käännän hiirtä itse hahmon eteen niin se palaa taas normaaliksi eli hiiri kulkee edessä.
Mietin vain, että eihän janojen koko ole koko ajan sama? Eli millä funktiolla saa mitattua hiiren ja hahmon välisen matkan ja lisätään niiden tulos.
olio otus = (x_kaukana, y_kaukana);
mika132 kirjoitti:
Mietin vain, että eihän janojen koko ole koko ajan sama? Eli millä funktiolla saa mitattua hiiren ja hahmon välisen matkan ja lisätään niiden tulos. olio otus = (x_kaukana, y_kaukana);
Tätähän sinulle on muun muassa metabolix kertonut jo ainakin kaksi kertaa, että käytä oikeita arvoja, äläkä noita paljaita lukuja. Etäisyyden saat jana_x:n ja jana_y:n avulla käyttämällä pythagoraan lausetta.
No sillä etäisyydellä ei ole suunnan suhteen mitään väliä. Ehkäpä sulla noi otuksen x ja y ilmaisee jotain muuta kuin otuksen katseen keskipistettä..
Muutin muuttujien nimet, kun huomasin, että saman niminen oli jo, mutta ei auttanut joten selitän tarkemin.
Pistänpä kuvat selvittämään hieman tilannetta.
Punainen piste kuvaa hiiren sijaintia.
Kuva 1.
Ukko katsoo niinkuin pitääkin suoraan hiirtä.
Kuva 2.
Yhtäkkiä kuva lopettaa pyörimisen noin 30 asteessa ja hiiri jatkaa silti matkaa.
Kuva 3.
Noin 120 asteessa hahmo pyörähtää yhtäkkiä yli 180 asteen ja hiiri jää jälkeen kuten kuvassa näkyy
Jos kuvat on pakko pistää bmp:inä, niin voisi olla edes nopeampi palvelin. :D
Tämä sentään latautuu muutamassa sekunnissa vaikka onkin 11+ megaa http://www.kolumbus.fi/jedi.akatemia/
Tuossa on kuvat vaihtoehtoisesti 1/200 tiedostokoolla:
http://grez.info/putka/mika132/hiiri_1.png
http://grez.info/putka/mika132/hiiri_2.png
http://grez.info/putka/mika132/hiiri_3.png
Ihan mielenkiinnosta muuten kysyisin, että miten tosta hahmosta näkyy, onko se kääntynyt 180° vai vaan 0°?
Mitäs jos pistäisit koko lähdekoodin johonkin, niin voisi olla hieman helpompi paikallistaa vika, kun pystyisi debuggaamaan omalla koneella?
Pistän koko "Pelin", jotta saatte grafiikat samalla.
Lähdekoodi on paikka paikoin vielä hieman epäpuhdas, mutta kuten saatatte huomata opein tuon tiedostoihin siirtämise ja kaikki funktiot ovat yhdessä tiedostossa, sekä alustukset. :P
Päätiedosto on siis main.cpp ja siellä sijaitsee tuo engine. Lyötte vain kertaalleen pelin päälle niin se kertoo jo toiminnasta.
Öö en tiedä missä vika, mut miks lataa vaan 1kb/s???????????????????????? Ei mitään muuta nettiliikennettä, taitaa jäädä lataamatta.
Joo, itselläkin pätki välillä ja sitten kun sen sai ladattua niin välillä meni 900kt/s ja välillä 9kt/s...
Mirroroin sen tonne: http://grez.info/War_In_World.zip
Täytyy kyllä sanoa, että paketin sisältö on vähintään mielenkiintoinen. Sen sisällä on toinen zip.. Ja ylipäätään, miten saa sorsakoodeista ja parista kuvasta 20 megaa... No joo, onhan siellä 5 megan mp3-tiedostokin yms.
Vikanahan tuossa koodissasi on se, että lasket hiiren kursorin suuntaa otuksesta katsoen ja otus on paikassa (200,100), kun taas ukkosi voi olla ihan missä päin vaan. (ei siis välttämättä kohdassa (200,100).)
Jos muuttaisit tuon muotoon
int hiiren_x, hiiren_y; hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y); int x_jana = (hiiren_x - hahmo_sijainti_x); int y_jana = (hiiren_y - hahmo_sijainti_y); double kulma = std::atan2((double)-y_jana, (double)x_jana); temp = rotozoomSurface(hahmo, rad2deg(kulma), 1, 1); PiirraKuva(musta_kuva, naytto, 0, 0); PiirraKuva(temp, naytto, hahmo_sijainti_x - temp->w / 2, hahmo_sijainti_y - temp->h / 2 );
niin se toimisi ihan hienosti.
(Lisäksi ukko ei enää heilu hulluna kääntyilleessään)
Kiitos paljon. Olen todella kiitollinen, että jaksoitte pinnistellä ja auttaa. :)
Aihe on jo aika vanha, joten et voi enää vastata siihen.