Android - 位图以错误的比例绘制

时间:2012-05-07 23:33:09

标签: android bitmap scale terrain world-map

我一直在研究一个简单的基于图块的地形生成器,以获得乐趣,并且遇到了一些问题。

首先,信息:

设备:Acer Iconica a500

操作系统:ICS

目标版本:3.1 +

可用屏幕分辨率:1280x752

编入:Eclipse / AIDE

所以,现在问题是:

我正在使用的所有瓷砖都被绘制得比它们应该更大。 Tehy都是32x32 .png文件,但它们都是在屏幕上以43 x 43绘制的。从我读过的内容来看,这可能与它们被绘制的画布密度有关,所以我试图通过添加

来修复它
canvas.setDensity(0x0000000);  //density int value for DENSITY_NONE

不幸的是,这并没有解决问题。我也尝试了相同的单个位图,但无济于事。

我试图在Stack和其他地方找到解决方案,但到目前为止还没有运气。

有谁知道如何解决这个问题?

提前谢谢你。这是我的绘图类的完整代码:(我知道这个代码可能有很多问题,我是业余程序员。欢迎建设性批评)

package com.psstudio.hub.views;

import java.util.Random;

import com.psstudio.hub.R;
import com.psstudio.hub.R.drawable;
import com.psstudio.hub.gen.PocketDimension;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import android.util.AttributeSet;
import android.util.Log;


public class DrawWorld extends SurfaceView implements SurfaceHolder.Callback {

private WorldThread wThread;

PointF playerPos = new PointF();
PocketDimension dim = null;             //Holder for the dimension

int screenW = 0;        //this.getWidth();
int screenH = 0;        //this.getHeight();
int dimType = 1;                    //Which type of dimension is it?
int curType = -1;
int r;
int g;
int b;
int numTilesX;
int numTilesY;

float curX = 0.0f;
float curY = 0.0f;
float curXOffset = 0.0f;
float curYOffset = 0.0f;

private boolean run = false;

Random rand = new Random(255-0);

Paint heightPaint = new Paint();
Paint black = new Paint();
Paint colorPaint = new Paint();

Bitmap grassBMP = BitmapFactory.decodeResource(getResources(), R.drawable.grass);
Bitmap dirtBMP = BitmapFactory.decodeResource(getResources(), R.drawable.dirt);
Bitmap mountainBMP = BitmapFactory.decodeResource(getResources(), R.drawable.mountain);
Bitmap treeBMP = BitmapFactory.decodeResource(getResources(), R.drawable.tree);
Bitmap stoneBMP = BitmapFactory.decodeResource(getResources(), R.drawable.stone);
Bitmap oceanBMP = BitmapFactory.decodeResource(getResources(), R.drawable.ocean);
Bitmap nothingBMP = BitmapFactory.decodeResource(getResources(), R.drawable.nothing);
Bitmap bTemp = null;

double curElevation = 0.0;

boolean drawHeight = false;
boolean drawContour = false;
boolean drawTerrain = false;
boolean minimap = false;

MiniMap mMap;


public void init(){
    getHolder().addCallback(this);
    wThread = new WorldThread(getHolder(), this);
}

public DrawWorld(Context context) {
    super(context);
    init();
}

public DrawWorld(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public DrawWorld(Context context, PocketDimension _dim) {
    super(context);
    dim = _dim;;
    init();
}


@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){       //used to get the view dimensions.
    screenW = xNew;
    screenH = yNew;
    Log.d("Hub", "Screen W x H : " + screenW + " x " + screenH + "  |  " + this.getWidth() + " x " + this.getHeight());
    numTilesX = screenW / 32;
    numTilesY = screenH / 32;
}


public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
    // TODO Auto-generated method stub

}

public void surfaceCreated(SurfaceHolder arg0) {
    //Log.d("Hub","Surface Created");
    wThread.setRunning(true);
    wThread.start();

}

public void surfaceDestroyed(SurfaceHolder arg0) {
    boolean retry = true;
    wThread.setRunning(false);
    while(retry){
        try{
            wThread.join();
            retry=false;
        } catch(InterruptedException e){

        }
    }

}

/*************************************************************
 * 
 * Get Methods
 * 
 ************************************************************/



/*************************************************************
 * 
 * Set Methods
 * 
 ************************************************************/
public void setPocketDimension(PocketDimension _dim, MiniMap mm, float pX, float pY){
    dim = _dim;
    mMap = mm;
    playerPos.set(pX, pY);
    //Log.d("Hub", "Dimension set, starting thread");
}

public void setPlayerPos(float pX, float pY){
    playerPos.x = pX;
    playerPos.y = pY;
}


class WorldThread extends Thread{       //Thread for handling tile selection and adjusting map to match character pos.

    private SurfaceHolder surfaceHolder;
    private DrawWorld dTV;              //drawWorld View


    public void setRunning(boolean isRun){
        run = isRun;
    }//end setRunning()

    public WorldThread(SurfaceHolder surface, DrawWorld drawWorld) {
        surfaceHolder = surface;
        dTV = drawWorld;
    }

    public void run() {
        Canvas canvas;
        boolean first = false;

        //Log.d("Hub", "mMap : " + mMap + "  |  nTX : " + numTilesX + "  |  nTY : " + numTilesY);
        mMap.setMiniMapInfo(numTilesX, numTilesY);


        /*while (run) {
            canvas = null;
            try {
                canvas = surfaceHolder.lockCanvas();
                synchronized (surfaceHolder){
                    if(canvas != null){
                        dTV.onDraw(canvas);
                    } else {
                        Log.d("Hub", "null canvas");
                    }
                }
            } finally {
                // do this in a finally so that if an except is thrown
                // during the above, we don't leave the Surface in an 
                // inconsistent state
                if ( canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }

            /*******************************************************
             * 
             *  Put all things that happen here
             *   
             ******************************************************/
            //Log.d("Hub", "Draw World Thread");

        //} // end while (run)*
    }//end run()


} //end WorldThread() class

