Tôi đang sử dụng SurfaceView và chuỗi hiển thị để phát triển trò chơi dựa trên cấu trúc như LunarLander.Lập trình với SurfaceView và chiến lược chuỗi để phát triển trò chơi
Tuy nhiên, tôi gặp nhiều vấn đề, và ở đây tôi muốn chỉ ra tất cả chúng. Tôi muốn bất cứ ai muốn phát triển một trò chơi sẽ không cần phải đấu tranh với họ nữa. Và bất kỳ ai có ý tưởng tốt hơn về cấu trúc đều có thể chia sẻ kinh nghiệm của họ, bởi vì tôi vẫn còn mới với android và háo hức muốn tìm hiểu :)
[1] Không nên gọi nhiều hơn thread.start()
.
Nhiều bài báo đề cập để tạo ra một thread khi bề mặt được tạo ra, để làm lại sau khi hoạt động dừng lại sử dụng phương pháp này:
public void surfaceCreated(SurfaceHolder holder) {
// start the thread here so that we don't busy-wait in run()
// waiting for the surface to be created
if (thread.getState() == Thread.State.TERMINATED)
{
thread = new LunarThread(getHolder(), getContext(), getHandler());
}
thread.setRunning(true);
thread.start();
}
Bạn có thể thấy rằng nếu các chủ đề không được chấm dứt và chức năng là được gọi là hoạt động bị treo.
[2] Nếu bạn nhấn nút "power" hoặc "red phone" hoặc điện thoại không hoạt động trong vài phút, hoạt động sẽ là trạng thái onPause()
nhưng chuỗi vẫn đang chạy. Đó là một thực tế tồi tệ, vì vậy tôi cần phải tìm ra một phương pháp để cho sợi chỉ dừng lại và bắt đầu lại khi onResume()
.
[3] Nếu khóa màn hình là dọc/ngang và trò chơi của bạn được dán theo hướng khác, khóa màn hình buộc bạn phải "định hướng" một lần. Điều đó có nghĩa là để bắt đầu hoạt động một lần nữa. Tôi vẫn không thể tìm ra giải pháp cho nó. (Như tôi đã đề cập trong Android screen orientation bug)
Dưới đây là mã của tôi để sửa chữa những vấn đề:
UIThread
public class UIThread extends Activity
{
private gameView gameview;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gameview = (gameView) findViewById(R.id.gameview);
}
protected void onPause()
{
super.onPause();
Log.v("MY_ACTIVITY", "onPause");
gameview.terminateThread();
System.gc();
}
protected void onResume()
{
super.onResume();
Log.v("MY_ACTIVITY", "onResume");
if (gameview.surfaceCreated == true)
{
gameview.createThread(gameview.getHolder());
}
}
}
GameView
public class gameView extends SurfaceView implements SurfaceHolder.Callback
{
boolean surfaceCreated;
class gameThread extends Thread{}
public gameView(Context context, AttributeSet attrs)
{
super(context, attrs);context.getResources();
Log.v("MY_ACTIVITY", "gameView");
surfaceCreated = false;
}
public void createThread (SurfaceHolder holder)
{
thread = new gameThread(holder);
thread.run = true;
thread.start();
}
public void terminateThread()
{
thread.run = false;
try
{
thread.join();
}
catch (InterruptedException e)
{
Log.e("FUNCTION", "terminateThread corrupts");
}
}
public void surfaceCreated(SurfaceHolder holder)
{
Log.v("MY_ACTIVITY", "surfaceCreated");
if (surfaceCreated == false)
{
createThread(holder);
surfaceCreated = true;
}
}
public void surfaceDestroyed(SurfaceHolder holder)
{
Log.v("MY_ACTIVITY", "surfaceDestroyed");
surfaceCreated = false;
}
}
Manifest
<activity android:name=".UIThread"
android:screenOrientation="landscape"
android:configChanges="orientation">
Tôi sử dụng onResume()
thay vì surfaceCreated()
cho chuỗi mới. Và tôi đặt một boolean surfaceCreated
để biết rằng onResume()
xuất phát từ ứng dụng lần đầu tiên được tạo hoặc xuất phát từ tình huống "tắt màn hình".
Vì vậy, chuỗi chết mỗi khi onPause()
được gọi. Có vẻ là một thực hành tốt. Một cách khác để cho thread dừng lại sau đó tiếp tục lại là để đồng bộ hóa một đối tượng và gọi chờ/thông báo. Nhưng tôi không biết nó tốt hơn hay không.
Có cách nào tốt hơn để kiểm soát chuỗi hiển thị không?
Có thể có liên quan: http://stackoverflow.com/questions/21567641/ nên-the-renderingthread-of-a-surfaceview-có-cùng-cuộc sống-chu kỳ-as-the-view/21684399 # 21684399 – fadden