0
是否有可能在我的遊戲視圖中添加攝像頭預覽? 我試圖在遊戲視圖裏添加相機預覽,這個錯誤出現了。如何在遊戲視圖中添加攝像頭預覽(表面視圖)
E/SurfaceHolder:異常鎖定表面java.lang.IllegalArgumentException異常
它看起來像我的gameloop 一些錯誤,但我不知道如何解決它。 任何人都知道如何解決這個問題?
我GameLoop
public class MainThread extends Thread {
public static final int MAX_FPS = 30;
private double averageFPS;
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
private boolean running;
public static Canvas canvas;
public void setRunning(boolean running){
this.running = running;
}
public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel){
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
@Override
public void run() {
long startTime;
long timeMillis = 1000/MAX_FPS;
long waitTime;
int frameCount = 0;
long totalTime = 0;
long targetTime = 1000/MAX_FPS;
while(running){
startTime = System.nanoTime();
canvas = null;
try{
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
this.gamePanel.update();
this.gamePanel.draw(canvas);
}
} catch (Exception e) {e.printStackTrace();}
finally {
if (canvas != null){
try{
surfaceHolder.unlockCanvasAndPost(canvas);
}catch (Exception e) {e.printStackTrace();}
}
}
timeMillis = (System.nanoTime() - startTime)/1000000;
waitTime = targetTime - timeMillis;
try{
if(waitTime > 0)
this.sleep(waitTime);
}catch (Exception e) {e.printStackTrace();}
totalTime += System.nanoTime() - startTime;
frameCount++;
if(frameCount == MAX_FPS){
averageFPS = 1000/((totalTime/frameCount)/1000000);
frameCount = 0;
totalTime = 0;
System.out.println(averageFPS);
}
}
}
}
我GameView
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
private MainThread thread;
private ObstacleManager obstacleManager;
private SurfaceHolder mHolder;
private Camera mCamera;
public GamePanel(Context context, Camera camera) {
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(90);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
thread = new MainThread(mHolder, this);
obstacleManager = new ObstacleManager(100, 100, Color.BLACK);
setFocusable(true);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try{
//when the surface is created, we can set the camera to draw images in this surfaceholder
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
thread = new MainThread(holder, this);
thread.setRunning(true);
thread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//before changing the application orientation, you need to stop the preview, rotate and then start it again
if(mHolder.getSurface() == null)//check if the surface is ready to receive camera data
return;
try{
mCamera.stopPreview();
} catch (Exception e){
//this will happen when you are trying the camera if it's not running
}
//now, recreate the camera preview
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = false;
while(retry){
try{
thread.setRunning(false);
thread.join();
}catch (Exception e) {e.printStackTrace(); }
retry = false;
}
mCamera.stopPreview();
mCamera.release();
}
public void update(){
obstacleManager.update();
}
@Override
public void draw(Canvas canvas){
super.draw(canvas);
//canvas.drawColor(Color.WHITE);
obstacleManager.draw(canvas);
}
}
我的MainActivity
public class Main2Activity extends Activity {
//declaring gameview
private GameView gameView;
private Camera mCamera;
private FrameLayout frameLayout;
private GamePanel gamePanel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
Constants.SCREEN_WIDTH = dm.widthPixels;
Constants.SCREEN_HEIGHT = dm.heightPixels;
try {
mCamera = Camera.open(0);//you can use open(int) to use different cameras
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if (mCamera != null) {
frameLayout = (FrameLayout) findViewById(R.id.gameView);
gamePanel = new GamePanel(this, mCamera);
frameLayout.addView(gamePanel);
}
}
}