Tein LWJGL:llä pelin, jossa liikutaan kameralla 3D-avaruudessa, jossa on 2x2x2 kuutioita. Olen yrittänyt ja yrittänyt saada törmäyksen toimimaan, ja se toimiikin x-akselin osalta, mutta ei z-akselin. Googlekaan ei ole auttanut.
Ideoita?
Tässä vielä nykyinen koodini:
public Vector3f collide(Vector3f cam, Vector3f block) { if (cam.x > block.x && cam.x < block.x + 1 && cam.z > block.z && cam.z < block.z + 2) { return new Vector3f(block.x, cam.y, cam.z); } if (cam.x < block.x + 2 && cam.x > block.x && cam.z > block.z && cam.z < block.z + 2) { return new Vector3f(block.x + 2, cam.y, cam.z); } return cam; }
Siis onko tuossa niin, että cam on (pistemäisen) kameran sijainti ja block on palikan yksi nurkka (ja toinen nurkka on x+2,y+2,z+2) ja tarkoituksena olisi saada kameralle uusi sijainti joka on lohkon ulkopuolella?
En kyllä nopeesti katsoen näe miksei tuo z:n osalta toimisi. Pikemminkin aika selvää on, että se ei toimi y:n osalta)
Koska ei kuitenkaan tiedetä mistä suunnasta kamera on törmännyt lohkoon, niin [sarkasmi]lienee samantekevää siirtää se kamera vaan johonkin lohkon kulmaan[/sarkasmi].
//Jos palikan "sisällä" if (cam.x < (block.x + 2) && cam.x > block.x && cam.y < (block.y + 2) && cam.y > block.y && cam.z < (block.z + 2) && cam.z > block.z) { return block; } else { return cam; }
Grez kirjoitti:
Koska ei kuitenkaan tiedetä mistä suunnasta kamera on törmännyt lohkoon, niin on lienee samantekevää siirtää se kamera vaan johonkin lohkon kulmaan.
Tuskin sentään: noinhan palikan väärältä puolelta tullessa pääsee palikan läpi. Loogista voisi olla siirtää kamera lähimpään kulmaan, jolloin koodi toimisi kohtalaisesti edes siinä tilanteessa, että kameran nopeus ei riitä lennättämään sitä yhdellä askeleella yli puolen palikan mittaa.
P.S. Sana ”lienee” on olla-verbin potentiaalimuoto, ja sen kanssa ei kuulu käyttää ylimääräistä olla-verbiä. Esimerkki: ”Koodisi lienee viallinen.”
Joo olet oikeassa sekä tuosta läpimenosta että on-sanan väärinkäytöstä.
Mutta oikeastaan ihan tahallani laitoin tuon että "koska ei tiedetä". Mielestäni järkevämpää olisi tutkia törmääkö kamera johonkin ja sitten palata vaikka edelliseen positioon mieluummin kuin alkaa arpoa jotain uutta koordinaattia kameralle sen liikesuuntaa tietämättä.
Grez kirjoitti:
En kyllä nopeesti katsoen näe miksei tuo z:n osalta toimisi.
Ei toimi sen z-akselin osalta sen vuoksi, että kun z-akselin kanssa niin kamera pamahtaa sen kuution x-akselin kulmaan, koska
return new Vector3f(block.x, cam.y, cam.z);
Kuten sanoin, sinun pitäisi laskea lähin kulma tai laskea jopa kameran kulkureitin ja palikan seinämän leikkauspiste. Kokeile vaikka hakusanoja check if line intersects cube. Kun kuutiosi on akselien suuntaisesti, laskuista tulee poikkeuksellisen helppoja.
En oikein ymmärrä, miksi sanoit epämääräisesti, että koodi ei toimi, jos kuitenkin tiesit, että olet ohjelmoinut toimivasti asian A mutta haluaisitkin tehdä asian B.
Metabolix kirjoitti:
En oikein ymmärrä, miksi sanoit epämääräisesti, että koodi ei toimi, jos kuitenkin tiesit, että olet ohjelmoinut toimivasti asian A mutta haluaisitkin tehdä asian B.
Jos sinulla on auto, haluat varmaankin sekä moottorin että vaihdelaatikon toimivan?
-_-
omcesa kirjoitti:
Jos sinulla on auto, haluat varmaankin sekä moottorin että vaihdelaatikon toimivan?
Jos sinulla on toimiva polkupyörä mutta haluaisit auton, varmaan kannattaisi kertoa, että haluat auton. Nythän vain sanoit, että tässä on polkupyörä mutta se ei toimi.
Alkuperäinen koodisi toimii aivan hyvin sekä x- että z-akselilla: molemmissa tapauksissa törmäys tunnistetaan ja kamera siirretään x-akselia pitkin lähemmälle laatikon reunalle. Jos tämä ei ole toivomasi toimintamalli, sinun pitää edes selittää, mitä haluat.
Kun nyt näköjään et viitsi muotoilla selvää kysymystä, arvaillaan. Ehkä haluamasi koodi on sellainen, että kamera siirretään aina lähimmälle reunalle:
if ( block.x < cam.x && cam.x < (block.x + 2) && block.y < cam.y && cam.y < (block.y + 2) && block.z < cam.z && cam.z < (block.z + 2) ) { float dx0 = cam.x - block.x; float dx1 = block.x + 2 - cam.x; float dy0 = cam.y - block.y; float dy1 = block.y + 2 - cam.y; float dz0 = cam.z - block.z; float dz1 = block.z + 2 - cam.z; float min = Math.min(Math.min(dx0, dx1), Math.min(Math.min(dy0, dy1), Math.min(dz0, dz1))); if (dx0 == min) return new Vector3f(block.x, cam.y, cam.z); if (dx1 == min) return new Vector3f(block.x + 2, cam.y, cam.z); if (dy0 == min) return new Vector3f(cam.x, block.y, cam.z); if (dy1 == min) return new Vector3f(cam.x, block.y + 2, cam.z); if (dz0 == min) return new Vector3f(cam.x, cam.y, block.z); if (dz1 == min) return new Vector3f(cam.x, cam.y, block.z + 2); } return cam;
(Edit: Ja Metabolix näköjään jo tekikin koodin alla selitettyyn)
Niin, tokihan olisi triviaalisti koodattavissa että mennään lähimpänä nykyistä (kuution sisällä olevaa) pistettä lähimpään kuution reunaan. Tämä lienee jopa kohtuullisen toimiva malli. Vaikka ajettaisiin kuution sisään niin läheltä reunaa, että se pullauttaa kameran sen lähellä olevan reunan eikä läpiajoreunan viereen, niin kelvannee.
Ainoa "vika" että kiinni toisissaan olevien välistä ja toistensa kanssa päällekkäin olevien kuutioiden läpi pääsee "purjehtimaan" (mikäli siis jokainen kuutio testataan erikseen tuolla koodilla). Sopivalla kuutiohässäkällä voisi pystyä jopa teleporttaamaan kuutioiden läpi :D
Jos tiedetään että kuutioita ei ole kiinni toisissaan niin sillionhan edelläolevalla ei ole merkitystä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.