2009-09-21 36 views
9

Tôi hiện đang làm việc trên một trò chơi Flash platformer rất lớn (hàng trăm lớp) và giải quyết một vấn đề mà trò chơi từ từ dừng lại nếu bạn để nó đủ lâu. Tôi đã không viết trò chơi và vì vậy tôi chỉ mơ hồ quen thuộc với nội bộ của nó. Một số triệu chứng bí ẩn bao gồm,AS3 giảm hiệu suất trò chơi lớn theo thời gian

  • Trò chơi sẽ chạy tốt trong một khoảng thời gian xác định (trên một mức nhất định) khi đột ngột bắt đầu rò rỉ bộ nhớ.
  • Thời gian cần thiết để trò chơi đạt đến điểm mà nó bị rò rỉ theo cấp số nhân ngắn hơn khi có nhiều hình họa trên màn hình.
  • Ngay cả khi không có gì hiển thị rõ ràng trên màn hình, trò chơi sẽ chậm lại.
  • Trò chơi sẽ chậm hơn với các va chạm sprite thường xuyên hơn.
  • Hoàn toàn vô hiệu hóa mã xung đột sẽ làm chậm sự xuống cấp nhưng không ngăn trò chơi từ bỏ khung hình cuối cùng.

Nhìn vào nguồn và sử dụng Flex profiler, nghi phạm chính của tôi là,

  • Có rất nhiều đối tượng lảng vảng, đặc biệt là WeakMethodClosure, chiếm một lượng lớn bộ nhớ.
  • Chương trình sử dụng vô cùng rộng rãi các trình nghe sự kiện yếu (hàng chục được gửi cho mỗi khung).
  • BitmapData đang được sao chép mỗi lần tạo một sprite mới. Đây là những sprites 50x50 pixel sinh ra ở khoảng 8 sprites mỗi giây.

Tôi biết không thể nói cho tôi biết sự cố mà không thấy nguồn, vì vậy tôi chỉ tìm kiếm các mẩu tin có thể giúp tôi thu hẹp điều này. Có ai đã trải qua sự suy thoái hiệu suất lảng tránh này trong các dự án của riêng họ không? Nguyên nhân trong trường hợp của bạn là gì?

Trả lời

7

Gần đây tôi đã hoàn thành tối ưu hóa một dự án lớn. Và tôi có thể cung cấp cho bạn một số lời khuyên kiến ​​trúc:

  1. nguyên tắc chính - cố gắng làm càng ít càng tốt chức năng/sự kiện gọi
  2. Nhận thoát khỏi tắt tất cả nhưng một onEnterFrame/onInterval/OnTimer chu kỳ. Thực hiện mọi thứ bạn cần cần trong số một cuộc gọi chung. Bạn có thể sẽ cần rất nhiều mảng tĩnh để lưu trữ các tham chiếu đã được xử lý .
  3. làm đồ họa của bạn/render thứ cũng trong vòng lặp chính một
  4. Hãy thử sử dụng lớn bức tranh sơn dầu (có thể được kết xuất trước) thay vì sprites nhỏ/bitmap. Thông thường nó có thể sử dụng được cho nền. Nhưng cũng làm việc tốt cho một vật thể nhỏ hơn (như cây cối, nền tảng, vv)
  5. thoát khỏi tắt nguồn bitmap nhỏ, lắp ráp nó vào một gạch-tờ và vẽ công cụ của bạn trực tiếp từ nó, thông qua sở hữu nguồn rect

Tôi hy vọng nó sẽ giúp bạn! Rò rỉ bộ nhớ - sự cố như vậy.

P.S. Kiểm tra trò chơi của bạn trong các trình duyệt khác nhau, IE - phần lớn rò rỉ tất cả, đôi khi nó không xóa bộ nhớ sau mỗi lần làm mới.

+0

Tôi nghĩ rằng đây là lời khuyên tuyệt vời cho ai đó vừa bắt đầu một dự án chơi game lớn và tự hỏi làm thế nào để cấu trúc nó tốt nhất. – Kai

0

Có vẻ như bạn cần phải lập hồ sơ ứng dụng của mình để xem điều gì đang xảy ra.

Chủ đề này có một vài gợi ý, nhưng, cuối cùng, bạn sẽ cần phải chỉ cần đưa vào mã để giúp xác định những gì đang xảy ra.

Profiling ActionScript-3 Code

Bạn có thể muốn xem nếu bạn chỉ có thể chạy một số phần nhỏ hơn trong một khoảng thời gian và xem nếu bạn nhìn thấy một sự suy giảm.

Bạn có thể muốn đơn vị kiểm tra ứng dụng của bạn, vì vậy bạn có thể chạy các phần khác nhau nhanh chóng, tìm kiếm rò rỉ bộ nhớ. Một khuôn khổ là: http://asunit.org/, và khác là: http://opensource.adobe.com/wiki/display/flexunit/

Đơn vị kiểm tra là một cái gì đó tôi sử dụng rất nhiều cho hồ sơ, vì vậy bạn có thể kiểm tra ở cấp cao nhất của trò chơi của bạn, chạy nó hàng ngàn lần, tìm kiếm các vấn đề, sau đó chạy từng phần và xem phần nào có sự cố và chỉ hoạt động theo cách của bạn. Đây là một quá trình thủ công, nhưng nếu hai ý tưởng trong chủ đề SO được liệt kê trong đầu không giúp đỡ, điều này có thể là cách tiếp cận tốt nhất của bạn.

