java - 绘制背景使我的应用变慢

标签 java android

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

谁能告诉我我做错了什么?

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

也许我的代码有点困惑,我还在学习中。

感谢您的帮助!

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();
    }

}
}

最佳答案

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

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

编辑

因此您的 xml 文件将 SurfaceView 包装在线性布局中并设置线性布局的 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);

}

关于java - 绘制背景使我的应用变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14939383/

相关文章:

java - 测试单元 Controller 剩余可分页

java - 我需要在 2D Java 模拟游戏中使用 OpenGL 吗?

android - ormlite 读取日期为 'yyyy-MM-dd'

android - 从 native 客户端中的应用程序的 uid/pid 获取包名称和签名

android - 造成原因:org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration $ ArtifactResolveException:

java - 日历输入忽略下一个输入行

java - 带有Around建议和@annotation的Spring AOP无法正常工作

java - 如果 get volley 请求为 true,则需要从 cardview 中的可绘制对象更新图像(200 ok)

android - Android 在哪里存储动态模块 APK?

Android 按键按下