ก่อนอื่นนี่คือรหัส คำอธิบายจะเป็นไปตาม:
/*
* tw, th contain the tile width and height.
*
* hitTest contains a single channel taken from a tile-shaped hit-test
* image. Data was extracted with getImageData()
*/
worldToTilePos = function(x, y) {
var eventilex = Math.floor(x%tw);
var eventiley = Math.floor(y%th);
if (hitTest[eventilex + eventiley * tw] !== 255) {
/* On even tile */
return {
x: Math.floor((x + tw) / tw) - 1,
y: 2 * (Math.floor((y + th) / th) - 1)
};
} else {
/* On odd tile */
return {
x: Math.floor((x + tw / 2) / tw) - 1,
y: 2 * (Math.floor((y + th / 2) / th)) - 1
};
}
};
โปรดทราบว่ารหัสนี้จะไม่ทำงานนอกกรอบสำหรับแผนที่ที่แสดงในคำถามของคุณ นี่เป็นเพราะคุณมีไทล์คี่ออฟเซ็ตทางซ้ายในขณะที่ไทล์คี่จะออฟเซ็ตมากกว่าทางด้านขวา (ในกรณีที่เป็นตัวแก้ไขแผนที่แบบเรียงต่อกัน ) คุณควรจะสามารถแก้ไขปัญหานี้ได้โดยง่ายโดยการปรับค่า x ที่ส่งกลับมาในกรณีคี่ไทล์
คำอธิบาย
นี่อาจดูเหมือนจะเป็นวิธีที่ใช้กำลังดุร้ายมากกว่าในการทำภารกิจนี้ แต่อย่างน้อยก็มีข้อดีของการเป็นพิกเซลที่สมบูรณ์แบบและยืดหยุ่นกว่าเล็กน้อย
เคล็ดลับคือในการดูแผนที่ไม่ใช่เป็นกริดเซเดียว แต่เป็นสองกริดที่ซ้อนทับกัน มีกริดแถวคี่และกริดคู่, แต่ลองเรียกมันว่าสีแดงและเขียวแทนเพื่อเราจะได้สร้างแผนภาพสวย ๆ ...
สังเกตทางด้านขวาของภาพนั้นฉันได้ทำเครื่องหมายจุดด้วยจุดสีม่วง นี่คือจุดตัวอย่างที่เราจะลองค้นหาในช่องว่างแบบดั้งเดิมของเรา
สิ่งที่สังเกตได้เกี่ยวกับจุดใด ๆ ในโลกก็คือมันจะอยู่ในสองภูมิภาคเสมอ - หนึ่งสีแดงและสีเขียว (เว้นแต่จะอยู่บนขอบ มาหาพื้นที่เหล่านั้น ...
ทีนี้ให้เลือกว่าพื้นที่ใดในสองภูมิภาคที่ถูกต้อง จะมีคำตอบเดียวเสมอ
จากที่นี่เราสามารถทำเลขคณิตได้ง่ายขึ้นและหาระยะยกกำลังสองจากจุดตัวอย่างของเราไปยังแต่ละจุดศูนย์กลางของสองภูมิภาค คำตอบของเราคือคำตอบที่ใกล้เคียงที่สุด
มีวิธีอื่นอย่างไรก็ตาม สำหรับแต่ละพื้นที่ทดสอบเราสุ่มบิตแมปที่ตรงกับรูปร่างที่แท้จริงของกระเบื้องของเรา เราสุ่มตัวอย่าง ณ จุดที่แปลเป็นพิกัดท้องถิ่นสำหรับไทล์เดียว สำหรับตัวอย่างของเรามันจะออกมาเป็นแบบนี้:
ทางด้านซ้ายหนึ่งที่เราตรวจสอบพื้นที่สีเขียวและได้รับการตี (พิกเซลสีดำ) ด้านขวาเราจะทดสอบพื้นที่สีแดงและรับ (พิกเซลสีขาว) การทดสอบครั้งที่สองนั้นซ้ำซ้อนแน่นอนเพราะมันจะเป็นการทดสอบอย่างใดอย่างหนึ่งเสมอไม่เคยทั้งคู่
จากนั้นเราก็มาถึงข้อสรุปที่ว่าเราได้รับความนิยมในไพ่แปลก ๆ ที่ 1,1 พิกัดนี้ควรจะง่ายต่อการแมปไปยังพิกัดของไทล์ดั้งเดิมโดยใช้การแปลงที่แตกต่างกันสำหรับแถวคี่และแถว
วิธีนี้ยังช่วยให้คุณมีคุณสมบัติต่อพิกเซลอย่างง่าย ๆ บนบิตแมปทดสอบพิกเซล เช่นสีขาวเป็นกระเบื้อง, สีดำเป็นที่นิยม, สีฟ้าคือน้ำ, สีแดงเป็นของแข็ง