2012-11-27 1 views
0

내 친구와 저는 일부 오픈 소스 Google 프로젝트 코드 인 가속도계를 기반으로 대리석 게임을 구현하고 있습니다. 우리의 목적은 우리 자신의 안드로이드 개발을 가르치는 장난감 프로그램을 만드는 것입니다. 우리는 다음 발생 :우리의 안드로이드 게임, 특히 우리의 대리석이 왜 그렇게 느리게 움직이는가?

문제 :

대리석이 매우 느린 화면에 출시됩니다. 슬로우 모션으로 움직이는 것을 보는 것과 같습니다. 그것은 끔찍한 일입니다. 어떻게하면 더 빨리/정상적으로 플레이 할 수 있을까요?

은 우리가 무슨 짓을 :

  1. 우리는 타일 맵을 그립니다 공급 accelerometerplay 우리의 코드를 강제로. 이것은 일을 늦추는 동안. 아직도 꽤 잘 돌아갑니다.

  2. 우리는 원래의 가속도계와 더 가깝도록 우리의보기를 다시 작성했으며, 우리의 대리석이 너무 느리게 움직이는 것과 똑같은 문제가 여전히 남아있어서 우리의 다른 클래스 접근법과 단순화에 대한 의구심을 제거합니다.

  3. 이 포럼을 검색했습니다. 우리는 invalidate()가 일을 느리게한다고 말하는 것을 보았지만 그 것이 문제라고 생각하지 않습니다. 하나의 대리석을 그려 화면에서만 움직이게하려면 onDraw()를 죽여서는 안됩니다.

다음은 프로그램의보기 부분에 대한 코드입니다. 활동 또는 물리학 코드와 같은 다른 클래스가 작동 중입니다. 우리는이 클래스에서 대리석을 그리며 움직이는 문제가 100 % 확실하다고 확신합니다.

package com.example.marblez; 
import com.example.marblez.R; 
import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.BitmapFactory.Options; 
import android.graphics.Canvas; 


import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 
import android.util.Log; 
import android.view.Display; 
import android.view.KeyEvent; 
import android.view.MotionEvent; 
import android.view.Surface; 
import android.view.View; 
import android.view.WindowManager; 

public class MarblezView extends View implements SensorEventListener{ 


//Sensor Stuff 
private SensorManager mSensorManager; 
private Display mDisplay; 


//Accelerometer sensor stuff 
private Sensor mAccelerometer; 
private float mSensorX; 
private float mSensorY; 


//Variables related to time 
private long mCpuTimeStamp; 
private long mSensorTimeStamp; 
private WindowManager mWindowManager; 


//Create the canvas 
private Canvas mCanvas; 
private MarblezBackground background; 

//Create the ball objects 
private Bitmap mBall; 
private Bitmap ball; 

//Finally call marblez system 
private final MarblezSystem mMarblezSystem = new MarblezSystem(); 


//Constructor for Marblez View 
@SuppressWarnings("deprecation") 
public MarblezView(Context context, Activity activity){ 
    super(context); 

    //Setup sensor stuff 
    mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 
    mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
    mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI); 

    mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
    mDisplay = mWindowManager.getDefaultDisplay(); 



    //Set up Maze 
    background = new MarblezBackground(activity); 

    //Create our rolling little friend :-) 
    Options opts = new Options(); 
    opts.inDither = true; 
    opts.inPreferredConfig = Bitmap.Config.RGB_565; 

    mBall = BitmapFactory.decodeResource(activity.getApplicationContext().getResources(), R.drawable.ball, opts); 

    // Rescale the ball to be whatever size you wish it to be 
    final int dstWidth = (int) 30;//(sBallDiameter * mMetersToPixelsX + 0.5f); 
    final int dstHeight = (int) 30;//(sBallDiameter * mMetersToPixelsY + 0.5f); 
    ball = Bitmap.createScaledBitmap(mBall, dstWidth, dstHeight, true); 

} 

@Override 
public void onSensorChanged(SensorEvent event) { 
    if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) 
     return; 
    /* 
     * record the accelerometer data, the event's timestamp as well as 
     * the current time. The latter is needed so we can calculate the 
     * "present" time during rendering. In this application, we need to 
     * take into account how the screen is rotated with respect to the 
     * sensors (which always return data in a coordinate space aligned 
     * to with the screen in its native orientation). 
     */ 
    mSensorX = event.values[0]; 
    mSensorY = -event.values[1]; 


    mSensorTimeStamp = event.timestamp; 
    mCpuTimeStamp = System.nanoTime(); 
} 


