我有一个益智游戏,其中棋盘是一个矩形,边框是由一个网格单位长的棋子组成的。我有一种方法可以随机化图像并将其环绕在水平面上,但是...这确实很糟糕。它具有最奇怪的错误:根据运行的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)旋转矩阵,调整位图的大小,并根据需要从图块的基本位置调整位置。

那是我无论如何都会做的事情。这样,它适用于任何基于图块的地图,即使是具有内部非活动区域的图,也无需像现在使用的那样硬编码“边缘”。

08-26 10:17