2014-04-12 14 views
5

Vì vậy, tôi đang tạo một trò chơi trong LibGDX nơi tôi đang sử dụng AssetManager để tải tất cả nội dung của mình. Tôi không chắc chắn đó là cách thích hợp để sử dụng nó.xử lý thích hợp LibGDX AssetManager

Hiện tại tôi đang tải tất cả nội dung trò chơi trước màn hình đầu tiên. Sau đó, tôi xóa người quản lý trong phương thức vứt bỏ. Nhưng điều đó có nghĩa rằng tôi có một loạt các kết cấu vv mà tôi sẽ không cần cho tất cả các màn hình. Có thể dẫn đến rò rỉ bộ nhớ?

Cách tiếp cận khác mà tôi có trong đầu là chỉ tải các nội dung tôi cần cho mỗi màn hình và sau đó giải phóng chúng trong mỗi phương thức hide() của màn hình.

Vì vậy, tôi đã tự hỏi phương pháp nào trong hai phương pháp này là cách tốt nhất để đi, hoặc nếu có một cách tốt hơn để giải quyết vấn đề này?

Cảm ơn

Trả lời

7

Đầu tiên: nếu bạn đang phát triển trên Android, hide() sẽ được gọi mỗi khi người dùng trả lời điện thoại hoặc công tắc của họ sang ứng dụng khác. Điều đó có nghĩa là bạn phải phân bổ lại tài nguyên theo số show(). Đối với các trò chơi chuyên sâu về tài nguyên, chẳng hạn như RPG, điều này có thể dẫn đến màn hình đen khó chịu trong khi trò chơi đang phân bổ lại đồ họa, v.v. Không vui.

Thứ hai: hãy cẩn thận khi tối ưu hóa trò chơi của bạn sớm. Nếu bạn gặp lỗi Out-of-Memory, một vài đồ họa bạn quên bỏ có thể không phải là nút cổ chai.

Với những điểm trên đường đi, tôi đã phát hiện ra rằng cách dễ nhất để thực hiện các bộ nạp tài sản là phải có một lớp riêng biệt Assets, tìm một cái gì đó như thế này:

public static AssetManager manager; 
public static TextureAtlas myGraphics; 
public static TextureAtlas myOtherGraphics; 

public static void create() { 
    manager = new AssetManager(); 
    load(); 
} 

private static void load() { 
    manager.load("mygraphics.pack", TextureAtlas.class); 
    manager.load("myothergraphics.pack", TextureAtlas.class); 
} 

public static void done() { 
    myGraphics = manager.get("mygraphics.pack", TextureAtlas.class); 
    myOtherGraphics = manager.get("myothergraphics.pack", TextureAtlas.class); 
} 

public static void dispose() { 
    manager.dispose(); 
} 

Sau đó, trong màn hình loading của bạn của render() phương pháp, tất cả những gì bạn phải làm là gọi Assets.manager.update() - nếu nó trả về true, hãy gọi Assets.done() và chuyển sang trò chơi của bạn.

Có một vài lợi ích cho cách tiếp cận này. Đầu tiên, nó cho phép bạn giữ tất cả logic tải nội dung của bạn trong một lớp. Thứ hai, nếu bạn phải loại bỏ tài nguyên theo cách thủ công, bạn có thể chỉ cần gọi Assets.myGraphics.dispose().

Nếu bạn thấy rằng bạn có quá nhiều dữ liệu đồ họa để nạp quá trình khởi động (ví dụ: 10 MB bộ sprites trên Android), bạn cũng có thể thử phá vỡ lưu dữ liệu đồ họa của bạn thành những phần rời rạc. Trong trò chơi của tôi, mỗi sprite có một TextureAtlas riêng biệt, và mỗi TextureAtlas được lưu trữ trong một mảng khi nó được nạp.

Các sprites được sử dụng thường xuyên, chẳng hạn như ký tự chính, luôn được giữ trong bộ nhớ, trong khi các sprites cũ hơn được tải xuống theo thời gian. Với phương pháp này, thay vì sử dụng 10 MB bộ nhớ trên sprites, tôi hiện đang sử dụng ít hơn 0,5 MB.

+0

Cảm ơn bạn đã trả lời! Tôi có một thiết lập tương tự trong trò chơi của tôi nhưng thay vì có tất cả mọi thứ tĩnh tôi có một lớp singleton. Không thực sự biết cách nào là tốt hơn. Tôi làm tất cả việc tải và dỡ các kết cấu trong lớp Tài sản của tôi nhưng tôi không gọi manager.dispose() trong lớp nội dung của tôi. Chỉ có manager.clear(). Tôi biết điều này là sai, nhưng khi tôi sử dụng phương thức dispose(), ứng dụng của tôi sẽ gặp lỗi khi tôi tiếp tục nó. Bạn có biết tại sao điều đó có thể là? Dù sao cho câu trả lời của bạn! – Johan

+1

manager.dispose() xử lý chính trình quản lý * *, vì vậy bạn nên sử dụng trình quản lý.clear() thay vào đó. Hãy nhớ rằng "tài sản trong bộ nhớ" không bằng "rò rỉ bộ nhớ", đặc biệt là với chính sách GC của Java. Bạn thực sự không cần vứt bỏ tài sản trong khi ẩn() trừ khi các ứng dụng khác đang gặp vấn đề về bộ nhớ. – user3525774

+5

Tôi có nghi ngờ về điều này. Trong wiki, nó được đề cập rằng "không làm cho AssetManager của bạn hoặc bất kỳ tài nguyên khác (như Texture, vv) tĩnh, trừ khi bạn quản lý chúng đúng cách". Nó sẽ không dễ dàng hơn nếu tôi xác định đối tượng quản lý tài sản trong lớp 'Game' của tôi và gọi nó trong suốt' Screen's? – WeirdElfB0y

Các vấn đề liên quan