Android开发:Canvas无法正确显示

时间:2015-03-16 17:17:54

标签: android canvas surfaceview

我是Android开发的新手,并试图实现一个用表面视图和画布实现的简单游戏。我使用LunarView示例作为草稿。

这个想法是让一个人(由触摸事件控制的运动)和跟随他的僵尸。

到目前为止,我有以下类(我从我的观点中删除了无用的代码):

1)MainActivity

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}
}

2)ZombieView与内置类ZombieThread和Person(Person仅用于保存数据)

public class ZombieView extends SurfaceView implements SurfaceHolder.Callback {

//Thread Class that performs drawing on Canvas
class ZombieThread extends Thread {

    class Person {
        ...
    }

    private final SurfaceHolder surfaceHolder;
    private ZombieView zombieView;
    private Context context;
    private boolean running = false;

    //Canvas info
    private int mCanvasWidth = 1;
    private int mCanvasHeight = 1;
    private Bitmap mBackgroundImage;
    private final Drawable mHumanImage;
    private final Drawable mZombieImage;
    private Resources res;

    //Game Variables
    double hSpeed = 1;
    double zSpeed = 0.8;
    Person zombie;
    Person human;

    public ZombieThread(SurfaceHolder holder, ZombieView zombie, Context context) {
        this.surfaceHolder = holder;
        this.zombieView = zombie;
        this.context = context;

        this.zombie = new Person(100, 100, hSpeed);
        this.zombie.setRunning(true); //zombie always walks
        this.human = new Person(100, 200, zSpeed);

        res = context.getResources();
        mHumanImage = context.getResources().getDrawable(R.drawable.green_circle);
        mZombieImage = context.getResources().getDrawable(R.drawable.red_circle);
        mBackgroundImage = BitmapFactory.decodeResource(res,R.drawable.background);

    }

    @Override
    public void run() {
        Canvas c = null;
        while (this.running) {

            try {
                c = surfaceHolder.lockCanvas(null);

                synchronized (surfaceHolder) {
                    play();
                    onDraw(c);
                    checkCollision();

                }
            } finally {
                if (c != null) {
                    surfaceHolder.unlockCanvasAndPost(c);
                }
            }
            try {
                sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void checkCollision() {
        //do something
    }

    public void play() {
        ...
    }

    public void onDraw(Canvas c) {
        //Do your drawing here...
      //  c.drawColor(Color.rgb(10, 0, 0));

        c.drawBitmap(mBackgroundImage, 0, 0, null);
        c.save();

        //draw human and zombie
        int width = mHumanImage.getIntrinsicWidth();
        int height = mHumanImage.getIntrinsicHeight();

        mHumanImage.setBounds((int) human.getX() - (width / 2), (int) human.getY() - (height / 2),
                (int) human.getX() + (width / 2), (int) human.getY() + (height / 2));
        mHumanImage.draw(c);


        width = mZombieImage.getIntrinsicWidth();
        height = mZombieImage.getIntrinsicHeight();

        mZombieImage.setBounds((int) zombie.getX() - (width / 2), (int) zombie.getY() - (height / 2),
                (int) zombie.getX() + (width / 2), (int) zombie.getY() + (height / 2));
        mZombieImage.draw(c);

        c.restore();


    }

    public boolean doTouchEvent(MotionEvent e) {
        //do something
    }

}

//ZombieView variables
private ZombieThread thread;
private final SurfaceHolder surfaceHolder;
private Context context;

public ZombieView(Context context) {
    super(context);
    surfaceHolder = getHolder();
    surfaceHolder.addCallback(this);
    this.context = context;
    setFocusable(true); //makes sure we receive key-events
}

public ZombieView(Context context, AttributeSet attrs) {
    super(context, attrs);
    surfaceHolder = getHolder();
    surfaceHolder.addCallback(this);
    this.context = context;
    setFocusable(true); //makes sure we receive key-events
}

public ZombieView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    surfaceHolder = getHolder();
    surfaceHolder.addCallback(this);
    this.context = context;
    setFocusable(true); //makes sure we receive key-events
}

public ZombieThread getThread() {
    return thread;
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    thread = new ZombieThread(surfaceHolder, this, context);
    thread.setRunning(true);
    thread.start();
}
}

XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<com.example.zombierun.zombierun.ZombieView android:background="#ccc"
    android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="20dp"
    android:paddingBottom="40dp"
    android:focusable="true"
    android:visibility="visible"
    android:id="@+id/customView" />

所以现在我的问题如下: 当我启动应用程序时,我看到Activity和一个灰色区域,它应该是canvas / surfaceview。不幸的是,这一切都是。但是当我通过按下主页按钮来最小化应用程序时,我会看到应用程序最小化时的画布(带有图像和背景颜色)。 logcat中没有显示错误。

我认为画布不知何故停留在背景中或者不同的视觉之间有叠加?这可能吗?

希望有人能帮我正确显示画布。

提前致谢

1 个答案:

答案 0 :(得分:2)

你不能使用android:background =&#34; x&#34;使用SurfaceView时。您必须在onDraw(Canvas c)调用中手动绘制颜色,在本例中为canvas.drawColor(Color.GREY)。否则,您正在做的是将您设置的背景颜色绘制在曲面视图的表面上,使其呈现不透明的灰色。调用onPause时,视图会被拆除,您可以立即看到视图的窗口覆盖层下方的表面,其中绘制了#ccc。

另外:你为什么每帧睡眠1/10秒?你应该删除这一行。或者,如果您尝试以帧速率为目标:实现1000 ms / 100 ms = 10帧,即您以10 fps绘制。