-1

ギター アプリケーションの開発を開始しましたが、グラフィカルな側面にこだわっています。私の画面には背景画像が含まれており、2 本の指で上下にスライドして移動できます。私の背景画像、ビットマップは、Android デバイス上で低い fps で移動します。どうやったらスムーズに走れるようになるのか、模索中です。

コードの詳細: 3 つのクラスがあります。1 つはメイン アクティビティ、2 番目はグラフィック用、3 番目はスプラッシュ スクリーンです (最後の 1 つは問題とは関係がないため、含めていません)。

MainActivity.java

package com.example.androidapplication;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;


public class MainActivity extends Activity implements OnTouchListener{

    FretBoard ourView;
    float y1, y2, dy;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        ourView = new FretBoard(this);
        ourView.setOnTouchListener(this);
        setContentView(ourView);

    }

    //Method to be used in future
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        ourView.pause();
    }

    //Method to be used in future
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        ourView.resume();
    }



    @Override
    public boolean onTouch(View v, MotionEvent event){

        //For debugging
        if(event!= null) ourView.fingerCount = event.getPointerCount();

        switch(event.getAction()){

            case MotionEvent.ACTION_DOWN:

                //Save first y position when finger touches screen
                y1 = event.getY();

                break;


            case MotionEvent.ACTION_MOVE:

                if(event != null && event.getPointerCount() == 2){

                    //Save second y position when finger moves
                    y2 = event.getY();

                    //Total distance moved
                    dy = y2 - y1;
                    if((ourView.bgY + dy)<0) ourView.bgY += dy/2;

                    //For Debugging
                    System.out.println("Y1 : " + y1 + "     Y2 : " + y2                +   "   DY : " + dy);

                    //Redraw the Screen 
                    ourView.invalidate();

                    //Reset y1 
                    y1 = y2;
                }

                break;
        }
        return true;
    }

}

FretBoard.java

package com.example.androidapplication;

import java.io.InputStream;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


public class FretBoard extends SurfaceView implements Runnable{

    //Background image variables
    Bitmap background;
    InputStream is = getResources().openRawResource(R.drawable.fret_board);

    //Debugger text variables
    Paint mPaint = new Paint();
    String string = "Fingers: ";
    int fingerCount = 0;

    //Position Variables
    int width, height;
    float bgY = 0, bgX = 0;

    //Holder variable
    SurfaceHolder ourHolder;

    //To be used in future
    Thread ourThread = null;
    Boolean isRunning = false;

    public FretBoard(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        ourHolder = getHolder();
        ourThread = new Thread(this);
        ourThread.start();

    }

    //To be used in the future
    public void pause(){
        isRunning = false;
        while(true){
            try {
                ourThread.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;
        }
        ourThread = null;
    }

    //To be used in the future
    public void resume(){
        isRunning = true;
        ourThread = new Thread(this);
        ourThread.start();
    }


    //Creates a InputStream to set width, then converts to bitmap to be
    //drawn as background on the canvas.
    public Bitmap bmScale(InputStream is){
       BitmapFactory.Options o = new BitmapFactory.Options();
       o.inSampleSize = 2;
       Bitmap bit = BitmapFactory.decodeStream(is, null, o);
       background = Bitmap.createScaledBitmap(bit, width, 2300, true);
       bit.recycle();
       return background;
    }


    //This is the draw method where I need help
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(isRunning){
            if(!ourHolder.getSurface().isValid()) continue;

            //Lock canvas to draw 
            Canvas canvas = ourHolder.lockCanvas();

            //Do Things Here:
            width = getWidth();
            height = getHeight();

            //Collision detection for the background
            if(bgY > 0 ) bgY = 0;

            //Draws the background
            bmScale(is);
            canvas.drawBitmap(background, bgX, bgY, null);

            //For debugging, displays the number of fingers on the screen
            canvas.drawText(string + fingerCount, 50, 50, mPaint);

            //Unlock canvas to show 
            ourHolder.unlockCanvasAndPost(canvas);
        }
    }   
}
4

2 に答える 2

3

各レンダーパスでビットマップをロード/読み取りおよびスケーリングしているようです。これは非常に非効率的です。( bmScale(is);FretBoard.java の呼び出しを参照)。

代わりに、ビットマップを 1 回だけ (ビューがレイアウトされるときに) ロード (およびスケーリング) してから、既にロードおよびスケーリングされたビットマップを描画します。

また、 に a を使用しているようSurfaceViewですFretBoard。なんで?コード サンプルでは、​​OpenGL またはビデオ/カメラ テクスチャをまったく使用していません。

于 2013-02-27T19:22:29.147 に答える
0

ループのスケーリング (ここでの他の回答で述べたように) は間違いなくあなたの大きな問題です。それを修正すると、物事ははるかにスムーズになるはずです。ただし、ループ内に他のオブジェクト、つまり文字列を作成しているため、おそらくまだいくつかのマイナーなスタッターが見つかるでしょう。一度にフレットボードに 5 本以上の指があることはない (タッピングしている場合、理論的には 10 本かもしれません) ことを考えると、可能な値は 5 つまたは 10 つしかありませんstring(ちなみに、特にこのコンテキストでは紛らわしい名前です)。 )。これらをループの外でも前もって作成し、正しい参照を選択することをお勧めします。

于 2013-02-27T19:29:24.617 に答える