我写了一个SurfaceView
方法,但是我不确定是否遵循最佳实践。我看过很多教程,但是找不到独特的编码方法。例如,我应该添加回调吗?在GameView
中呼叫setContentView
是否正确?
简化代码如下所示。
GameActivity.java
public class GameActivity extends AppCompatActivity {
private static final String TAG = "TAG_GameActivity";
private GameView gameView;
FrameLayout game;
RelativeLayout GameButtons;
private FirebaseAuth mAuth = FirebaseAuth.getInstance();
private FirebaseUser currentUser = mAuth.getCurrentUser();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
gameView = new GameView(this, size.x, size.y);
game = new FrameLayout(this);
GameButtons = new RelativeLayout(this);
setContentView(gameView);
}
@Override
protected void onPause() {
super.onPause();
gameView.pause();
}
@Override
protected void onResume() {
super.onResume();
gameView.resume();
}
}
GameView.java
public class GameView extends SurfaceView implements Runnable {
private static final String TAG = "TAG_GameView";
private FirebaseAuth mAuth = FirebaseAuth.getInstance();
private FirebaseUser currentUser = mAuth.getCurrentUser();
private DocumentReference myRef = FirebaseFirestore.getInstance().collection("Users").document(currentUser.getUid());
private ListenerRegistration noteListener;
final Movement movement = new Movement();
//Data
private double balance = 0;
private long tips = 0;
volatile boolean inLoop;
volatile boolean playing;
private Thread gameThread = null;
private Paint paint;
private Canvas canvas;
private SurfaceHolder surfaceHolder;
public GameView(GameActivity context, int screenX, int screenY) {
super(context);
surfaceHolder = getHolder();
paint = new Paint();
Xg = screenX/2;
Yg = screenY/2;
raggio = Math.min(screenX,screenY)/5;
}
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
Log.d(TAG,"onTouchEvent: start");
if ((motionEvent.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) {playing = true;}
}
Log.d(TAG,"onTouchEvent: end");
return true;
}
@SuppressLint("DefaultLocale")
@Override
public void run() {
Log.d(TAG,"run: end");
reset();
while (inLoop) {
if (playing) {
// Execute game
}
control(17);
}
Log.d(TAG,"run: end");
}
private void update_data(double won) {
Log.d(TAG,"update_data: start");
// write some data in DB
Log.d(TAG,"update_data: end");
}
private void control(int t) {
try {
Thread.sleep(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void pause() {
noteListener.remove();
inLoop = false;
try {
gameThread.join();
} catch (InterruptedException e) {
Log.d("Error Pause",e.toString());
}
}
public void resume() {
Log.d(TAG,"resume: start");
noteListener = myRef.addSnapshotListener((documentSnapshot, e) -> {
if (documentSnapshot != null) {
myRef
.get()
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
DocumentSnapshot doc = task.getResult();
if (doc != null) {
// take some data from DB
} else {
Log.d(TAG,"doc is null");
}
reset();
}
})
.addOnFailureListener(e1 -> Log.d(TAG, e1.toString()));
} else if (e != null) {
Log.d(TAG,e.toString());
} else {
Log.d(TAG,"something went wrong.");
}
});
inLoop = true;
playing = false;
gameThread = new Thread(this);
gameThread.start();
Log.d(TAG,"resume: end");
}
@SuppressLint("DefaultLocale")
private void reset() {
Log.d(TAG,"reset: start");
if (surfaceHolder.getSurface().isValid()) {
//execute other code
playing = false;
inLoop = true;
} else {
Log.d(TAG,"surfaceHolder.getSurface() is not valid");
}
Log.d(TAG,"reset: end");
}
}