2013-02-18 57 views
2

我正在嘗試製作一個非常簡單的遊戲。用戶必須嘗試用手指移動籃子來捕捉蘋果。 一切似乎工作得很好,但我有一個問題:我想繪製應用程序的背景。但是使用圖像作爲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(); 
    } 

} 
} 

回答

1

不要繪製背景圖像中SurfaceView的方法的onDraw。每次surfaceView改變時,它都會重繪整個位圖。

您最好的選擇是將您的SurfaceView添加到LinearLayout中,然後將LinearLayout設置爲onCreate方法中的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); 

} 
+0

這是我的新xml佈局。 http://pastebin.com/cksKMjDy 它錯了嗎? – 2013-02-18 15:53:05

+0

看看我的編輯。如果它解決了,不要忘記接受答案! – wdziemia 2013-02-18 20:30:58

0

看起來像你的應用程序是fillrate-bound。你是否試圖關閉過濾和抗鋸齒的背景?另外,嘗試使用分析器運行應用程序並查找繪製背景。比較CPU花在繪製背景和遊戲其餘部分上的時間。如果太高,則意味着您的設備無法足夠快地傳輸像素,因此您應該考慮關閉濾鏡,至少要繪製背景。

Fillrate on wiki