Java-沿任何方向连续滚动一个大型无缝图像

Java-沿任何方向连续滚动一个大型无缝图像,第1张

概述这个问题与游戏相关,但我认为它可以应用于其他用例.我有一个比屏幕大的无缝图像.大约两倍大.目的是使该图像可以在表面上的任何方向滚动.这是针对Android的.我已经看到了一些有关图像的问题/答案,但没有无缝图像.这里的区别和我的问题是,当在某些点上显示有4个单独的图像时(当用

这个问题与游戏相关,但我认为它可以应用于其他用例.

我有一个比屏幕大的无缝图像.大约两倍大.目的是使该图像可以在表面上的任何方向滚动.这是针对Android的.

我已经看到了一些有关图像的问题/答案,但没有无缝图像.

这里的区别和我的问题是,当在某些点上显示有4个单独的图像时(当用户对角滚动一半时,如何处理滚动).

当您要边缘滚动图像时,如何做到这一点非常明显.使用世界值,并使用矩形显示您所在位置的某种“视口”.

就像是:

Rect oRect1 = new Rect(DWorldX, DWorldY, DWorldX + canvas.getWIDth(), DWorldY + canvas.getHeight());Rect oRect2 = new Rect(0, 0, canvas.getWIDth(), canvas.getHeight());canvas.drawBitmap(largeBitmapTexture, oRect1, oRect2, new Paint());

但是,当位图是无缝的并且连续滚动时,这对我来说是一个编程难题.我是否使用一堆if语句?有没有做这种事情的更有效方法?

编辑:更多的想法.这里的一个复杂之处是世界(x,y)无限大.因此,我必须使用屏幕宽度和高度的划分来显示需要显示的内容.我最初考虑的是Rect的4次迭代,因为屏幕上的图像永远不会超过4张.如果那有意义的话.我想我对如何计算有点模糊.

编辑:这是我现在的代码,并带有@glowcoder的建议.

public voID draw(Canvas canvas){    int iImagesOverX=0;    int iImagesOverY=0;    iImagesOverX = (int)dX / mCloud.getIntrinsicWIDth();    iImagesOverY = (int)dY / mCloud.getIntrinsicHeight();    mCloud.setBounds(iImagesOverX * (int)mCloud.getIntrinsicWIDth() , iImagesOverY * (int)mCloud.getIntrinsicHeight() , (iImagesOverX * (int)mCloud.getIntrinsicWIDth()) + mCloud.getIntrinsicWIDth() ,  (iImagesOverY * (int)mCloud.getIntrinsicHeight()) + mCloud.getIntrinsicHeight() );    Log.d(TAG, "bounds:"+ mCloud.getBounds());    mCloud.draw(canvas);    mCloud.setBounds((iImagesOverX + 1) * (int)mCloud.getIntrinsicWIDth() , iImagesOverY * (int)mCloud.getIntrinsicHeight() , ((iImagesOverX + 1) * (int)mCloud.getIntrinsicWIDth()) + mCloud.getIntrinsicWIDth() ,  (iImagesOverY * (int)mCloud.getIntrinsicHeight()) + mCloud.getIntrinsicHeight() );    mCloud.draw(canvas);    mCloud.setBounds((iImagesOverX + 1) * (int)mCloud.getIntrinsicWIDth() , (iImagesOverY + 1)* (int)mCloud.getIntrinsicHeight() , ((iImagesOverX + 1) * (int)mCloud.getIntrinsicWIDth()) + mCloud.getIntrinsicWIDth() ,  ((iImagesOverY + 1) * (int)mCloud.getIntrinsicHeight()) + mCloud.getIntrinsicHeight() );    mCloud.draw(canvas);    mCloud.setBounds((iImagesOverX) * (int)mCloud.getIntrinsicWIDth() , (iImagesOverY + 1)* (int)mCloud.getIntrinsicHeight() , ((iImagesOverX) * (int)mCloud.getIntrinsicWIDth()) + mCloud.getIntrinsicWIDth() ,  ((iImagesOverY + 1) * (int)mCloud.getIntrinsicHeight()) + mCloud.getIntrinsicHeight() );    mCloud.draw(canvas);    Log.d(TAG, "imagesoverx:"+ iImagesOverX);}

我必须将dX和dY添加到边界以使图像移动.但是,一旦向右移了一个“平铺”,就不会出现第三个图块.

因此,这在一定程度上是可行的,但并不是我需要的.有4个面板,但这仅是因为边界和绘制的4个实例.无论我们在x和y所在的位置如何,我都需要这4个面板来绘制它们所需的位置.

解决方法:

基本思想是,您有一个无限的平面,其中包含在各个方向上一遍又一遍重复的图像.然后有一个“视口”-您可以将其视为限制无限平面视图的窗口.换句话说,视口“下方”的无限平面区域实际上是屏幕上显示的区域.

因此,当视口的左上角为(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).它必须为负数,因为它是在概念上将画布移动到视口下方,而不是移动视口.

现在,使用来自对grIDContainingPoint()的4次调用的信息,您可以在(0,0),(0,100),(100,0)和(100,100)处绘制图像.你完成了:)

注意事项-本示例中使用的数字将不是您要使用的实际数字.

一方面,视口的大小不会是50×50,但将是绘制时视口的实际大小.您可以使用VIEw.getWIDth()和VIEw.getHeight()来获得它.

其次,您需要根据图像大小调整网格大小和相关计算-我怀疑您使用的是100×100的图像.

最后,请记住,当为视口的每个角调用grIDContainingPoint()方法时,它可能为多个角返回相同的网格.例如,如果视口改为(25,25),则它将为每个角返回(0,0)图像,因为(25,25),(25,75),(75,25)和( 75,75)都在(0,0)至(100,100)的图像中.因此,这是您必须绘制的唯一图像,以完全覆盖视口.

总结

以上是内存溢出为你收集整理的Java-沿任何方向连续滚动一个大型无缝图像全部内容,希望文章能够帮你解决Java-沿任何方向连续滚动一个大型无缝图像所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/1083867.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存