Основная идея заключается в том, что у вас есть бесконечная плоскость, в которой ваше изображение повторяется снова и снова во всех направлениях. И тогда у вас есть «окно просмотра», которое вы можете рассматривать как окно, ограничивающее ваш взгляд на бесконечную плоскость. Другими словами, область бесконечной плоскости, которая находится «под» областью просмотра, - это то, что фактически отображается на экране.
Таким образом, когда верхний левый угол вашего видового экрана находится в точке (0,0), вы видите часть бесконечной плоскости от (0,0) до (50,50) (при условии, что ваш видовой экран имеет 50 пикселей по ширине и высоте). ). Точно так же, если ваша область просмотра находится в (238 753), то вы видите часть бесконечной плоскости от (238, 753) до (288, 803).
Если ваши изображения 100х100, то ваша бесконечная плоскость будет выглядеть примерно так:
(-100,-100) (0,-100) (100,-100) (200,-100)
******************************************
* * * *
* * * *
* * * *
* * * *
*(-100,0) *(0,0) *(100,0) *(200,0)
******************************************
* * * *
* * * *
* * * *
* * * *
*(-100,100) *(0,100) *(100,100) *(200,100)
******************************************
* * * *
* * * *
* * * *
* * * *
*(-100,200) *(0,200) *(100,200) *(200,200)
******************************************
Теперь предположим, что в левом верхнем углу окна просмотра находится 75,75. Графически это будет выглядеть примерно так:
(-100,-100) (0,-100) (100,-100) (200,-100)
******************************************
* * * *
* * * *
* * * *
* * * *
*(-100,0) *(0,0) *(100,0) *(200,0)
******************************************
* * * *
* * * *
* * (75,75) * (125,75) *
* * ####### *
*(-100,100) *(0,100) # * # *(200,100)
************************#*****#***********
* * # * # *
* * ####### *
* * (75,125) * (125,125) *
* * * *
*(-100,200) *(0,200) *(100,200) *(200,200)
******************************************
В этом случае ваш видовой экран имеет углы в (75,75), (75,125), (125,75) и (125,125). Таким образом, вы видите нижний правый угол изображения с (0,0), нижний левый угол изображения с (100,0) и т. Д.
Теперь предположим, что вы реализовали функцию, которая вычисляет, в какой сетке находится конкретная точка. В частности, она возвращает верхний левый угол сетки, в которой находится эта точка. Несколько примеров:
gridContainingPoint(0,0) -> (0,0)
gridContainingPoint(50,50) -> (0,0)
gridContainingPoint(100,100) -> (100,100)
gridContainingPoint(123, -27) -> (100,-100)
Реализация этой функции довольно проста:
Point gridContainingPoint(Point pt) {
int newX = ((int)Math.floor(pt.x/100f)) * 100;
int newY = ((int)Math.floor(pt.y/100f)) * 100;
return new Point(newX, newY);
}
Теперь, чтобы определить, какие изображения вам нужно нарисовать, вы вызываете метод gridContainingPoint()
для каждого угла области просмотра. В этом примере вы получите:
gridContainingPoint(75,75) -> (0,0)
gridContainingPoint(75,125) -> (0,100)
gridContainingPoint(125,75) -> (100, 0)
gridContainingPoint(125,125) -> (100, 100)
Теперь вы точно знаете, какие изображения вам нужно нарисовать, чтобы полностью покрыть область просмотра.
Прежде чем рисовать изображения, вы должны правильно установить область просмотра. По умолчанию, когда вы начинаете рисовать на холсте, область просмотра располагается в (0,0). Таким образом, вы увидите только те вещи, которые нарисованы на холсте, в области (0,0) x (50,50). Однако мы хотим, чтобы область просмотра была расположена в (75,75), чтобы мы могли видеть вещи в области (75,75) x (125,125). Для этого вы вызываете метод Canvas.translate()
. Например, canvas.translate(-75,-75)
. Он должен быть отрицательным, поскольку он концептуально перемещает холст под областью просмотра, а не перемещает область просмотра.
Теперь, используя информацию из 4 вызовов к gridContainingPoint()
, вы рисуете свое изображение в (0,0), в (0,100), в (100, 0) и в (100, 100). И все готово:)
Несколько вещей, которые следует иметь в виду - числа, используемые в этом примере, не будут фактическими числами, которые вы хотите использовать.
Во-первых, размер вашего видового экрана не будет 50x50, но это будет фактический размер вашего вида на момент его отрисовки. Вы можете получить это с View.getWidth()
и View.getHeight()
.
Во-вторых, вам нужно настроить размер сетки и связанные с ней расчеты на основе размера вашего изображения - я сомневаюсь, что вы используете изображение размером 100x100.
И, наконец, имейте в виду, что когда вы вызываете метод gridContainingPoint()
для каждого из углов области просмотра, он может возвращать одну и ту же сетку для нескольких углов. Например, если ваш видовой экран был вместо этого в (25,25), то он вернул бы изображение (0,0) для каждого угла, потому что (25,25), (25,75), (75,25) и ( 75,75) все в пределах изображения от (0,0) до (100,100). Так что это будет единственное изображение, которое вы должны нарисовать, чтобы полностью покрыть область просмотра.