2012-11-27 62 views
0

我和朋友正在實施基於一些開源的google項目代碼accelerometerplay的大理石遊戲。我們的目的是製作一個玩具程序來教自己的android開發。我們正在經歷如下:爲什麼我們的安卓遊戲,特別是我們的大理石,移動如此緩慢?

問題:

大理石將滾動屏幕極其緩慢的。這就像看慢慢地運動一樣。太糟糕了。我們如何讓它更快/正常發揮?

我們所做的:

  1. 我們強行加accelerometerplay我們的代碼,吸引了來自瓦片地圖。這會降低速度。它仍然運行相當不錯。

  2. 我們重寫了我們的觀點,使其更接近原始加速度計,並且仍然存在與我們的大理石運行速度太慢相同的問題,因此這消除了我們對不同類別方法和簡化的懷疑。

  3. 已搜索本論壇。我們看到有些事情說invalidate()會讓事情變得緩慢,但我們不認爲這是問題所在。它不應該殺死onDraw()來繪製一個大理石只能在屏幕上移動。

我們在我們的程序視圖部分包含了我們的代碼。其他類如活動或物理代碼正在工作。我們百分之百地確信,這個課題正在發生,它正試圖畫大理石來移動。

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) { 
} 

} 

我們碰到了一堵磚牆,以減緩我們的大理石。我相信我們正在使用三星Galaxy平板電腦10.1。如果任何人能看到什麼導致我們的大理石慢慢移動,請告訴我們。我們在onDraw方法中做了些什麼?所有的閱讀,包括指南,似乎表明這應該工作,但我們似乎無法理解爲什麼我們的大理石移動如此緩慢。

謝謝您的考慮, GeekyOmega

編輯:

讀者希望看到updatePositions(),從谷歌的開源例如適應,所以在這裏你是:

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

請編輯您的問題並刪除所有不必要的代碼(如未使用或未註釋的部分)。期望人們通過所有外來的糠wa來篩選出有問題的實際代碼是有點不合理的。這裏的問題應該清楚簡潔,用盡可能少的代碼來說明問題。謝謝。 –

+1

你看到什麼幀速率,即被調用的onDraw()的頻率?大理石慢慢移動的事實可能是因爲幀速率非常低,或者因爲您不是很大程度上移動大理石。這可能很明顯,但對我們來說並不明顯。 :-) – fadden

+0

1.多久調用一次onDraw()?我不知道,我也想弄清楚。在任何示例代碼中,我沒有看到如何確定FPS的例子。 – GeekyOmega

回答

1

我認爲你的問題與你的FPS設置有關。我沒有在你的代碼中看到它。
如果您不考慮FPS和當前幀速率,那麼當CPU的負載變大時,事情會緩慢地移動。
我記得有類似的問題,並經歷了這tutorial之後,一切順利。
如果你有時間嘗試去通過它。
希望這會有所幫助。

相關問題