//Automatic call 
@Override 
public void onDraw(Canvas canvas){ 
    //mCanvas = canvas; 

    //Draw the maze 
    //background.drawMaze(canvas); 


    //Update the position and then draw the marble 
    final MarblezSystem marblezSystem = mMarblezSystem; 
    final long now = mSensorTimeStamp + (System.nanoTime() - mCpuTimeStamp); 
    final float sx = mSensorX; 
    final float sy = mSensorY; 

    marblezSystem.updatePositions(sx, sy, now); 
    final float x = marblezSystem.getPosX(); 
    final float y = marblezSystem.getPosY(); 
    canvas.drawBitmap(ball, x, y, null); 

    //Invalidate so it draws again 
    invalidate(); 

} 

@Override 
public void onAccuracyChanged(Sensor sensor, int accuracy) { 
} 

} 

우리는 대리석을 감속시키고있는 것에 벽돌 벽을 치고 있습니다. 우리는 삼성 갤럭시 타블렛을 사용하고 있습니다. 10.1 믿습니다. 대리석이 천천히 움직이는 원인을 누구나 볼 수 있다면 알려 주시기 바랍니다. 우리는 onDraw 메서드에서 뭔가를하고 있습니까? 포함 된 모든 독서 가이드는 이것이 효과가 있다는 것을 나타내는 것 같지만 우리 대리석이 왜 그렇게 느리게 움직이는 지 이해할 수 없습니다.

은 고려 GeekyOmega 주셔서 감사합니다

편집 :

package com.example.marblez; 

public class MarblezSystem { 

    private long mLastT; 
    private float mLastDeltaT; 
    private Marblez ball; 

    MarblezSystem() { 
     /* 
     * Initially our marble have no speed or acceleration 
     */ 
      ball = new Marblez(); 
     } 


    /* 
    * Update the position of marble in the system using the 
    * Verlet integrator. 
    */ 
    public void updatePositions(float sx, float sy, long timestamp) { 
     final long t = timestamp; 
     if (mLastT != 0) { 
      final float dT = (float) (t - mLastT) * (1.0f/1000000000.0f); 
      if (mLastDeltaT != 0) { 
       final float dTC = dT/mLastDeltaT; 
        //Particle ball = mBalls[i]; 
        ball.computePhysics(sx, sy, dT, dTC); 

      } 
      mLastDeltaT = dT; 
     } 
     mLastT = t; 
    } 


    public float getPosX() { 
     return ball.mPosX; 
    } 

    public float getPosY() { 
     return ball.mPosY; 
    } 

}//End of MarblezSystem 
+1

질문을 편집하고 불필요한 코드 (예 : 사용되지 않거나 주석 처리 된 부품)를 모두 제거하십시오. 문제가되는 실제 코드를 분리하기 위해 관계없는 모든 왕관을 헤매는 사람들을 예상하는 것은 약간 중요하지 않습니다.여기에있는 질문은 문제를 설명하는 데 필요한만큼의 코드로 명확하고 간결해야합니다. 감사. –

+1

어떤 프레임 속도, 즉 onDraw()가 얼마나 자주 호출됩니까? 대리석이 천천히 움직이고 있다는 사실은 프레임 속도가 매우 낮거나 대리석을 아주 많이 움직이지 않아서 일 수 있습니다. 그것은 분명 당신에게 분명하지만, 우리에게는 그리 명백하지 않습니다. :-) – fadden

+0

1. onDraw()가 얼마나 자주 호출됩니까? 나도 몰라, 나도 알아 내려고 애 쓰고있어. 샘플 코드에서 FPS를 결정하는 방법에 대한 예제가 없습니다. – GeekyOmega

답변

1
:

독자가 updatePositions을 (보고 싶어), 그래서 여기에 당신이, 구글 오픈 소스의 예에서 적응

귀하의 문제는 귀하의 FPS 설정과 관련이 있다고 생각합니다. 나는 당신의 코드에서 그것을 보지 못한다.
고려해야 할 FPS와 현재 프레임 속도를 사용하지 않으면 CPU로드가 과중 해지면 상황이 천천히 움직입니다.
비슷한 문제가 있었음을 기억하고이 tutorial을 살펴본 후 모든 것이 원활하게 진행되었습니다.
시간이 있다면 시도하십시오.
희망이 도움이됩니다.

관련 문제