绘制背景使我的应用程序变慢

时间:2013-02-18 15:10:01

标签: java android

我正在尝试制作一款非常简单的游戏。用户必须尝试用手指移动的篮子抓住苹果。 一切似乎都很好,但我有一个问题:我想为应用程序绘制一个背景。但是使用图像作为backgorund会使应用程序极其缓慢并导致很多延迟。如果我使用白色背景我没有问题。

有人可以告诉我我做错了吗?

我认为这是因为我每次应用更新时都会绘制背景,但我不知道有什么方法可以改变它。

也许我的代码有点混乱,我还在学习。

感谢您的帮助!

package com.cris9696.mela;

import java.util.Random;

import com.cris9696.mela.R;

import android.os.Bundle;
import android.app.Activity;
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.Rect;
import android.graphics.Typeface;
import android.graphics.Paint.Align;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

public class Game extends Activity implements OnTouchListener {

ClasseCanvas View;
float xApple, yApple, xBasket, yBasket;
Bitmap Apple, Basket, BackG;
Random rnd = new Random();
int win = 0, score = 0, level = 1;
int record = 0;
Typeface Font;
Paint TextP = new Paint();
Rect dest;
Paint paint;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Font = Typeface.createFromAsset(getAssets(), "TF2.ttf");
    View = new ClasseCanvas(this);
    View.setOnTouchListener(this);
    TextP.setColor(Color.RED);
    TextP.setTextSize(50);
    TextP.setTypeface(Font);
    xApple = yApple = xBasket = yBasket = 0;
    xApple = rnd.nextInt(600);
    Apple = BitmapFactory.decodeResource(getResources(), R.drawable.apple);
    BackG = BitmapFactory
            .decodeResource(getResources(), R.drawable.bg);
    Basket = BitmapFactory.decodeResource(getResources(),
            R.drawable.basket);

    setContentView(View);

}

// /////////////////////////////////////////////////////////////////////////////

@Override
public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub

    xBasket = event.getX();
    yBasket = event.getY();
    /*
     * switch (event.getAction()) { // ci dice cosa succede
     * 
     * case MotionEvent.ACTION_DOWN:
     * 
     * case MotionEvent.ACTION_UP:
     * 
     * break; }
     */
    return true;
}

// ///////////////////////////////////////////////////////////////////////////

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    View.pause();
}

// /////////////////////////////////////////////////////////////////////////////

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    View.resume();
}

// ///////////////////////////////////////////////////////////

public class ClasseCanvas extends SurfaceView implements Runnable {

    SurfaceHolder Holder;
    Thread thread = null;
    boolean isRunning = true;

    public ClasseCanvas(Context context) {
        super(context);
        Holder = getHolder();

        // TODO Auto-generated constructor stub
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (isRunning) {
            if (!Holder.getSurface().isValid())
                continue;

            Canvas canvas = Holder.lockCanvas();

            dest = new Rect(0, 0, getWidth(), getHeight());
            paint = new Paint();
            paint.setFilterBitmap(true);
            canvas.drawBitmap(BackG, null, dest, paint);
            TextP.setColor(Color.RED);
            canvas.drawText(Integer.toString(score), 56, 56, TextP);
            TextP.setColor(Color.BLACK);
            canvas.drawText("Level " + Integer.toString(level), 115,
                    56, TextP);
            if (xBasket != 0 && yBasket != 0) {
                canvas.drawBitmap(Basket, xBasket - Basket.getWidth() / 2,
                        yBasket - Basket.getHeight() / 2, null);
            }
            canvas.drawBitmap(Apple, xApple, yApple, null);
            if (yApple < canvas.getHeight())
                if (score >= 0)
                    yApple += 5 * level;
                else
                    yApple += 5;
            else {
                yApple = 0;
                score--;
                xApple = rnd.nextInt(canvas.getWidth() - Apple.getWidth());
            }
            if (score > record)
                record = score;
            if (score == 10) {
                level++;
                score = 0;
            }
            if ((xApple >= xBasket - (Basket.getWidth() / 2)
                    && xApple + (Apple.getWidth()) <= xBasket
                            + (Basket.getWidth() / 2) && yApple >= yBasket && yApple <= yBasket
                    + Basket.getHeight())
                    || (xApple >= xBasket - (Basket.getWidth() / 2)
                            && xApple <= xBasket + (Basket.getWidth() / 2)
                            && yApple >= yBasket && yApple <= yBasket
                            + Basket.getHeight())
                    || (xApple + (Apple.getWidth()) >= xBasket
                            - (Basket.getWidth() / 2)
                            && xApple + (Apple.getWidth()) <= xBasket
                                    + (Basket.getWidth() / 2)
                            && yApple >= yBasket && yApple <= yBasket
                            + Basket.getHeight())) {
                win = 1;
                xApple = rnd.nextInt(canvas.getWidth());
                yApple = 0;
                score++;
            }

            Holder.unlockCanvasAndPost(canvas);
        }
    }

    public void pause() {
        isRunning = false;
        while (true) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
        thread = null;
        // TODO Auto-generated method stub
    }

    public void resume() {
        // TODO Auto-generated method stub
        isRunning = true;
        thread = new Thread(this);
        thread.start();
    }

}
}

2 个答案:

答案 0 :(得分:1)

不要在SurfaceView的onDraw方法中绘制背景图像。每次surfaceView更改时,它都会重绘整个位图。

最好的办法是将SurfaceView添加到LinearLayout中,然后在onCreate方法中将LinearLayout设置为ContentView。将linearLayout的背景设置为R.drawable.bg,这样它只绘制一次。

修改

因此,您的xml文件将SurfaceView包装在线性布局中并设置linearlayout的bg。问题是您没有在onCreate方法中使用此布局。

在您的XMl中

,将<SurfaceView更改为<com.cris9696.mela.game.ClasseCanvas。然后在onCreate方法中,您可以执行以下操作:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main); // the XML layout you created.

    View = (ClasseCanvas) findViewById(R.id.View); // the ClasseCanvas view in your XML file.
    View.setOnTouchListener(this);

    Font = Typeface.createFromAsset(getAssets(), "TF2.ttf");

    TextP.setColor(Color.RED);
    TextP.setTextSize(50);
    TextP.setTypeface(Font);

    xApple = yApple = xBasket = yBasket = 0;
    xApple = rnd.nextInt(600);

    Apple = BitmapFactory.decodeResource(getResources(), R.drawable.apple);
    BackG = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
    Basket = BitmapFactory.decodeResource(getResources(),R.drawable.basket);

}

答案 1 :(得分:0)

好像你的应用程序是fillrate-bound。您是否尝试关闭背景的过滤和抗锯齿?此外,尝试使用分析器运行应用程序并查找绘图背景。将CPU花在绘制背景上的时间与游戏的其余部分进行比较。如果它太高,则意味着您的设备无法足够快地传输像素,您应该考虑关闭滤镜,至少是为了绘制背景。

Fillrate on wiki