我有一个益智游戏,其中棋盘是一个矩形,边框由一个网格单位长的部分组成。我有一种方法可以随机化图像并将它们包裹在关卡中,但是......这真的非常糟糕。它有最奇怪的错误:根据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度角)。谢谢您的帮助!这是我和发布游戏之间的最后一个错误!
答案 0 :(得分:1)
我同意Gangnus在这种情况下重新绘制所有内容。
我回复的主要原因是“如果你对如何包装这些随机边框有更好的建议,我会很高兴听到它!”部分。这并不是说你的代码那么糟糕,但如果你想做非矩形地图,那你就需要做一些工作。这是我的想法,至少。
我从一个布尔级别的“map”开始,定义哪个是“board”和“non-board”正方形。
在基本功能中,循环遍历每个图块。检查每侧是否有“活动”瓷砖。如果是,请使用所需的位置和旋转调用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)
,旋转矩阵,调整位图大小,并根据需要从平铺的基本位置调整位置。
无论如何,这就是我的方式。这样,它适用于任何基于图块的地图,即使是具有内部非活动区域的地图,也没有像您现在使用的硬编码“边缘”。
答案 1 :(得分:0)
我在2.2中使用bkg图像查看了类似的问题。在LinearLayout中。我知道的唯一方法是接受默认布局无法正常工作并通过代码重绘所有内容。