Bạn đang sử dụng quá nhiều bộ nhớ? Hoặc là sử dụng CPU của bạn quá cao?

+0

Câu hỏi đề cập đến rò rỉ bộ nhớ, vì vậy tôi đoán rằng việc sử dụng CPU không phải là vấn đề. –

+0

Tôi đang cố gắng xem có vấn đề gì khác ngoài những gì anh ta đang đoán. Thật không may, khi tôi đoán các chương trình của tôi gặp vấn đề gì, tôi có xu hướng sai, đó là lý do tại sao tôi phụ thuộc vào việc lập hồ sơ quá nhiều. –

+0

Tôi tự hỏi nếu quá nhiều bộ sưu tập rác dẫn đến sự xuống cấp của chương trình, do có quá nhiều đối tượng được tạo ra quá nhanh. –

0

Trước tiên hãy xác định xem giới hạn bộ nhớ hoặc bộ xử lý của bạn có bị ảnh hưởng không.Nghe có vẻ như sau này, có vẻ như có nhiều đối tượng đang làm những thứ xung quanh ... có khả năng những sprites phụ không được giải phóng tốt. Tìm phụ thuộc giữa các đối tượng/biến/bất kỳ điều gì trong các sự kiện đó, đảm bảo rằng các sprites được loại bỏ, chú ý đến bất kỳ trình xử lý nào của EnterFrame hoặc các sự kiện định kỳ.

3
  • Tránh các phương pháp ẩn danh - thay đổi chúng thành các phương thức cấp lớp.
  • Sử dụng tham chiếu yếu trong addEventListener và/hoặc đảm bảo bạn xóa tất cả người nghe của một đối tượng trước khi xóa nó bằng removeChild
  • Đảm bảo bạn xóaChọn tất cả các sprites thay vì chỉ để chúng bay ra khỏi màn hình. Ngoài ra, nếu có thể, hãy sử dụng lại các sprites thay vì tạo các hình mới.
1

Bạn nên cân nhắc việc tạo nhóm đối tượng nếu bạn có nhiều sáng tạo/hủy diệt đang diễn ra, đặc biệt là với các đối tượng nặng như bitmapdata.

thấy Object Pool class

+0

Đây là một ý tưởng tuyệt vời khi tôi xác định tài nguyên nào đang gây ra nút cổ chai. – Kai

0

Nó nhiều khả năng âm thanh mà bạn đang đóng nắp ra vào tốc độ xử lý so với bộ nhớ. Bạn phải cố gắng hết sức để nhớ thêm một ứng dụng Flash.

Cũng may là có rất nhiều thứ dễ dàng, bạn có thể làm để giữ cho CPU xuống ...

1) nghiêm ngặt quản lý người nghe sự kiện cho tất cả mọi thứ , đặc biệt là người nghe chuột. Bạn có người nghe sự kiện $ texas trên tất cả các đối tượng sprite của bạn không? Đó có thể là một vấn đề.

2) Truy cập mảng bằng int hoặc uint thay vì Số. Điều này là rất lớn, và đây là một trong những thủ thuật Adobe backwater. Truy cập đối tượng mảng với int và uint là cách nhanh hơn Number và nếu bạn thực hiện rất nhiều lần lặp (và nó giống như bạn làm), điều này có thể cạo phần nghìn giây quý báu khỏi việc thực thi khung của bạn.

3) Trong cùng một tĩnh mạch như # 2, theo dõi hoạt động toán học của bạn và loại bạn đang sử dụng cho các hoạt động nhất định. Điều chậm nhất bạn có thể làm trong các phép tính toán cho AS3 là việc lặp đi lặp lại (nạp ints vào một hàm trả về một số), hoặc thực hiện các phép toán cơ bản như cộng và trừ trên số thay vì int.

Điều tuyệt vời về việc có một chương trình wtfhuge như thế này trong Flash là ngay cả một thay đổi tối ưu hóa nhỏ cũng có thể có tác động lớn đến hiệu suất. Tôi đã từng chơi với một động cơ raytrace trong AS3, nơi tôi tuyên bố thêm một biến và nó đã giết FPS của tôi từ 30 đến 23.

+0

Tôi chắc chắn rằng trò chơi của tôi đang vi phạm các quy tắc này trong ít nhất một vài nơi. Tôi hy vọng nó dễ dàng như vậy! – Kai

0
Flash có vấn đề khá khét tiếng (nhiều người coi đó là lỗi) khiến người nghe sự kiện cho bộ hẹn giờ và sự kiện ENTER_FRAME không thu thập rác, ngay cả khi họ bị tham chiếu yếu. Vì vậy, mặc dù thực hành tốt để sử dụng các sự kiện được tham chiếu yếu, bạn vẫn nên xóa tất cả người nghe sự kiện của mình khi họ không còn cần thiết nữa.
+0

Sau khi tìm kiếm nhanh Event.ENTER_FRAME tôi đã đưa ra 18 kết quả phù hợp, do đó, an toàn để nói rằng vấn đề có thể ở đây là tốt. – Kai

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