Java 绘制基于平铺的地图
此脚本绘制控件、英雄、曲面和地图:Java 绘制基于平铺的地图,java,android,bitmap,drawable,Java,Android,Bitmap,Drawable,此脚本绘制控件、英雄、曲面和地图: public void render(Canvas canvas) { canvas.drawColor(Color.TRANSPARENT); Drawable myImage; int tileWidth = 50; int tileHeight = 50; int rowBaseX = 0; int rowBaseY = 0; int[
public void render(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
Drawable myImage;
int tileWidth = 50;
int tileHeight = 50;
int rowBaseX = 0;
int rowBaseY = 0;
int[][] board = new int[][] {
{0,0,0,0,0,0,2,0,0,0,},
{0,0,0,0,0,2,2,0,0,0,},
{0,0,0,0,0,2,0,0,0,0,},
{0,0,0,0,0,2,0,0,0,0,},
{0,0,0,2,2,2,0,0,0,0,},
{0,0,0,2,0,0,0,0,0,0,},
{0,0,0,2,0,0,0,0,0,0,},
{0,0,2,2,0,0,0,0,0,0,},
{0,0,2,0,0,0,0,0,0,0,},
{0,0,2,0,0,0,0,0,0,0,}
};
int mapWidth = 10;
int mapHeight = 10;
for (int row = 0; row < mapHeight; row++)
{
for (int col = 0; col < mapWidth; col++)
{
Resources res = this.getContext().getResources();
switch(board[row][col])
{
case 0:
myImage = res.getDrawable(R.drawable.tile1);
break;
case 1:
myImage = res.getDrawable(R.drawable.tile2);
break;
default:
myImage = res.getDrawable(R.drawable.tile3);
break;
}
int curL = rowBaseX + (col * tileWidth);
int curU = rowBaseY + (row * tileHeight);
int curR = curL + tileWidth;
int curD = curU + tileHeight;
myImage.setBounds(curL,curU,curR,curD);
myImage.draw(canvas);
}
}
droid.draw(canvas);
butt.draw(canvas);
butt1.draw(canvas);
butt2.draw(canvas);
butt3.draw(canvas);
buttz.draw(canvas);
buttz1.draw(canvas);
buttz2.draw(canvas);
buttz3.draw(canvas);
buttx.draw(canvas);
}
public void渲染(画布){
画布。drawColor(颜色。透明);
可绘制图像;
int tileWidth=50;
int-tileHeight=50;
int rowBaseX=0;
int rowBaseY=0;
int[][]板=新int[][]{
{0,0,0,0,0,0,2,0,0,0,},
{0,0,0,0,0,2,2,0,0,0,},
{0,0,0,0,0,2,0,0,0,0,},
{0,0,0,0,0,2,0,0,0,0,},
{0,0,0,2,2,2,0,0,0,0,},
{0,0,0,2,0,0,0,0,0,0,},
{0,0,0,2,0,0,0,0,0,0,},
{0,0,2,2,0,0,0,0,0,0,},
{0,0,2,0,0,0,0,0,0,0,},
{0,0,2,0,0,0,0,0,0,0,}
};
int mapWidth=10;
int MAPHEIGH=10;
对于(int row=0;row
有一个英雄,当玩家用控制键移动他时,他必须被重画,所有其他的可画人物也必须被重画。问题是绘制地图是一个很长的过程,所以我创建的地图越大,英雄的移动速度就越慢,因为地图的每一块都必须绘制。是否有一种方法可以将所有平铺放在另一种方法中的一个位图上,并在画布方法中绘制该位图?如果在应用程序外部创建静态贴图不是一个选项,则可以将静态内容的绘制与动态内容的绘制分开 创建一个
位图
,用它创建一个画布
,并在该画布
上绘制地图。你只需要做一次。在另一个画布上,每帧渲染一次动态内容。
然后在SurfaceView
的“real”Canvas
上绘制这两个位图。它可能是这样的:
每个地图零件显示一次:
Bitmap mapBitmap = Bitmap.createBitmap(width, height, myConfig);
Canvas c = new Canvas(mapBitmap);
//draw map on c
…以及每帧一次的零件:
//draw dynamic stuff
Canvas canvas = getHolder().lockCanvas();
canvas.drawBitmap(mapBitmap, null, targetRect, null);
canvas.drawBitmap(heroBitmap, null, targetRect, null);
getHolder().unlockCanvasAndPost();
编辑:
您可以像使用myImage.draw(canvas)
一样绘制平铺,但将mapBitmap-canvas
作为参数传递,而不是“真实”画布<代码>myConfig
必须是一个。采用内部格式的RGB_565
。最好的选择是只绘制屏幕上可见的地图部分。这样,无论整个地图变得多大,该地图的绘制始终是恒定的。由于您处于网格系统中,您可以轻松确定英雄所在的单元:
heroGridX = hero.x % mapWidth;
heroGridY = hero.y % mapHeight;
从这里,您可以使用画布的宽度和高度以及网格单元的宽度和高度的恒定大小来计算要在播放器周围绘制的单元数:
leftGrid = heroGridX - (canvas.getWidth() / tileWidth) / 2;
topGrid = heroGridY - (canvas.getHeight() / tileHeight) / 2;
rightGrid = heroGridX + (canvas.getWidth() / tileWidth) / 2;
bottomGrid = heroGridY + (canvas.getHeight() / tileHeight) / 2;
您可以使用数据结构独立于英雄存储这些值,并且仅在玩家靠近边缘滚动地图时移动这些值。这样,英雄就可以上下移动,而无需滚动地图,直到他们将X或Y像素移动到平铺边缘为止。而不是在渲染例程中计算这些
这将使用比将整个地图绘制成一个大位图少得多的内存。绘制一个大的位图是用更少的CPU时间换取更多的内存使用。随着地图变大,绘制地图所需的内存也会随之增大。这种算法只是保持绘制地图的恒定,因为屏幕的大小在运行时不会改变。而且,与另一个选项相比,随着地图的增大,内存使用量不会增加(与在画布中绘制更多的分幅相比,内存使用量会变得非常小)。关于这一点,一个重要的事实是,如果你确实得到了更大的屏幕(比如平板电脑和手机)。此算法也将适当放大,以便玩家可以看到地图周围的更多地形。但是如何将地图分幅放入地图位图?我必须写一些关于myConfig?的istead@Liukas我已经编辑了答案以包含它。我希望这能使事情更清楚`抱歉,我使用了另一种解决方案。你们可以在另一个问题上帮助我:)@Liukas-当然,正如查伯德所说,这是CPU时间和RAM之间的折衷。chubbard的解决方案适用于比屏幕大得多的地图,与我的解决方案不同,它也适用于动态地图。我的解决方案要快得多,但一旦地图变大,就不现实了。我不是说你的解决方案不好;)无论如何,我需要大地图的最快解决方案,因为chubbards的解决方案仍然很慢…:/