Android 参考可绘制尺寸并呈现彼此相邻的可绘制尺寸

Android 参考可绘制尺寸并呈现彼此相邻的可绘制尺寸,android,canvas,bitmap,rendering,Android,Canvas,Bitmap,Rendering,我正在制作一个使用2D瓷砖贴图的游戏。通过SurfaceView中的自定义方法doDraw()渲染贴图。它是一个简单的双for循环,从2D数组中获取平铺类型,确定该类型的对应位图,然后在指定坐标处将平铺绘制到画布 以前我在我的可绘图文件夹中有占位符.pngs。这些占位符绘图是我在ms paint中创建的简单的100x100.png纯色文件。在我用一些纹理精美的绘图工具替换占位符绘图工具之前,一切似乎都很顺利。然后我意识到我参考坐标绘制瓷砖的方式是不正确的,实际上导致了它们的重叠。当瓷砖为纯色时,

我正在制作一个使用2D瓷砖贴图的游戏。通过SurfaceView中的自定义方法doDraw()渲染贴图。它是一个简单的双for循环,从2D数组中获取平铺类型,确定该类型的对应位图,然后在指定坐标处将平铺绘制到画布

以前我在我的可绘图文件夹中有占位符.pngs。这些占位符绘图是我在ms paint中创建的简单的100x100.png纯色文件。在我用一些纹理精美的绘图工具替换占位符绘图工具之前,一切似乎都很顺利。然后我意识到我参考坐标绘制瓷砖的方式是不正确的,实际上导致了它们的重叠。当瓷砖为纯色时,这一点并不明显,但从纹理上看,瓷砖的两面明显被相邻的瓷砖覆盖

我相信问题实际上不在于我的doDraw()方法,而在于我引用瓷砖大小的方式。.png文件是100x100,但它们可能会根据设备的像素密度转换为不同的大小。我想这就是发生的事情,我一直在阅读如何处理它,但我在那里发现的一切通常都是关于一个位图,而不是许多需要相对绘制的小位图

以下是我的SurfaceView中的相关代码:

public class MapView extends SurfaceView implements SurfaceHolder.Callback {

protected Context context;
public World world;
public Map<Integer,Bitmap> TILE_MAP;
public Bitmap SPRITE;
public Player player;
public Camera camera;

//hardcoded parameters for testing
private int tile_width = 50;
private int tile_height = 50;
public int screen_width = 12; //specifies how many tiles to draw in y direction
public int screen_height = 6; //specifies how many tiles to draw in x direction

public MapThread mapThread; 

public MapView(Context context, AttributeSet attrs) {

    super(context, attrs);
    this.context = context;
    Log.d("LOGCAT", "MapView created"); 

    //get the tile map
    WorldFeatures worldFeatures = new WorldFeatures(context);       
    TILE_MAP = worldFeatures.TILE_MAP;
    SPRITE = worldFeatures.SPRITE;

    SurfaceHolder holder = getHolder();
    holder.addCallback(this);

}

public void doDraw(Canvas canvas) {

    /*the draw method looks a little muddled at the moment as my camera is referencing 
    the center tile instead of the top left tile. I'll be updating that soon*/

    int screenX = 0; //reset screenX each loop 

    for (int worldX = (camera.x - screen_height/2 + 1); worldX < (camera.x + screen_height/2 + 1); worldX += 1, screenX += 1) {

        int screenY = 0; //reset screenY each loop 

        for (int worldY = (camera.y - screen_width/2 + 1);  worldY < (camera.y + screen_width/2 + 1); worldY += 1, screenY += 1) {

            canvas.drawBitmap(TILE_MAP.get(world.world_map[worldX][worldY]), screenY*tile_height , screenX*tile_width, null);

            if (player.x == worldX && player.y == worldY) { //if the player is standing here, draw the sprite
                canvas.drawBitmap(SPRITE, screenY*tile_height + tile_height/5, screenX*tile_width + tile_width/5, null);

            }

        }
    }


}

    }
