Đầu tiên, đây là mã. Một lời giải thích sẽ theo sau:
/*
* 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
};
}
};
Lưu ý rằng mã này sẽ không hoạt động ngoài hộp cho bản đồ được hiển thị trong câu hỏi của bạn. Điều này là do bạn có các ô lẻ lẻ lệch sang trái, trong khi đó các ô lẻ thường được bù ở bên phải (Như trường hợp trong trình chỉnh sửa bản đồ lát gạch ). Bạn sẽ có thể dễ dàng khắc phục điều này bằng cách điều chỉnh giá trị x được trả về trong trường hợp gạch lẻ.
Giải trình
Đây có vẻ là một phương pháp mạnh mẽ hơn một chút để hoàn thành nhiệm vụ này, nhưng ít nhất nó có lợi thế là pixel hoàn hảo và linh hoạt hơn một chút.
Bí quyết là trong việc xem bản đồ không phải là một lưới so le, mà là hai lưới chồng lên nhau. Có lưới hàng lẻ và lưới hàng chẵn, nhưng thay vào đó, hãy gọi chúng là màu đỏ và màu xanh lá cây để chúng ta có thể tạo một sơ đồ đẹp ...
Lưu ý bên phải hình ảnh đó Tôi đã đánh dấu một điểm bằng một chấm màu tím. Đây là điểm ví dụ chúng tôi sẽ cố gắng tìm trong không gian gạch ban đầu của chúng tôi.
Điều cần chú ý về bất kỳ điểm nào trên thế giới là nó sẽ luôn nằm ở hai khu vực chính xác - một màu đỏ và một màu xanh lá cây (Trừ khi nó ở một cạnh, nhưng dù sao bạn cũng sẽ bị kẹp trong ranh giới cạnh lởm chởm). Hãy tìm những vùng đó ...
Bây giờ để chọn cái nào trong hai vùng là đúng. Sẽ luôn có một câu trả lời chính xác.
Từ đây, chúng tôi có thể thực hiện một số số học đơn giản hơn và tính ra khoảng cách bình phương từ điểm mẫu của chúng tôi đến từng điểm trung tâm của hai vùng. Bất cứ điều gì gần nhất sẽ là câu trả lời của chúng tôi.
Có một cách khác tuy nhiên. Đối với mỗi khu vực thử nghiệm, chúng tôi lấy mẫu một bitmap phù hợp với hình dạng chính xác của các ô của chúng tôi. Chúng tôi lấy mẫu tại một điểm được dịch thành tọa độ cục bộ cho ô đơn đó. Ví dụ của chúng tôi, nó sẽ trông giống như thế này:
Một bên trái, chúng tôi kiểm tra vùng màu xanh lá cây và nhận được một điểm nhấn (pixel đen). Ở bên phải, chúng tôi kiểm tra vùng màu đỏ và bỏ lỡ (pixel trắng). Thử nghiệm thứ hai tất nhiên là dư thừa vì nó sẽ luôn luôn chính xác cái này hay cái kia, không bao giờ cả hai.
Sau đó chúng tôi đi đến kết luận rằng chúng tôi có một điểm nhấn trong ô lẻ ở mức 1,1. Tọa độ này phải đơn giản để ánh xạ tới tọa độ ô ban đầu bằng cách sử dụng một phép biến đổi khác nhau cho các hàng lẻ và chẵn.
Phương pháp này cũng cho phép bạn có các thuộc tính mỗi pixel đơn giản trên (các) bitmap thử nghiệm pixel. Ví dụ: màu trắng là gạch ngói, màu đen là một hit, màu xanh là nước, màu đỏ là rắn.