public void onDraw(Canvas canvas){

    //Log.d("Hub", "Starting onDraw()");
    Bitmap toDraw = null;
    Bitmap player = BitmapFactory.decodeResource(getResources(), R.drawable.player);

    //Log.d("Hub", "numTilesX : " + numTilesX + "  |  numTilesY : " + numTilesY);
    heightPaint.setColor(Color.WHITE);
    black.setColor(Color.BLACK);

    //Log.d("Hub", "onDraw();" + screenW + "  |  " + screenH);      //Test successful, it is reaching onDraw()

    //canvas.drawColor(Color.BLACK);

    for(int x = -1; x < numTilesX + 2; x++){
        for(int y = -1; y < numTilesY + 2 ; y++){

            curType = -1;
            curX = ((playerPos.x - (numTilesX / 2)) + x);
            curY = ((playerPos.y - (numTilesY / 2)) + y);
            curXOffset = (playerPos.x - ((int) playerPos.x));
            curYOffset = (playerPos.y - ((int) playerPos.y));

        //  Log.d("Hub", "CurX : " + curX + "  |  CurY : " + curY);     
            if(curX >= 0 && curY >= 0 && curX < (200 - (numTilesX / 2)) && curY < (200 - (numTilesY/2))){
                curType = dim.getType((int)curX, (int)curY);    //get the tile for the current x position
            } else {
                curType = -1;
            }

            toDraw = getBMP(curType);
            canvas.drawBitmap(toDraw, (x*32) - (curXOffset * 32), (y*32) - (curYOffset * 32), null);
            //canvas.drawRect(624,384,624+32+11,384+32+11,heightPaint); //32x32 bitmaps are being drawn at 43x43
            canvas.drawBitmap(player, 624, 384, null);

        }
    }

    if(drawHeight || drawContour || drawTerrain){
        for(int x = 0; x < 200; x++){               //Draw Heightmap, "Contour" map, and Terrain Map
            for(int y = 0; y < 200; y++){

                curType = dim.getType(x, y);
                curElevation = dim.getElevation(x, y);

                if(drawHeight){
                    heightPaint.setAlpha((int) (255*dim.getElevation(x, y)));
                    canvas.drawPoint(x + 20, y + 20, black);
                    canvas.drawPoint(x + 20, y + 20, heightPaint);      //Heightmap
                }

                colorPaint.setColor(Color.WHITE);
                if(drawContour){
                    if(curElevation >= 0.01 && curElevation <0.1) colorPaint.setColor(Color.BLACK);
                    else if(curElevation >= 0.1 && curElevation <0.2) colorPaint.setColor(Color.rgb(127, 0, 255));
                    else if(curElevation >= 0.2 && curElevation <0.3) colorPaint.setColor(Color.rgb(75, 0, 130));
                    else if(curElevation >= 0.3 && curElevation <0.4) colorPaint.setColor(Color.BLUE);
                    else if(curElevation >= 0.4 && curElevation <0.5) colorPaint.setColor(Color.GREEN);
                    else if(curElevation >= 0.5 && curElevation <0.6) colorPaint.setColor(Color.YELLOW);
                    else if(curElevation >= 0.6 && curElevation <0.7) colorPaint.setColor(Color.rgb(255,127,0));
                    else if(curElevation >= 0.7) colorPaint.setColor(Color.RED);
                    canvas.drawPoint(x + 20, y + 220, colorPaint);      //"Contour" Map
                }

                if(drawTerrain){
                    if(curType == 1) colorPaint.setColor(Color.rgb(1, 166, 17));
                    else if(curType == 2) colorPaint.setColor(Color.rgb(207, 181, 144));
                    else if(curType == 3) colorPaint.setColor(Color.rgb(105, 108, 117));
                    else if(curType == 4) colorPaint.setColor(Color.rgb(0, 92, 9));
                    else if(curType == 5) colorPaint.setColor(Color.rgb(186, 173, 166));
                    else if(curType == 6) colorPaint.setColor(Color.BLUE);
                    canvas.drawPoint(x + 20, y + 420, colorPaint);      //Terrain Map
                }
            }
        }
    }

    r = rand.nextInt();
    g = rand.nextInt();
    b = rand.nextInt();

    colorPaint.setColor(Color.rgb(r, g, b));

    canvas.drawRect (0,0,10,10,colorPaint);

    //Log.d("Hub", "Ending onDraw()");
}// end onDraw()

public Bitmap getBMP(int nBMP){

    bTemp = nothingBMP; // image for areas beyond the map
    switch (dimType){
    case 1:
        switch(nBMP){
            case -1:
                bTemp = nothingBMP;
                break;
            case 1 :
                bTemp = grassBMP;
                break;
            case 2 :
                bTemp = dirtBMP;
                break;
            case 3 :
                bTemp = mountainBMP;
                break;
            case 4 :
                bTemp = treeBMP;
                break;
            case 5 :
                bTemp = stoneBMP;
                break;
            case 6 :
                bTemp = oceanBMP;
                break;
        }
    }
    //Log.d("Hub", "getBMP() " + dimType + "  |  " + nBMP + "  |  " + bTemp );
    //bTemp.setDensity(0x0000000);
    return bTemp;
}//end getBMP();

}

1 个答案:

答案 0 :(得分:0)

使用decodeResources解码位图时,实际上会发生基于密度的缩放。您可以使用指定了BitmapFactory.Options的重载。有很多选项,但您可能只想将inScaled设置为false