Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何滚动屏幕内存位图_Java_Android_Bitmap_Scroll_Surfaceview - Fatal编程技术网

Java 如何滚动屏幕内存位图

Java 如何滚动屏幕内存位图,java,android,bitmap,scroll,surfaceview,Java,Android,Bitmap,Scroll,Surfaceview,使用下面的代码滚动 我有一个Surfaceview线程和一个正在生成(更改)的非画布纹理位图,第一行(线),每帧,然后在常规Surfaceview位图上复制一个位置(线)以产生滚动效果,然后我继续在上面绘制其他东西。这就是我真正想要的,但是我不能让它工作,即使我正在为屏幕外位图创建一个单独的画布。它根本不滚动 换句话说,我有一个内存位图,与Surfaceview画布大小相同,我需要每帧向下滚动一行,然后用新的随机纹理替换顶行,然后在常规Surfaceview画布上绘制 以下是我认为有效的方法 我

使用下面的代码滚动 我有一个Surfaceview线程和一个正在生成(更改)的非画布纹理位图,第一行(线),每帧,然后在常规Surfaceview位图上复制一个位置(线)以产生滚动效果,然后我继续在上面绘制其他东西。这就是我真正想要的,但是我不能让它工作,即使我正在为屏幕外位图创建一个单独的画布。它根本不滚动

换句话说,我有一个内存位图,与Surfaceview画布大小相同,我需要每帧向下滚动一行,然后用新的随机纹理替换顶行,然后在常规Surfaceview画布上绘制

以下是我认为有效的方法

我的表面更改了指定位图和画布以及开始线程的位置:

@Override
    public void surfaceCreated(SurfaceHolder holder) {
    intSurfaceWidth = mSurfaceView.getWidth();
    intSurfaceHeight = mSurfaceView.getHeight();

    memBitmap = Bitmap.createBitmap(intSurfaceWidth, intSurfaceHeight,
            Bitmap.Config.ARGB_8888);
    memCanvas = new Canvas(memCanvas);

    myThread = new MyThread(holder, this);
    myThread.setRunning(true);
    blnPause = false;
    myThread.start();
}
我的线程,仅显示基本的中间运行部分:

@Override
public void run() {
  while (running) {     
    c = null;
try {
    // Lock canvas for drawing
    c = myHolder.lockCanvas(null);                  

    synchronized (mSurfaceHolder) {
        // Scroll down off screen canvas and hopefully underlying bitmap bitmap
        Rect src = new Rect(0, 0, intSurfaceWidth, intSurfaceHeight - 1);
        Rect dst = new Rect(0, 1, intSurfaceWidth, intSurfaceHeight);
        memCanvas.drawBitmap(memBitmap, src, dst, null);

        // Note scrolling up like this works fine
        // Rect src = new Rect(0, 1, intSurfaceWidth, intSurfaceHeight + 1);
        // Rect dst = new Rect(0, 0, intSurfaceWidth, intSurfaceHeight);
        // memCanvas.drawBitmap(memBitmap, src, dst, null);

        // Create random one line(row) texture bitmap
        textureBitmap = Bitmap.createBitmap(imgTexture, 0, rnd.nextInt(intTextureImageHeight), intSurfaceWidth, 1);

        // Now add this texture bitmap to top of screen canvas and hopefully underlying bitmap
        memCanvas.drawBitmap(textureBitmap,
                intSurfaceWidth, 0, null);

        // Draw above updated off screen bitmap to regular canvas, at least I thought it would update (save changes) shifting down and add the texture line to off screen bitmap the off screen canvas was pointing to.
        c.drawBitmap(memBitmap, 0, 0, null);

        // Other drawing to canvas comes here


    } finally {
        // do this in a finally so that if an exception is thrown
        // during the above, we don't leave the Surface in an
        // inconsistent state
        if (c != null) {
            myHolder.unlockCanvasAndPost(c);
        }
    }
}       
}

对于我的游戏隧道运行,现在我有一个有效的解决方案,我有一个位图数组,表面高度的大小,我用我的随机纹理填充,然后在每个帧的循环中向下移动。我每秒获得50帧,但我认为我可以通过滚动位图来做得更好

画布中有一个drawBitmap函数,其签名如下:

public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint);
您可以将dst设置为画布的大小,并且可以将src设置为新的

 Rect(0,offset,width,height+offset)

然后,您可以增加每一帧的偏移量,并在视图中获得一个平滑滚动的位图。

您正在尝试在其上方绘制位图,这在Android AFAIK上从未起过作用。我的第一个游戏,一个叫做鼹鼠矿工的侧滚游戏,正好掉进了这个洞里

问题很简单:drawBitmap()本质上是一种特殊的memcpy(),其中字节总是向前寻址。这很好,并以最佳方式使用一级缓存,等等,但是如果源和目标区域(a)重叠,以及(b)源地址<目标地址,显然会遇到问题

(顺便说一句,memcpy()的实际实现,检查这种可能性,并在必要时向后复制。Canvas.drawBitmap()不会这样做。)


我为Mole Miner使用的解决方法是使用两个屏幕外位图,并在交替帧上在它们之间切换。但那是在2009年,现在我可能根本不会使用滚动了。

谢谢你的建议。我已经试过了,看到上面的代码更改,因为它不适合这里,但本质上它以错误的方式滚动位图,并且将偏移量反转为-1不会使它向下滚动在您的示例中,我认为您的源和目标可能是向后的。源是您正在查看的位图区域,目标是显示器上的区域。另外,你向下滚动的代码是什么?好的,我理解我添加的注释可能会让人困惑,所以让我修改原始代码并去掉附加内容。这就是我逻辑上认为应该使用drawBitmap Rect Src和Dst将当前(源)位图从第一行向下移动到底部上方的一行的方式,并将其向下移动一个位置,到(目的地)第一行;Rect src=new Rect(0,0,intSurfaceWidth,intsurfacewhight-1);Rect dst=新的Rect(0,1,内表面宽度,内表面高度);drawBitmap(memBitmap、src、dst、null);完全脱离主题,但你在市场上的应用程序描述是全文,没有段落,什么都没有。。。你应该组织它!第一个想法是:很好的建议,添加段落,谢谢,但不确定“全文……没有什么”是什么意思。这是一个纯文本字段,我无法向其中添加图像。是的,但您的文本格式非常难看。我不希望在描述中有完整的“如何使用/播放”指南。把它想象成一个广告文本。在列表中总结一些很酷的功能,让读者对你的游戏感兴趣。是的,我觉得这是一个bug/糟糕的实现。今天晚些时候,我将尝试两个屏幕外位图,并在它们之间切换,如果它有效,我相信你的答案,谢谢!如果你只朝一个方向(向下)滚动,你可以改变它,这样你就可以把位图上下颠倒,然后向上滚动。如果dest