我有一个益智游戏,其中棋盘是一个矩形,边框是由一个网格单位长的棋子组成的。我有一种方法可以随机化图像并将其环绕在水平面上,但是...这确实很糟糕。它具有最奇怪的错误:根据运行的Android版本,其行为会有所不同。在2.1上,活动开始时边界没有正确对齐,但是一旦移动了一块,边界就会自动修复。不是当一块移动时,而是当移动到另一个位置时(如果我将其拖动到屏幕上并将其放回同一位置,则不会发生任何事情)。实际放下一块物体(MotionEvent.ACTION_UP)时,边界将自行校正。在2.2中,它可以正确启动,但是当我加载一个新级别(它不启动新活动但再次调用createBorder)时,它的作用方式相同。看起来是这样的:
这是我的createBorder方法:
private void createBorder(int h, int w, int levelWidthUnits, int levelHeightUnits){
//This method could definitely use some work (understatement), but it's all right for the moment.
//int blankPiece = 0;
int bored = board.getId();
int lastBorder = 0;
int borderWidth = 0;
Matrix m90 = new Matrix();
m90.setRotate(90);
Matrix m180 = new Matrix();
m180.setRotate(180);
Matrix m270 = new Matrix();
m270.setRotate(270);
Bitmap bm1 = BitmapFactory.decodeResource(getResources(), getRandomBorderBitmap());
borderWidth = (int)(bm1.getHeight()/(bm1.getWidth()/((float)(w/levelWidthUnits))));
//Log.i(TAG, "borderWidth = "+borderWidth);
for(int counter=0;counter<levelWidthUnits;counter++){
Bitmap bm = BitmapFactory.decodeResource(getResources(), getRandomBorderBitmap());
Bitmap borderbm = Bitmap.createScaledBitmap(bm, (w/levelWidthUnits), borderWidth, true);
ImageView border = new ImageView(this);
border.setImageBitmap(borderbm);
border.setId(0x90000000+counter);
//border.setImageResource(R.drawable.border_tiki1);
//border.setAdjustViewBounds(true);
//border.setImageMatrix(matrixTop);
//border.setScaleType(ImageView.ScaleType.MATRIX);
LayoutParams params = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
if(counter==0){
params.addRule(RelativeLayout.ALIGN_LEFT, bored);
params.addRule(RelativeLayout.ABOVE, bored);
}else{
//Log.i(TAG, "lastBorder before added rule = "+lastBorder);//TODO Why does this only work for the 3rd through 6th pieces?!
params.addRule(RelativeLayout.RIGHT_OF, lastBorder); //This method works just fine for everything but the 2nd piece!
params.addRule(RelativeLayout.ABOVE, bored); //And even for the 2nd piece, this line works! Just not the one above.
}
border.setLayoutParams(params);
game_view.addView(border);
lastBorder = border.getId();
//Log.i(TAG, "lastBorder set to: "+lastBorder);
}
Bitmap cbm = BitmapFactory.decodeResource(getResources(), Theme.getBorderCorner());
Bitmap cornerbm1 = Bitmap.createScaledBitmap(cbm, borderWidth, borderWidth, true);
Bitmap cornerbm = Bitmap.createBitmap(cornerbm1, 0, 0, borderWidth, borderWidth, m90, true);
ImageView border1 = new ImageView(this);
border1.setImageBitmap(cornerbm);
border1.setId(lastBorder+1);
LayoutParams params = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.RIGHT_OF, lastBorder);
params.addRule(RelativeLayout.ABOVE, bored);
border1.setLayoutParams(params);
game_view.addView(border1);
lastBorder = border1.getId();
for(int counter=0;counter<levelHeightUnits;counter++){
Bitmap bm2 = BitmapFactory.decodeResource(getResources(), getRandomBorderBitmap());
Bitmap borderbm2 = Bitmap.createScaledBitmap(bm2, (h/levelHeightUnits), borderWidth, true);
Bitmap borderbm1 = Bitmap.createBitmap(borderbm2, 0, 0, (h/levelHeightUnits), borderWidth, m90, true);
ImageView border = new ImageView(this);
border.setImageBitmap(borderbm1);
border.setId(lastBorder+1);
LayoutParams params2 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
params2.addRule(RelativeLayout.RIGHT_OF, bored);
params2.addRule(RelativeLayout.BELOW, lastBorder);
border.setLayoutParams(params2);
((ViewGroup) findViewById(R.id.game_view)).addView(border);
lastBorder = border.getId();
/*if(counter==2){
blankPiece = border.getId();
}*/
//Log.i(TAG, "lastBorder set to: "+lastBorder);
}
Bitmap cbm2 = BitmapFactory.decodeResource(getResources(), Theme.getBorderCorner());
Bitmap cornerbm21 = Bitmap.createScaledBitmap(cbm2, borderWidth, borderWidth, true);
Bitmap cornerbm2 = Bitmap.createBitmap(cornerbm21, 0, 0, borderWidth, borderWidth, m180, true);
ImageView border2 = new ImageView(this);
border2.setImageBitmap(cornerbm2);
border2.setId(lastBorder+1);
LayoutParams params1 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
params1.addRule(RelativeLayout.ALIGN_LEFT, lastBorder);
params1.addRule(RelativeLayout.BELOW, lastBorder);
border2.setLayoutParams(params1);
((ViewGroup) findViewById(R.id.game_view)).addView(border2);
lastBorder = border2.getId();
for(int counter=0;counter<levelWidthUnits;counter++){
Bitmap bm2 = BitmapFactory.decodeResource(getResources(), getRandomBorderBitmap());
Bitmap borderbm2 = Bitmap.createScaledBitmap(bm2, (h/levelHeightUnits), borderWidth, true);
Bitmap borderbm1 = Bitmap.createBitmap(borderbm2, 0, 0, (h/levelHeightUnits), borderWidth, m180, true);
ImageView border = new ImageView(this);
border.setImageBitmap(borderbm1);
border.setId(lastBorder+1);
LayoutParams params2 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
params2.addRule(RelativeLayout.ALIGN_TOP, lastBorder);
params2.addRule(RelativeLayout.LEFT_OF, lastBorder);
border.setLayoutParams(params2);
((ViewGroup) findViewById(R.id.game_view)).addView(border);
lastBorder = border.getId();
//Log.i(TAG, "lastBorder set to: "+lastBorder);
}
Bitmap cbm3 = BitmapFactory.decodeResource(getResources(), Theme.getBorderCorner());
Bitmap cornerbm31 = Bitmap.createScaledBitmap(cbm3, borderWidth, borderWidth, true);
Bitmap cornerbm3 = Bitmap.createBitmap(cornerbm31, 0, 0, borderWidth, borderWidth, m270, true);
ImageView border3 = new ImageView(this);
border3.setImageBitmap(cornerbm3);
border3.setId(lastBorder+1);
LayoutParams params2 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
params2.addRule(RelativeLayout.ALIGN_TOP, lastBorder);
params2.addRule(RelativeLayout.LEFT_OF, lastBorder);
border3.setLayoutParams(params2);
((ViewGroup) findViewById(R.id.game_view)).addView(border3);
lastBorder = border3.getId();
for(int counter=0;counter<levelHeightUnits;counter++){
Bitmap bm2 = BitmapFactory.decodeResource(getResources(), getRandomBorderBitmap());
Bitmap borderbm2 = Bitmap.createScaledBitmap(bm2, (h/levelHeightUnits), borderWidth, true);
Bitmap borderbm1 = Bitmap.createBitmap(borderbm2, 0, 0, (h/levelHeightUnits), borderWidth, m270, true);
ImageView border = new ImageView(this);
border.setImageBitmap(borderbm1);
border.setId(lastBorder+1);
LayoutParams params3 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
params3.addRule(RelativeLayout.LEFT_OF, bored);
params3.addRule(RelativeLayout.ABOVE, lastBorder);
border.setLayoutParams(params3);
((ViewGroup) findViewById(R.id.game_view)).addView(border);
lastBorder = border.getId();
//Log.i(TAG, "lastBorder set to: "+lastBorder);
}
Bitmap cbm4 = BitmapFactory.decodeResource(getResources(), Theme.getBorderCorner());
Bitmap cornerbm41 = Bitmap.createScaledBitmap(cbm4, borderWidth, borderWidth, true);
Bitmap cornerbm4 = Bitmap.createBitmap(cornerbm41, 0, 0, borderWidth, borderWidth, null, true);
ImageView border4 = new ImageView(this);
border4.setImageBitmap(cornerbm4);
border4.setId(lastBorder+1);
LayoutParams params3 = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
params3.addRule(RelativeLayout.ALIGN_LEFT, lastBorder);
params3.addRule(RelativeLayout.ABOVE, lastBorder);
border4.setLayoutParams(params3);
((ViewGroup) findViewById(R.id.game_view)).addView(border4);
lastBorder = border4.getId();
}
放下一块时,它会测试是否移动。如果有,它将调用
counter.setText("Total moves: " + moves); //counter is a TextView
我认为这是导致布局自行修复的原因(也许是通过要求屏幕重新绘制自身来实现的)。我正在寻找解决我遇到的奇怪故障的方法,但是如果您对如何包装这些随机的边界部分有更好的建议,我将很高兴听到它! (请注意:将来,我希望水平不是矩形,但仍然只有90度角)。谢谢您的帮助!这是我和发布游戏之间的最后错误!
最佳答案
我同意Gangnus在这种情况下重画所有内容。
我之所以要回答,主要是因为“如果您对如何包装这些随机的边框有更好的建议,我将很高兴听到它!”部分。这并不是说您的代码很糟糕,但您是对的,如果您想执行非矩形地图,则需要做一些工作。至少这是我的主意。
我将从布尔级别“地图”开始定义哪些是“木板”和“非木板”正方形。
在基本功能中,遍历每个图块。检查每侧是否有“活动”磁贴。如果是这样,请使用所需的位置和旋转度调用addBorder()
函数。
void createBorders(int widthUnits, int heightUnits, boolean[][] activeMap) {
for(int x=0;x<widthUnits;x++) {
for(int y=0;y<heightUnits;y++) {
if(!activeMap[x][y]) // boolean "map" (true if active)
continue;
if(x == 0)
addBorder(LEFT, x, y);
else if(!activeMap[x-1][y])
addBorder(LEFT, x, y);
if(x == widthUnits-1)
addBorder(RIGHT, x, y);
else if(!activeMap[x+1][y])
addBorder(RIGHT, x, y);
if(y == 0)
addBorder(TOP, x, y);
else if(!activeMap[x][y-1])
addBorder(TOP, x, y);
if(y == heightUnits-1)
addBorder(BOTTOM, x, y);
else if(!activeMap[x][y+1])
addBorder(BOTTOM, x, y);
}
}
}
在
addBorder()
函数中,获得图块的左侧和顶部位置,如左侧的(board.left + (tile.width * x))
所示,与顶部相似。然后,您可以
switch(where)
旋转矩阵,调整位图的大小,并根据需要从图块的基本位置调整位置。那是我无论如何都会做的事情。这样,它适用于任何基于图块的地图,即使是具有内部非活动区域的图,也无需像现在使用的那样硬编码“边缘”。