trò chơi libgdx không xử lý


7

Trò chơi của tôi không thoát hoàn toàn ngay cả sau khi gọi phương thức dispose (). Nó tải một màn hình đen khi tôi khởi chạy lần thứ hai và hoạt động tốt nếu tôi giết trò chơi bằng tay và khởi động lại nó.

Tôi gặp một lỗi thông báo buffer not allocated with newUnsafeByteBuffer or already disposedkhi tôi cố gắng loại bỏ đối tượng SpriteBatch. Đây là tôi nghi ngờ vấn đề là. Nhưng không thể sửa nó hoàn toàn. Xin vui lòng giúp đỡ!

Đây là cách tôi đã xây dựng nó (Tôi đã đặt mã mẫu ở đây chỉ để cho các bạn thấy rằng không có mặt sau vòng lặp có thể nhìn thấy trong chức năng xử lý, vui lòng sửa cho tôi nếu tôi sai) - Trong màn hình trò chơi,

public void dispose() {
  AssetLoader.dispose();
  render.dispose();
  Gdx.app.exit(); }

Dưới lớp AssetLoader-

public void dispose(){
  Texture.dispose();
  sound.dispose();
}

Dưới lớp kết xuất trò chơi -

public void dispose(){
  spritebatch.dispose(); //throws an error when I GameScreen.dispose is called
  font.dispose();
  shaperender.dispose();
}

Tôi tin rằng spritebatch của tôi không xử lý gây ra màn hình đen nhưng tôi không thể tìm cách loại bỏ nó thành công. Mọi sự trợ giúp sẽ rất được trân trọng.


Bạn đang nói về Android? libgdx là đa nền tảng, vì vậy đó sẽ là một thông tin tốt để có :-) Tôi mong đợi android: Hãy thử như sau: Bắt đầu trò chơi của bạn và nhấn nút home của thiết bị. Trò chơi sẽ KHÔNG bị đóng cửa - nó sẽ bị mất. Nếu bạn khởi động lại nó sẽ nhận được KẾT QUẢ và không khởi động lại. Bạn có thể bị mất kết cấu - phụ thuộc vào cách bạn thực hiện nó. Tôi không thể nhớ chính xác vào lúc này, nhưng bạn cần quan tâm đến tình huống đó. Thông thường android quyết định khi nào thực sự dỡ tải một ứng dụng không phải là nhà phát triển. Vì vậy, bạn phải quan tâm đến một sơ yếu lý lịch (ví dụ như cuộc gọi điện thoại đến, v.v.) ..
reiti.net

bạn có thực sự sử dụng "Texture" .dispose (); hoặc <nameOfYourTexture (s)>. dispose (); ?
wes

Câu trả lời:


4

Phần thân của dispose()phương thức không phải là nơi thích hợp để gọi Gdx.app.exit()phương thức. Gọi cái sau sẽ gọi cuộc gọi của người trước và vì vậy bạn kết thúc bằng việc gọi dispose()vào đối tượng của mình lần thứ hai. Gợi ý: Đọc javadoc của Gdx.app.exit()phương thức để xem chính xác những gì nó làm.

Điều bạn nên làm là:

  1. Loại bỏ Gdx.app.exit()cuộc gọi khỏi dispose()phương thức của bạn .
  2. Bạn có một hide()phương thức, được gọi khi ứng dụng của bạn bị "ẩn" khi bạn nhấn nút home, nhận cuộc gọi đến, v.v. Đặt cuộc gọi đến phương thức xử lý tại đây.
  3. Đặt cuộc gọi đến Gdx.app.exit()ví dụ trong phần thân người nghe của một nút chịu trách nhiệm thoát khỏi trò chơi hoặc bắt nút nhấn trong Android và sử dụng nút đó ở đó.

Bằng cách này, bạn sẽ đảm bảo tất cả các tài nguyên của mình được xử lý một cách chính xác và bạn không cố gắng xử lý thứ gì đó lần thứ hai.

Hi vọng điêu nay co ich.


0

Có, bạn có thể viết tất cả mã của bạn trong phương thức ẩn. Nhưng nếu sự cố vẫn xảy ra thì bạn có thể thực hiện tất cả công việc xử lý ngay trước khi bạn tải Tài sản của mình và làm cho SpriteBatch trở nên rỗng khi bắt đầu và sau đó tạo đối tượng của nó.

Giống :

AssetLoader.dispose (); AssetLoader.load ("đường dẫn của kết cấu", "Type. Class");

spriteBatch = null; spriteBatch = new SpriteBatch ();


0

Đây là một chủ đề cũ, nhưng tôi đã có cùng một vấn đề và cuối cùng đã tìm ra nó bằng cách sử dụng Gdx.app.log("note: ", "dispose called")các bản in LogCat trong phương pháp xử lý của mỗi màn hình. Điều thực sự xảy ra là (trên Android):

  1. Nhấn nút HOME => phương thức pause()được gọi.
  2. Khởi động lại ứng dụng một lần nữa và khi khởi động lại phương thức loại bỏ của màn hình cuối cùng được gọi để làm mới màn hình. Thông thường không nên có bất kỳ vấn đề ở đây.

Vấn đề phát sinh (ít nhất là trong trường hợp của tôi) khi tôi nhấn nút RETURN và khởi động lại ứng dụng một lần nữa, dẫn đến sự cố. Bây giờ, điều này xảy ra:

  1. Nhấn nút RETURN => cái này gọi dispose()phương thức chính , KHÔNG phải pause()phương thức. Do đó, mọi tài nguyên đều được xử lý.
  2. Sau đó, khi khởi chạy lại ứng dụng, nó sẽ cố gắng loại bỏ màn hình cuối cùng một lần nữa để làm mới, nhưng điều đó đã được xử lý bằng cách nhấn nút RETURN. Vì vậy, đây là vấn đề: phương pháp xử lý của màn hình hiện tại được gọi hai lần khi nhấn RETURN, dẫn đến lỗi sau : java.lang.IllegalArgumentException: buffer not allocated with newUnsafeByteBuffer or already disposed.

Tôi đã giải quyết vấn đề này bằng cách sử dụng boolean để kiểm tra xem màn hình hiện tại đã được xử lý chưa. Dưới đây là một ví dụ (tôi sử dụng một Screenlớp trừu tượng và một ScreenManager, thiết lập một màn hình mới bằng cách gọi createphương thức của một lớp con):

public class MainScreen extends Screen {

    private boolean disposed;

    @Override
    public void create() {
        disposed = false;
        //rest of your code here
    }

    @Override
    public void dispose() {
        if (disposed == false) {
            //dispose your resources here
            disposed = true;
        }
    }
}

Vì vậy, sau khi nhấn RETURN, disposedsẽ được đặt thành true. Khi khởi chạy lại nó vẫn sẽ đúng, vì vậy tài nguyên không được xử lý hai lần. Tiếp theo màn hình được đặt lại, tự động gọi createnhư vậydisposed = false

Tôi hy vọng điều này sẽ giúp bất cứ ai có vấn đề tương tự trong tương lai :)


1
Tại sao không chỉ sử dụng : if(!disposed)?
Ammar Tarajia

0

Gọi Gdx.app.exithàm gọi disposehàm này từ chính ApplicationListenercủa trò chơi nào. Việc gọi hàm bên trong xử lý sẽ gây ra sự đệ quy của hàm vì nó sẽ đến Gdx.app.exithàm bên trong disposehàm mà nó gọi dẫn đến một lỗi khi nó cố gắng xử lý một cái gì đó đã được xử lý.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.