java - Android - Canvas onDraw 具有跟随角色移动的缩放相机

标签 java android camera android-canvas

一些上下文:

我正在创建一个 Android 游戏,它根据背景图像在 Canvas 上绘制一个迷宫,它使用一个方 block ,因此迷宫总是自动放大到 5 x 5 的正方形,而迷宫可能是 20 x 20. 通过简单地运行一组 for 循环然后在相关位置画线来绘制迷宫。这一切都工作得很好,但是我在让我的 onDraw 顺利工作方面遇到了问题。发生这种情况是因为每次我使无效时我都必须重新运行 for look 并运行各种 if 语句来检查位置(不幸的是这个过程无法改进)。

问题:

我希望重写迷宫在 Canvas 上的绘制方式,以下是我需要实现的 3 个主要功能:

1 - 将整个迷宫绘制到 Canvas 上(这很简单) 2 - 放大迷宫,只显示 5 x 5 3 - 移动角色(始终位于屏幕中心)并绘制迷宫的下一个部分

现在如上所述,绘制整个迷宫非常容易,并且会使 onDraw 显着加快,因为它们不需要在 invaldate 上运行 for 循环,它可以在第一次加载关卡时完成一次。

就第 2 点和第 3 点而言,我认为这种工作方式是在 Canvas 中间绘制角色,然后将 2d 鸟瞰图摄像机附加/链接到角色运动。该相机还需要放大到只显示整个迷宫网格的 5 x 5 的程度。然后当角色移动时,相机会随着角色移动并显示已经绘制的迷宫的下一部分。我已经尝试了一些事情并做了一些研究,但是我以前从未使用过 Canvas ,也不知道从哪里开始,甚至不知道这是否可能。

因此,总结问题的主要部分是,它们是否是一种将鸟瞰相机链接到放大并随角色图像移动的角色的方法。

下面是关于当前如何绘制迷宫的 fragment ,使用 2 组 for 循环检查 2 组 boolean 数组 [][],它们仅存储要绘制的垂直线和水平线。

@Override
protected void onDraw(Canvas canvas) 
{
    canvas.drawRect(0, 0, width, 100, background);
    RectBackground.set(0,0, FullScreenWidth, FullScreenWidth);
    canvas.drawBitmap(gameBackground, null, RectBackground, null);

    for(int i = 0; i < 5; i++) 
    {
        for(int j = 0; j < 5; j++)
        {
            float x = j * totalCellWidth;
            float y = i * totalCellHeight;

            indexY = i + currentY;
            indexX = j + currentX;

            // Draw Verticle line (y axis)
            if (indexY < vLength && indexX < vLines[indexY].length && vLines[indexY][indexX])
            {
                RectOuterBackground.set((int)x + (int)cellWidth, (int)y, (int)x + (int)cellWidth + 15,  (int)y + (int)cellHeight + 15);
                canvas.drawBitmap(walls, null, RectOuterBackground, null);
            }
            // Draws Horizontal lines (x axis)
            if (indexY < hLength && indexX < hLines[indexY].length && hLines[indexY][indexX])
            {
                RectOuterBackground.set((int)x, (int)y + (int)cellHeight,(int)x + (int)cellWidth + 15,(int)y + (int)cellHeight + 15);
                canvas.drawBitmap(walls, null, RectOuterBackground, null);
            }
        }
    }
}

最佳答案

为了加快绘图速度,您可以通过直接绘制到位图中并将位图闪烁到 Canvas 中来双重缓冲 Canvas 。速度非常快。

private void init()
{
        //variables below are class-wide variables
        b = Bitmap.createBitmap(cwidth, cheight, Bitmap.Config.ARGB_8888);
        bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        bitmapPaint.setStyle(Paint.Style.STROKE);

        bitmapPaint.setStrokeWidth(3);
        myPaint.setColor(0xff000000);
        myCanvas = new Canvas(b);
}

protected void onDraw(Canvas c)
{
    super.onDraw(c);
    c.drawBitmap(b, 0, 0, myPaint);

    for(int i = 0; i < number lines; i++)
    {
        //draw here using myPath
    }

    if(b != null)
        c.drawBitmap(b, 0, 0, myPaint);

    myCanvas.drawPath(myPath, bitmapPaint);

}

然后,为了“四处移动”,我建议使用裁剪框。这意味着 1:1 比例,图像比屏幕上显示的视口(viewport)大。当有人“移动”时,真正发生的是位图被移动到裁剪框下方。

您可以使用 BitmapRegionDecoder 并仅显示字符所在的区域(这可能会很慢)或使用

public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint)

此处的 src 参数允许您指定要显示的位图的一个小区域。它实际上是一个裁剪框。

关于java - Android - Canvas onDraw 具有跟随角色移动的缩放相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20199613/

相关文章:

android-layout - 在不移动操作栏的情况下在 Activity 之间转换

android - 在webview中拦截下载并使用HttpClient下载

java - 相机 Intent 使 Android 应用程序不断崩溃

java - 如何在用户首选浏览器中打开网页作为 Java 中的发布请求

java - 创建安全的java应用程序

java - 使用 openSAML 签署响应

objective-c - AVCaptureSession预设照片和AVCaptureVideoPreviewLayer大小

Java + readLine 和 BufferedReader

Android - AdMob 点击次数

ios - 从弹出窗口打开全屏模式时,相机的屏幕位置不正确