การแปลตำแหน่งหน้าจอเป็นตำแหน่งไทล์สามมิติพร้อมสเกล

ฉันกำลังพยายามแปลตำแหน่งของเมาส์บนหน้าจอเป็นไทล์เฉพาะบนแผนที่ การใช้ฟังก์ชันด้านล่างนี้ ฉันเชื่อว่าฉันมาถูกทางแล้ว แต่ฉันไม่สามารถปรับขนาดได้อย่างถูกต้องเมื่อซูม มีความคิดอะไรบ้างว่าทำไม?

นี่คือฟังก์ชั่นที่ฉันใช้:

    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;
    }

จากข้อมูลการดีบักของฉัน X และ Y จะเพิ่มขึ้นเมื่อฉันเลื่อนเมาส์ไปตามเส้นไทล์ อย่างไรก็ตาม ค่าของมันผิดทั้งหมดเนื่องจากไม่ได้แยกตัวประกอบมาตราส่วน ฉันได้ลองรวมมาตราส่วนในฟังก์ชันด้านบนแล้ว แต่ ทุกที่ที่ฉันเพิ่มเข้าไป มันดูเหมือนว่าจะทำให้เรื่องแย่ลง สำหรับการอ้างอิง สเกลจะถูกจัดเก็บเป็นแบบทศนิยม โดยที่ 1.0f หมายความว่าไม่มีการปรับขนาด (ในกรณีที่เกี่ยวข้อง)

นี่คือภาพหน้าจอในกรณีที่ช่วยให้กระจ่างขึ้น:

ป้อนคำอธิบายรูปภาพที่นี่

แก้ไข:

เมื่อเปลี่ยนฟังก์ชันเป็นด้านล่าง ดูเหมือนว่าตัวเลขจะยังคงเพิ่มขึ้นที่จุดเดิม (เช่น ขึ้น 1 หรือลดลง 1 ตามแกนที่เกี่ยวข้องต่อไทล์) แต่ผลลัพธ์ยังคงดูเหมือนขยายขนาดมากเกินไป ตัวอย่างเช่น หากผลลัพธ์เป็น 100, 100 เมื่อฉันซูมเข้า ผลลัพธ์เหล่านี้อาจเปลี่ยนเป็น 50, 50 แม้ว่าเมาส์จะอยู่เหนือไทล์เดียวกันก็ตาม

ฟังก์ชั่นใหม่:

    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 แหล่งที่มา


คำตอบ (1)


หลังจากยุ่งกับโค้ดนิดหน่อย ดูเหมือนว่าฉันจะพบวิธีแก้ปัญหาแล้ว ฉันจะทิ้งมันไว้ที่นี่เผื่อจะเป็นประโยชน์กับคนอื่น:

    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;
    }

ฉันไม่แน่ใจว่าทำไมจึงต้องมีนอร์มัลไลเซอร์อยู่ที่นั่น แต่ฉันลองเล่นกับสเกลและขนาดของแผนที่โดยรวมแล้ว และดูเหมือนว่าจะไม่ส่งผลกระทบต่อค่านี้ที่ต้องการ

สุดท้ายนี้ นี่คือภาพหน้าจอที่แสดงให้เห็นว่ามันใช้งานได้ที่ด้านซ้ายบน:

ป้อนคำอธิบายรูปภาพที่นี่

person Lyise    schedule 21.01.2013