我和朋友正在實施基於一些開源的google項目代碼accelerometerplay的大理石遊戲。我們的目的是製作一個玩具程序來教自己的android開發。我們正在經歷如下:爲什麼我們的安卓遊戲,特別是我們的大理石,移動如此緩慢?
問題:
大理石將滾動屏幕極其緩慢的。這就像看慢慢地運動一樣。太糟糕了。我們如何讓它更快/正常發揮?
我們所做的:
我們強行加accelerometerplay我們的代碼,吸引了來自瓦片地圖。這會降低速度。它仍然運行相當不錯。
我們重寫了我們的觀點,使其更接近原始加速度計,並且仍然存在與我們的大理石運行速度太慢相同的問題,因此這消除了我們對不同類別方法和簡化的懷疑。
已搜索本論壇。我們看到有些事情說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
請編輯您的問題並刪除所有不必要的代碼(如未使用或未註釋的部分)。期望人們通過所有外來的糠wa來篩選出有問題的實際代碼是有點不合理的。這裏的問題應該清楚簡潔,用盡可能少的代碼來說明問題。謝謝。 –
你看到什麼幀速率,即被調用的onDraw()的頻率?大理石慢慢移動的事實可能是因爲幀速率非常低,或者因爲您不是很大程度上移動大理石。這可能很明顯,但對我們來說並不明顯。 :-) – fadden
1.多久調用一次onDraw()?我不知道,我也想弄清楚。在任何示例代碼中,我沒有看到如何確定FPS的例子。 – GeekyOmega