Izometrikus térképen a csempe koordinátáinak meghatározása
2019-05-30T14:26:24+02:00
2019-05-31T17:53:44+02:00
2022-08-11T12:50:31+02:00
Axxtros
Sziasztok,

Van egy hagyományos (diamond) felépítésű izometrikus térképem, amelyet egy mátrixból generáltam ki. Azt kellene megoldani, hogy az egérkurzor poziciójából meg kellene pontosan határozni azt, hogy melyik térképcsempe felett van az egér. Sok ilyen leírás van a net-en, sokat ki is próbáltam, de ez valahogy nem akar összejönni. Eddig ez volt a legközelebbi, de itt - nem tudom, hogy miért - de kompenzálni kell a kijött koordinátákat, és máris hibás lesz, ha a térkép csempe mérete megváltozik:

tileX = Math.round( ((mouseX / (ISOMETRIC_TILE_WIDTH / 2)) + (mouseY / (ISOMETRIC_TILE_HEIGHT / 2))) / 2) - 11; tileY = Math.round( ((mouseY / (ISOMETRIC_TILE_HEIGHT / 2)) - (mouseX / (ISOMETRIC_TILE_WIDTH/ 2))) / 2) + 10;
A végén a -11, és a +10 a kompenzáció, de nem értem, hogy miért kell. Amúgy ezek nélkül a képlet hibás.
Nekem igazából pontosan ez kellene: https://www.youtube.com/watch?v=cBxUapog9bQNagyon megköszönném, ha valaki elküldene egy olyan formulát, amely minden csempe méretre megfelelően adja vissza a csempe koordinátákat. Az interneten felelhető leírásokat - szerintem - már mind kipróbáltam, de persze ha van valakinek saját leírása, azt is szívesen venném. Thx! :)
Mutasd a teljes hozzászólást!
ha a 2d diamond shaped isometric map with mouse collision -nek megfelelően felül van a (0,0), bal szélén a (0,7), jobb szélén a (7,0) és alul a (7,7), továbbá az egér megkapott pozíciója az ábrát tartalmazó canvas bal felső sarkához képest relatív, akkor nekem a következő adódott:

let mx = (e.offsetX - TOPLEFT.x) / TILE_WIDTH let my = (e.offsetY - TOPLEFT.y) / TILE_HEIGHT let tileX = Math.floor(my + mx - N / 2) let tileY = Math.floor(N / 2 - mx + my)
ahol TOPLEFT az ábra bal felső sarka a canvas koordináta rendszerében, a TILE_WIDTH és TILE_HEIGHT a csempék nagysága, az N pedig az ábra "mérete" (a demó szerint 8), a tileX és tileY adja meg így a csempe "indexét", (értelemszerűen, ha TOPLEFT = (0,0), akkor "egyszerűsíthető")

nem nagyon értek a JavaScript-hez, de tesztelhető: Edit fiddle - JSFiddle
Mutasd a teljes hozzászólást!

  • a mouseX, mouseY a "középponthoz" képest adott, vagy ...?
    Mutasd a teljes hozzászólást!
  • Nem a középponthoz képest adott, hanem simán, csak canvas a bal felső sarkából kiindulva számított.
    Mutasd a teljes hozzászólást!
  • A végén a -11, és a +10 a kompenzáció, de nem értem, hogy miért kell. Amúgy ezek nélkül a képlet hibás.

    Nem "hibás", hanem anélkül a canvas bal felső sarka lesz a 0,0 tile.

    hibás lesz, ha a térkép csempe mérete megváltozik

    Mert a kompenzáció mértékegysége "darab csempe", és a képernyő közepe/alja más csempeméretnél más "darab csempe" pozícióba esik.

    Lehet, hogy ezt a képletet volt könnyű copy-paste-ezni, de én inkább azt javasolnám, hogy az egérpozíció segítségével valósítsd meg az eltolást, szóval mouseX helyett mx=mouseX-<canvas szélesség fele>, illetve mouseY helyett valószínűleg my=<canvas magasság>-mouseY, feltéve, hogy a 0,0 tile a képernyőn alul középen van (a mozit most nem tudom megnézni).

    (Viccből: mouse position to isometric tile including height  - persze az egész kérdés meg a többi válasz is érdekes, csak igazából eléggé más a feladat a magasságtérkép miatt)
    Mutasd a teljes hozzászólást!
  • ha a 2d diamond shaped isometric map with mouse collision -nek megfelelően felül van a (0,0), bal szélén a (0,7), jobb szélén a (7,0) és alul a (7,7), továbbá az egér megkapott pozíciója az ábrát tartalmazó canvas bal felső sarkához képest relatív, akkor nekem a következő adódott:

    let mx = (e.offsetX - TOPLEFT.x) / TILE_WIDTH let my = (e.offsetY - TOPLEFT.y) / TILE_HEIGHT let tileX = Math.floor(my + mx - N / 2) let tileY = Math.floor(N / 2 - mx + my)
    ahol TOPLEFT az ábra bal felső sarka a canvas koordináta rendszerében, a TILE_WIDTH és TILE_HEIGHT a csempék nagysága, az N pedig az ábra "mérete" (a demó szerint 8), a tileX és tileY adja meg így a csempe "indexét", (értelemszerűen, ha TOPLEFT = (0,0), akkor "egyszerűsíthető")

    nem nagyon értek a JavaScript-hez, de tesztelhető: Edit fiddle - JSFiddle
    Mutasd a teljes hozzászólást!
  • Köszi.
    Amikor még korábban írtad, hogy az egér kurzor mihez képest van kalkulálva, már akkor beugrott, hogy valóban az lehet a hiba, hogy nem számolok vele offset-et, a képhez viszonyítva. Aztán összeraktam én is azt a képletet, amit később te is leírtál.
    Ettől függetlenül köszönöm a segítséget, működik, természetesen jár a pont! Thx! :)
    Mutasd a teljes hozzászólást!
  • Csak ötlet szinten, hogy hogyan lehetne még kezelni, amennyiben nem szabályos dologról lenne szól.
    A háttérbe legenerálhatsz egy tömböt, melybe az adott x, y koordinátába azt írod be, hogy mely indexű tile-hoz
    tartozik az adott pixel. Így az egér kattintáskor elég csak beleindexelned ebbe a buffer-ba, hogy megkapd a konkrét indexű elemet.
    Amennyiben kirajzolni kitudod a megjelenítendő és kattintható elemeket, akkor könnyen tudsz ilyen map-et gyártani, hiszen annyi a dolgod, hogy a képernyő helyett ebbe a 'bufferbe rajzolsz' az adott mezőt reprezentáló ID-vel..
    (Pl custom térkép esetén, hogy mi fölött is van az egér), bár az ilyesmikhez nyújt segítséget általában a keretrendszer/könyvtár, amit használsz.
    Mutasd a teljes hozzászólást!
  • (Az előző hsz-em végén linkelt birkás-fás kód pont ezt csinálja, csak ide igazából felesleges)
    Mutasd a teljes hozzászólást!
abcd