Menerjemahkan lokasi layar ke lokasi ubin isometrik dengan penskalaan

Saya mencoba menerjemahkan lokasi mouse di layar ke ubin tertentu di peta. Dengan menggunakan fungsi di bawah ini, saya yakin saya sudah berada di jalur yang benar, namun saya tidak bisa mengatur skalanya dengan benar ketika saya melakukan zoom. Ada ide kenapa?

Inilah fungsi yang saya gunakan:

    Vector2 TranslationVectorFromScreen(Vector2 toTranslate)
    {
        Vector2 output = new Vector2();

        toTranslate -= offset; // Offset is the map's offset if the view has been changed

        toTranslate.X /= tileBy2; // tileBy2 is half of the each tile's (sprite) size
        toTranslate.Y /= tileBy4; // tileBy2 is a quarter of the each tile's (sprite) size

        output.X = (toTranslate.X + toTranslate.Y) / 2;
        output.Y = (toTranslate.X - toTranslate.Y) / 2;

        return output;
    }

Menurut informasi debug saya, X dan Y bertambah ketika saya menggerakkan mouse di sepanjang garis ubin, namun nilainya semua salah karena skala tidak diperhitungkan. Saya sudah mencoba memasukkan skala ke dalam fungsi di atas, tetapi di mana pun saya menambahkannya, sepertinya hal itu memperburuk keadaan. Sebagai referensi, skala disimpan sebagai float dimana 1.0f berarti tidak ada penskalaan (untuk berjaga-jaga jika ini relevan).

Berikut tangkapan layar jika ada yang bisa membantu menjelaskan:

masukkan deskripsi gambar di sini

Sunting:

Dengan mengubah fungsinya ke bawah, angka tersebut tampaknya masih bertambah pada titik yang sama (yaitu naik sebesar 1 atau turun sebesar 1 sepanjang sumbu yang relevan per petak), namun hasilnya masih tampak terlalu besar. Misalnya, jika hasilnya 100, 100, ketika saya memperbesarnya, hasilnya mungkin berubah menjadi 50, 50 meskipun mouse berada di petak yang sama.

Fungsi baru:

    Vector2 TranslationVectorFromScreen(Vector2 toTranslate)
    {
        Vector2 output = new Vector2();

        toTranslate -= offset;

        toTranslate.X /= (tileBy2 * scale); // here are the changes
        toTranslate.Y /= (tileBy4 * scale); // 

        output.X = (toTranslate.X + toTranslate.Y) / 2;
        output.Y = (toTranslate.X - toTranslate.Y) / 2;

        return output;
    }

person Lyise    schedule 21.01.2013    source sumber


Jawaban (1)


Setelah sedikit mengutak-atik kodenya, sepertinya saya telah menemukan solusi. Saya akan meninggalkannya di sini kalau-kalau ini berguna bagi orang lain:

    Vector2 TranslationVectorFromScreen(Vector2 toTranslate)
    {
        Vector2 output = new Vector2();
        Vector2 tempOffset = offset; // copy of the main screen offset as we are going to modify this

        toTranslate.X -= GraphicsDevice.Viewport.Width / 2;
        toTranslate.Y -= GraphicsDevice.Viewport.Height / 2;
        tempOffset.X /= tileBy2;
        tempOffset.Y /= tileBy4;

        toTranslate.X /= tileBy2 * scale;
        toTranslate.Y /= tileBy4 * scale;

        toTranslate -= tempOffset;

        output.X = (toTranslate.X + toTranslate.Y) / 2;
        output.Y = (toTranslate.X - toTranslate.Y) / 2;

        output += new Vector2(-1.5f, 1.5f); // Normaliser - not too sure why this is needed

        output.X = (int)output.X; // rip out the data that we might not need
        output.Y = (int)output.Y; // 

        return output;
    }

Saya tidak sepenuhnya yakin mengapa normaliser perlu ada di sana, tapi saya telah bermain-main dengan skala dan ukuran peta secara total dan ini tampaknya tidak mempengaruhi nilai yang seharusnya.

Terakhir, berikut tangkapan layar untuk mengilustrasikannya berfungsi di kiri atas:

masukkan deskripsi gambar di sini

person Lyise    schedule 21.01.2013