我已经开始开发吉他应用程序了,并且陷入了图形方面。我的屏幕包含一个背景图像,您可以通过向上或向下滑动两个手指移动。我的背景图片,一个位图,在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);
}
}
}
答案 0 :(得分:3)
您似乎在每个渲染过程中加载/读取和缩放位图。这非常低效。
(请参阅FretBoard.java中对bmScale(is);
的调用)。
相反,只加载(并缩放你的)位图一次(当视图布局时),然后绘制已加载和缩放的位图。
此外,您似乎为SurfaceView
使用了FretBoard
。为什么?在您的代码示例中,您根本不使用OpenGL或视频/相机纹理。
答案 1 :(得分:0)
在循环中缩放(如此处的其他答案所述)绝对是您的主要问题。一旦你解决了这个问题,事情就会变得更加顺畅。你可能会发现一些小的口吃,因为你在循环中创建其他对象,即字符串。假设你一次在指板上永远不会有超过5个手指(好的,如果你正在敲击,理论上可能是10个)string
只有5或10个可能的值(顺便说一下,这是一个令人困惑的名字) ,特别是在这种情况下)。最好先在循环之外创建这些,然后选择正确的参考。