-1

我已经开始开发吉他应用程序,并且停留在图形方面。我的屏幕包含一个背景图像,您可以用两根手指向上或向下滑动来移动它。我的背景图像(位图)在 Android 设备上以低 fps 移动。我正在寻找如何使其运行更顺畅。

代码详细信息:我有 3 个类:一个主要活动,第二个用于图形,第三个作为启动屏幕(我没有包括最后一个,因为它与我的问题无关)。

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 中的调用)。

相反,只加载(并缩放)位图一次(当视图布局时),然后绘制已经加载和缩放的位图。

此外,您似乎将 aSurfaceView用于您的FretBoard. 为什么?在您的代码示例中,您根本没有使用 OpenGL 或视频/相机纹理。

于 2013-02-27T19:22:29.147 回答
0

循环缩放(如此处的其他答案所述)绝对是您的主要问题。一旦你解决了这个问题,事情应该会顺利得多。您可能仍然会发现一些轻微的口吃,因为您正在循环中创建其他对象,即字符串。鉴于您一次在指板上的手指永远不会超过 5 个(好吧,如果您正在敲击,理论上可能是 10 个)只有 5 或 10 个可能的值string(顺便说一下,这是一个令人困惑的名称,尤其是在这种情况下)。最好在循环之外预先创建这些,然后选择正确的参考。

于 2013-02-27T19:29:24.617 回答