公共类MapView扩展了SurfaceView实现了SurfaceHolder.Callback{
受保护的语境;
公共世界;
公共地图;
公共位图精灵;
公共玩家;
公共摄像机;
//测试用硬编码参数
私人内部瓷砖宽度=50;
私人内部瓷砖高度=50;
public int screen_width=12;//指定在y方向上绘制的瓷砖数量
public int screen_height=6;//指定在x方向上绘制的瓷砖数量
公共映射线程映射线程;
公共地图视图(上下文、属性集属性){
超级(上下文,attrs);
this.context=上下文;
Log.d(“LOGCAT”、“创建的地图视图”);
//获取平铺图
WorldFeatures WorldFeatures=新的WorldFeatures(上下文);
TILE\u MAP=worldFeatures.TILE\u MAP;
SPRITE=worldFeatures.SPRITE;
SurfaceHolder holder=getHolder();
holder.addCallback(本);
}
公共虚空doDraw(画布){
/*当我的相机正在引用时,绘制方法看起来有点混乱
中间的磁贴而不是左上方的磁贴。我很快就会更新它*/
int screenX=0;//重置每个循环的screenX
对于(int worldX=(camera.x-屏幕高度/2+1);worldX<(camera.x+屏幕高度/2+1);worldX+=1,屏幕x+=1){
int screenY=0;//重置每个循环的屏幕
对于(int-worldY=(camera.y-屏幕宽度/2+1);worldY<(camera.y+屏幕宽度/2+1);worldY+=1,屏幕宽度+=1){
canvas.drawBitmap(TILE\u MAP.get(world.world\u MAP[worldX][worldY]),屏幕*TILE\u高度,屏幕*TILE\u宽度,null);
如果(player.x==worldX&&player.y==worldY){//如果玩家站在这里,画精灵
canvas.drawBitmap(精灵,屏幕*平铺高度+平铺高度/5,屏幕X*平铺宽度+平铺宽度/5,空);
}
}
}
}
}
正如你在上面看到的,我已经硬编码了瓷砖的高度和宽度。一个抽象的方法会很好,但首先我想了解使用的正确数字是什么。如果我将瓷砖的高度和宽度设置为100,则瓷砖之间会有间距。如果将它们设置为50,我将得到重叠。这告诉我正确的参考尺寸介于两者之间。我可以一直猜测,直到我猜对为止,但我想知道如何确定我的可绘制设备的缩放尺寸和像素密度

目前,我的drawables位于我的DrawableHDPI文件夹中,而不是其他任何地方。我想知道,如果我把它们放在一个通用的“可绘制”文件夹中,我是否能够将瓷砖高度和宽度参考为100x100?我已经阅读了关于获取内在高度和宽度的内容,但当位图为视图或设备缩放时,这并没有帮助。即使可以根据原始的可绘制尺寸以某种方式引用瓷砖尺寸,我认为应该有一种更好的方法,而不是通过任何特定的数字来引用它们。在我的绘图方法中,难道我不能找出缩放的大小吗?然后用它来确定画瓷砖的坐标?更好的是,在我将位图绘制到画布之前,有没有办法强制位图缩放到什么大小

我在上读过像素密度、dpi、可绘制文件夹等,但当我绘制瓷砖时,这并没有真正帮助我,因为它们彼此相对,因此需要坐标

我还研究了使用矩形绘制画布,因为画布的drawbitmap()方法将矩形作为输入不依赖于像素密度。但我不确定当我要画一组12x6的瓷砖时,使用矩形有多实际。每个瓷砖位置需要一个矩形吗


任何关于处理缩放位图的解释和/或更好的方法来绘制我正在绘制的内容都会非常有帮助。

在睡眠后回答了我自己的问题。要在android自动缩放位图后获取位图的高度,请在位图上使用getWidth()和getHeight()。要强制位图缩放到特定大小,请使用scaleBitmap()