On ollut pitkä tauko ohjelmoinnista ja on unohtanut kaikenlaista, niin jattelin tulla tänne kysymään muutamaa kysymystä.
Ensinnäkin olisi yksi ongelma tuon SDL:än, lisäkirjastojen ja C++ kanssa. Kääntäjä gcc.
Elikkäs esim. SDL:ssa on määritelty setpixel-funktio. Funktio käyttää noita SDL:än omia muuttujia muuttujinaan, ja niiden pitää olla kokonaislukuja, kuten myös int-muuttujien, joita käytetään itse ohjelman funktiossa.
Mikä ratkaisu ongelmaan, kun pitää käyttää desimaaleja muuttujien arvoina? Double muuttujan muuttaminen laskennan jälkeen int:ksi ei ole ratkaisu, koska tämä aiheuttaa epätarkkuutta.
Yritin vaihtaa SDL:n kirjastoista ne muuttujan doubleiksi, mutta silloin ei toimi...
No toinen harmaita hiuksia aiheuttaa kysymys koskee yksinkertasta autopelin ohjelmointia. Siis ihan mustalle taustalle piirrettäisiin auto SDL:n avulla, ja löysin hyvän funktion jolla saa auton kuvaa pyöritettyä keskipisteensä ympäri (rotozoomin kanssa touhuamalla).
Siis kiihtyvyyden, ja jonkun asteisen kitkan olen oppinut tekemään, mutta asiaa pitää lähestyä vähän eri tavalla ilmeisesti...
Elikkäs auton piäisi edetä aina siihen suuntaan mihin keula osoittaa. Miten tämän toteuttaa? Eli siis jos auto aluksi on täysin oikealle, niin painamalla auton ollesa vauhdissa vasemmalle, auton kuvaa kännettäisiin asteen vasemmalle, ja suunta muuttuisi myös nyt y-akselilla. Tähän jotain esimerkkiä olisi kiva saada?
Shark90 kirjoitti:
Elikkäs esim. SDL:ssa on määritelty setpixel-funktio. Funktio käyttää noita SDL:än omia muuttujia muuttujinaan, ja niiden pitää olla kokonaislukuja, kuten myös int-muuttujien, joita käytetään itse ohjelman funktiossa.
Mikä ratkaisu ongelmaan, kun pitää käyttää desimaaleja muuttujien arvoina? Double muuttujan muuttaminen laskennan jälkeen int:ksi ei ole ratkaisu, koska tämä aiheuttaa epätarkkuutta.
Jos sinulla on kaksi kaappia, ja laitat henkarin niiden väliin, henkari ei ole minkään kaapin sisällä. Kuva näkyy näytössä pikselin tarkkuudella.
Voit kyllä muuttaa pikselin väriä tai piirtää vaikka neljän vierekkäisen pikselin ryhmän, jolloin se näyttää olevan kahden pikselin välissä.
Shark90 kirjoitti:
Elikkäs esim. SDL:ssa on määritelty setpixel-funktio. Funktio käyttää noita SDL:än omia muuttujia muuttujinaan, ja niiden pitää olla kokonaislukuja, kuten myös int-muuttujien, joita käytetään itse ohjelman funktiossa.
Mikä ratkaisu ongelmaan, kun pitää käyttää desimaaleja muuttujien arvoina? Double muuttujan muuttaminen laskennan jälkeen int:ksi ei ole ratkaisu, koska tämä aiheuttaa epätarkkuutta.
Epätarkkuutta voi vähän purkasti vähentää vaikka miinustamalla 0.5 luvusta ennen typecastausta intiksi, koska typecastaus intiksi pyöristää aina ylöspäin. Vähentämällä 0.5 takaa pyöristyksen lähimpään kokonaislukuun.
Toinen tapa on sitten luoda vähän järkevämpi illuusio useammasta pikselistä, vaikkapa blurrilla/pehmennyksellä/antialisoinnilla, miksi sitä nyt ikinä haluataankaan kutsua.
Shark90 kirjoitti:
Elikkäs auton piäisi edetä aina siihen suuntaan mihin keula osoittaa. Miten tämän toteuttaa? Eli siis jos auto aluksi on täysin oikealle, niin painamalla auton ollesa vauhdissa vasemmalle, auton kuvaa kännettäisiin asteen vasemmalle, ja suunta muuttuisi myös nyt y-akselilla. Tähän jotain esimerkkiä olisi kiva saada?
https://www.ohjelmointiputka.net/oppaat/opas.
Jos auton nopeus on vaikka 50 km/h ja se kääntyy asteen vasemmalle olettaen, että täysin oikealle menevä suunta on 0 astetta, on y-akselin mukainen suunta sin(1)*nopeus, joka olisi ~0,87km/h ja vastaavasti x-akselin mukainen nopeus olisi cos(1)*nopeus, ts. 49,99.
Pythagoraan lauseella näkee että nopeus on todellakin 50 kilometriä tunnissa tuossa vaiheessa.
Yleisestikin trigonometria on oikein kätevää.
Tzaeru kirjoitti:
Epätarkkuutta voi vähän purkasti vähentää vaikka miinustamalla 0.5 luvusta ennen typecastausta intiksi, koska typecastaus intiksi pyöristää aina ylöspäin. Vähentämällä 0.5 takaa pyöristyksen lähimpään kokonaislukuun.
Ei. Typecast pyöristää aina pienempään, joten lukuun pitää lisätä puolikas. Mutta eivät ne pikselit tosiaan sillä kapeammiksi muutu, kuten jo mainittiinkin.
Edit. Tarkennuksena siis: "pienempi" viittaa itseisarvoltaan pienempään eli nollaa lähempänä olevaan, ja lisääminen koskee tietenkin vain ei-negatiivisia lukuja, joista tässä aiheessa luonnollisesti on kyse, kun pikselien paikat yleensä ilmaistaan sellaisilla.
Metabolix kirjoitti:
Ei. Typecast pyöristää aina pienempään, joten lukuun pitää lisätä puolikas.
Ei. Typecast pyöristää aina nollaa kohti, joten positiiviseen lukuun pitää lisätä ja negatiivisesta vähentää puolikas.
Metabolix kirjoitti:
Tzaeru kirjoitti:
Epätarkkuutta voi vähän purkasti vähentää vaikka miinustamalla 0.5 luvusta ennen typecastausta intiksi, koska typecastaus intiksi pyöristää aina ylöspäin. Vähentämällä 0.5 takaa pyöristyksen lähimpään kokonaislukuun.
Ei. Typecast pyöristää aina pienempään, joten lukuun pitää lisätä puolikas. Mutta eivät ne pikselit tosiaan sillä kapeammiksi muutu, kuten jo mainittiinkin.
:-o perin ovelasti muistelin taas omiani ja toki väärinpäin.
Toki tuo olikin se luonnollinen ja järkevä pyöristyssuunta.
Joo siis toi setpixel funktio oli vain esimerkki. Sama ongelma ihan normaalin bmp-kuvan piirron kanssa. Ja oikeastaan jokaisen SDL:n funktion kanssa, kuten lineRGBA:n.
Esim. tämä ei käänny https://www.ohjelmointiputka.net/koodivinkit/
Mutta muistaakseni sain muuten tuon kääntymään kun käytin gcc:tä, g++ sijasta... Mistä tämä johtuu?
Niin ja tuo pyöristäminen tulee oikeastaan ongelmaksi siinä vaiheessa, kun lisätään jokakerta loopissa esim. muuttujaa yhdellä, joka on aivan liikaa, pitäisi lisätä esim 0.1. Mutta muu loopin toiminta voi vaatia silti normaalilla nopeudella luuppaavaa silmukkaa, joten minkää delayn käyttö ei tulisi kysymykseen.
Shark90 kirjoitti:
Mutta muistaakseni sain muuten tuon kääntymään kun käytin gcc:tä, g++ sijasta... Mistä tämä johtuu?
C:tä ei käännetä g++:lla.
ville-v kirjoitti:
Shark90 kirjoitti:
Mutta muistaakseni sain muuten tuon kääntymään kun käytin gcc:tä, g++ sijasta... Mistä tämä johtuu?
C:tä ei käännetä g++:lla.
Joo, tiedossa on. Tarkotin että c-kielen kääntäjällä onistuu kääntö *.c tiedostona, mutta g++:lla *.cpp tiedostona ei.
Shark90 kirjoitti:
ville-v kirjoitti:
Shark90 kirjoitti:
Mutta muistaakseni sain muuten tuon kääntymään kun käytin gcc:tä, g++ sijasta... Mistä tämä johtuu?
C:tä ei käännetä g++:lla.
Joo, tiedossa on. Tarkotin että c-kielen kääntäjällä onistuu kääntö *.c tiedostona, mutta g++:lla *.cpp tiedostona ei.
Tiedostonimen vaihtaminen ei muuta kieltä, jolla ohjelma on koodattu. Jos C-koodi ei ole yhteensopiva C++:n kanssa, sitä pitää muokata.
Shark90 kirjoitti:
Niin ja tuo pyöristäminen tulee oikeastaan ongelmaksi siinä vaiheessa, kun lisätään jokakerta loopissa esim. muuttujaa yhdellä, joka on aivan liikaa, pitäisi lisätä esim 0.1.
Mikä nyt oli ongelmana, ettet voi käyttää laskennassa doublea ja pyöristää sitä piirtovaiheessa? Eihän pyöristyksen yhteydessä suinkaan tarvitse hukata alkuperäistä arvoa minnekään.
Jos loopissa on x+=0.1, ja sen pyöristää piirtoa varten, niin silloinhan se olisi sama asia kuin pistäisi x+=1.
Shark90 kirjoitti:
Jos loopissa on x+=0.1, ja sen pyöristää piirtoa varten, niin silloinhan se olisi sama asia kuin pistäisi x+=1.
ville-v kirjoitti:
Jos sinulla on kaksi kaappia, ja laitat henkarin niiden väliin, henkari ei ole minkään kaapin sisällä. ¨Kuva näkyy näytössä pikselin tarkkuudella.
Vaihtoehdoksi jää kymmenkertaistaa näytöntarkkuus, mutta se ei taida tulla kyseeseen tässä tapauksessa.
Shark90 kirjoitti:
Jos loopissa on x+=0.1, ja sen pyöristää piirtoa varten, niin silloinhan se olisi sama asia kuin pistäisi x+=1.
Eikä ole. Kun pyöristät sen vain piirtoa varten, tulee kuva aina kymmenen kertaa samaan kohti ja siirtyy vasta sitten yhden pikselin — eli tavallaan liikkuu hitaammin.
Voisit edes kokeilla asiaa, ennen kuin sanot noin ehdottomasti, ettei se toimi. Mikä seuraavassa koodissa sinusta menee pieleen?
#include <iostream> #include <iomanip> using namespace std; int main() { double x; int piirto_x; for (x = 0; x < 2; x += 0.1) { piirto_x = (int) (x + 0.5); cout << "x: " << setw(3) << x << "; piirto_x: " << piirto_x << endl; } return 0; }
Juu, oma virhe. Koodissa oli muutakin hämärää, mikä teki virheitä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.