2011-06-03 71 views
2

我有一个益智游戏,其中棋盘是一个矩形,边框是由一个网格单元长的棋子组成。我有一种方法可以将图像随机化并将它们包裹在关卡中,但是......这真的很糟糕。它有最奇怪的错误:根据Android的运行版本,它的行为有所不同。在2.1上,当活动开始时,边界并没有正确对齐,但是只要一块被移动,它们就会自行修复。不是当一块棋子移动时,而是当它移动到另一个位置时(如果我将它拖过屏幕并将它放回到同一个点,则不会发生)。当片断实际被放下(MotionEvent.ACTION_UP)时,边框自行纠正。在2.2中它正确启动,但是当我加载一个新的级别(它不会启动一个新的活动,但再次调用createBorder)时,它的行为方式是一样的。这里是什么样子:RelativeLayout在运行时的变化

enter image description here

这里是我的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度角)。谢谢您的帮助!这是我和我发布游戏的最后一个bug!

回答

1

我同意Gangnus在这种情况下重绘所有内容。

我回复的主要原因是“如果你对如何包装这些随机边框有更好的建议,我会很高兴听到它!”部分。这并不是说你的代码很糟糕,但你说得对,如果你想做非矩形的地图,它需要一些工作。至少这是我的想法。

我会从一个布尔等级“map”开始,以定义哪个是“board”和“non-board”正方形。

在基函数中,遍历每个tile。检查每边是否有“活动”瓷砖。如果是这样,请调用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),旋转矩阵,调整位图的大小,并根据需要调整瓷砖基本位置的位置。

这就是我反正做这件事的方式。这种方式适用于任何基于瓦片的地图,即使是具有内部非活动区域的地图,也不需要像现在使用的硬编码“边缘”。

+0

谢谢,这是一个很好的建议!而且它应该很容易实现,因为我的Level类存储所有块的信息和每个级别的大小已经输出相似的数组。 – Amplify91 2011-06-03 14:43:17

+0

我已经开始实施这种方法,它的工作很棒!我仍在调整它的像素完美,但是当我完成后,我可能会发布我最终使用的单独答案,以防别人想要看到它。再次感谢你的帮助! – Amplify91 2011-06-05 00:16:07

0

我有类似的问题与2.2中的bkg图像的意见。在LinearLayout中。我知道的唯一方法是接受默认布局不能正常工作,并通过代码重新绘制所有内容。