Về cơ bản, bạn đang đi đúng hướng - bạn cần biết một hoạt hình kéo dài bao lâu để thực hiện loại việc này. Ảnh động không chỉ là một bộ sưu tập các khung, có tất cả các loại thông tin khác xung quanh chúng mà bạn cần. Ví dụ: có bao nhiêu khung hình, vòng lặp hoạt hình, nó phát lại nhanh như thế nào (ví dụ 10 khung hình động mỗi giây hoặc 25, hoặc 60?). Mỗi hình ảnh động có thể được định nghĩa theo một vài phần dữ liệu, mà một số mã hoạt hình tổng quát có thể nhìn và phát lại. Bạn nên gói gọn phần hoạt hình trong một đoạn mã riêng, không biết gì ngoại trừ các định nghĩa hoạt hình này và cách hiển thị các khung hình ảnh riêng lẻ. Đó là, có một đối tượng hoạt hình mà bạn có thể tải, bắt đầu chơi, dừng phát và yêu cầu kết xuất tại một vị trí cụ thể trên màn hình.
Một cách tiếp cận linh hoạt là sử dụng một loại định nghĩa hoạt hình để gói gọn loại thông tin này. Vì vậy, thay vì chỉ nói "hoạt hình X là tất cả các khung hình này, chỉ cần phát qua chúng", bạn sẽ nhận được một cái gì đó phức tạp hơn một chút.
Ví dụ: với một số loại định dạng dữ liệu giả định
hình ảnh động =
{
{name = "walk", files = "walk * .png", frameCount = "12", loop = "true"},
{name = "fire" files = "fire * .png" frameCount = "6",
sự kiện = {
{name = "đạnLeavesGun", frame = "4", param1 = "43", param2 = "30"}
}
}
}
Vì vậy, mã của bạn nói một cái gì đó như:
currentAnimation = animations.Get("fire");
currentAnimation.Play();
Cách bạn phát hiện các sự kiện có thể bằng mã hoạt hình gọi lại cho bạn (nghĩa là khi phát hiện sự kiện mới vì hoạt hình đã phát đến một khung nhất định, nó gọi mã trò chơi của bạn để thông báo về sự kiện mới) hoặc bằng cách bỏ phiếu hoạt hình như vậy:
List<Event> events = currentAnimation.EventsSinceLastCheck();
foreach (AnimationEvent event in events)
{
if (event.name == "bulletLeavesGun")
{
Vector2 bulletPosition = new Vector2(event.param1, event.param2);
Vector2 actualBulletPosition = new Vector2(
character.x + bulletPosition.x,
character.y + bulletPosition.y);
CreateBulletAt(actualBulletPosition);
}
}
Điểm cần lưu ý:
- Mã hoạt hình nên tồn tại tách biệt với mã trò chơi. Bạn thực sự không muốn mã trò chơi của mình quá chặt với các đai ốc và bu lông phát lại hoạt hình.
- Mã hoạt hình biết có lặp hay không dựa trên định nghĩa hoạt hình
- Mã hoạt hình biết khi nào hoạt hình được hoàn thành và có thể gọi lại cho một số mã khác để nói 'này, hoạt hình được gọi là "lửa" vừa hoàn thành, bạn muốn làm gì bây giờ?'
- Mã hoạt hình không biết gì về các sự kiện ngoài việc chúng có tên và một số dữ liệu tùy ý liên quan đến chúng (param1 và param2)
- Mã hoạt hình biết khung hình hiện tại của nó là gì và khi nó chuyển sang khung mới, nó có thể kiểm tra và nói 'ồ, bây giờ tôi đang ở khung 4, điều đó có nghĩa là sự kiện này có tên là "lửa" vừa xảy ra, hãy thêm nó vào danh sách các sự kiện gần đây của tôi để tôi có thể nói với bất kỳ ai hỏi về nó '.
Nếu bạn không cần việc bắn đạn xảy ra trong hoạt hình, nhưng chỉ khi nó kết thúc, bạn có thể thoát khỏi một hệ thống ít phức tạp hơn nhiều mà không có khái niệm về các sự kiện. Nhưng bạn vẫn muốn có một hệ thống mà hoạt hình tự phát lại, biết chúng dài bao nhiêu và có thể gọi lại mã trò chơi khi hoạt ảnh hoàn tất.