2009-04-28 39 views
11

Tôi đang tạo trò chơi dựa trên lưới trong Java và tôi muốn triển khai ghi và phát lại trò chơi. Tôi không chắc chắn cách thực hiện việc này, mặc dù tôi đã xem xét 2 ý tưởng:Cách tốt nhất để triển khai phát lại trò chơi là gì?

  1. Vài lần mỗi giây, tôi sẽ ghi lại toàn bộ trạng thái trò chơi. Để phát lại, tôi viết một trình kết xuất để đọc các trạng thái và cố gắng tạo ra một biểu diễn trực quan. Tuy nhiên, với điều này, tôi có thể có một tệp lưu lớn và mọi nỗ lực phát lại có thể có độ trễ đáng chú ý.

  2. Tôi cũng có thể viết mọi lần nhấn và nhấp chuột chính vào tệp lưu. Điều này sẽ cho tôi một tập tin nhỏ hơn, và có thể phát lại với độ trễ ít hơn. Tuy nhiên, lỗi nhỏ nhất khi bắt đầu trò chơi (Ví dụ: quay 1 mili giây sau) sẽ dẫn đến trạng thái trò chơi rất khác nhau trong vài phút vào trò chơi.

Vậy thì, cách tốt nhất để triển khai phát lại trò chơi là gì?

Chỉnh sửa- Tôi không chắc chắn cách xác định trò chơi của mình, vì vậy tôi không chắc chắn rằng toàn bộ trò chơi có thể được ghép chính xác bằng cách chỉ ghi lại các lần nhấn phím và chuột.

Trả lời

14

Cơ chế phát lại tốt không phải là thứ có thể được thêm vào trò chơi mà không gặp khó khăn lớn. Điều tốt nhất sẽ là thiết kế cơ sở hạ tầng trò chơi với nó trong tâm trí. Bạn có thể sử dụng command pattern để đạt được cơ sở hạ tầng trò chơi như vậy.

Ví dụ:

public interface Command{ 
    void execute(); 
} 
public class MoveRightCommand implements Command { 
    private Grid theGrid; 
    private Player thePlayer; 

    public MoveRightCommand(Player player, Grid grid){ 
     this.theGrid = grid; 
     this.thePlayer = player; 
     } 

    public void execute(){ 
    player.modifyPosition(0, 1, 0, 0); 
    } 
} 

Và sau đó các lệnh có thể được đẩy vào một hàng đợi thực hiện cả khi người dùng nhấn một nút bàn phím, di chuyển chuột hoặc không có một kích hoạt với cơ chế phát lại. Đối tượng lệnh có thể có giá trị tem thời gian (tương ứng với đầu phát lại) để phát lại chính xác ...

+2

Đây là một cách thanh lịch để xử lý. Nếu trò chơi thực tế và bản ghi âm dựa trên cùng một cơ chế thời gian/khung hình, bạn nên tránh các lỗi do vấn đề về thời gian. Nếu bạn có ngẫu nhiên trong các sự kiện của bạn, bạn có thể cần phải ghi lại giá trị hạt giống bắt đầu cho trình tạo số ngẫu nhiên của bạn. Đó là cách các chức năng 'Bản đồ ngẫu nhiên' trong các trò chơi RTS cho phép bạn tạo lại một bản đồ ngẫu nhiên mà bạn thích. –

+0

Mẫu này cũng có thể cung cấp cho bạn khả năng Hoàn tác/Làm lại. –

2

Tại sao không ghi lại nhiều lần trong một giây và sau đó nén đầu ra của bạn, hoặc có lẽ làm điều này:

recordInitialState(); 
... 
runs 30 times a second: 
recordChangeInState(previousState, currentState); 
... 

Nếu bạn chỉ ghi lại sự thay đổi trong tình trạng với một dấu thời gian (và mỗi thay đổi nhỏ, và nếu có không có thay đổi, sau đó ghi lại không có gì), bạn nên kết thúc với kích thước tập tin hợp lý.

3

Giả sử rằng trò chơi của bạn là xác định, có thể là đủ nếu bạn ghi lại đầu vào của người dùng (tùy chọn 2). Tuy nhiên, bạn sẽ cần phải chắc chắn rằng bạn đang nhận ra thời gian chính xác và nhất quán cho những sự kiện này, chẳng hạn như khi nó được máy chủ nhận ra. Tôi không chắc chắn cách bạn xử lý các sự kiện trong lưới.

Nỗi lo lắng của tôi là nếu bạn không có cơ chế có thể tham chiếu thống nhất các sự kiện theo thời gian, có thể có vấn đề với cách mã của bạn xử lý người dùng được phân phối.

Hãy xem xét trò chơi như Halo 3 trên XBOX 360 chẳng hạn - mỗi khách hàng sẽ ghi lại quan điểm của trò chơi, bao gồm sửa lỗi dựa trên máy chủ.

2

Không cần phải lưu mọi thứ trong cảnh cho mỗi khung hình. Lưu các thay đổi gia tăng và sử dụng một số kỹ thuật nội suy tốt. Tôi sẽ không thực sự sử dụng một phương pháp tiếp cận dựa trên mẫu lệnh, mà là kiểm tra ở một mức cố định cho mỗi đối tượng trò chơi và xem nó có thay đổi bất kỳ thuộc tính nào không. Nếu có thay đổi mà thay đổi được ghi lại trong một số mã hóa tốt và phát lại thậm chí sẽ không trở thành lớn.

2

Cách tiếp cận này sẽ phụ thuộc rất nhiều vào ngôn ngữ bạn đang sử dụng cho trò chơi của mình, nhưng nói chung có nhiều cách tiếp cận, tùy thuộc vào việc bạn muốn sử dụng nhiều bộ nhớ hay muốn trì hoãn. Sẽ rất hữu ích nếu bạn có thể đưa ra một số suy nghĩ về những hy sinh mà bạn sẵn sàng thực hiện. Tuy nhiên, dường như cách tiếp cận tốt nhất có thể là chỉ lưu đầu vào từ người dùng, như đã đề cập và lưu trữ vị trí của tất cả các diễn viên/sprites trong trò chơi cùng một lúc, điều này đơn giản như chỉ lưu hướng, vận tốc và gạch x, y, hoặc, nếu mọi thứ có thể được xác định thì bỏ qua các tác nhân/sprites khi bạn có thể nhận được thông tin của họ.

Cách thức không xác định trò chơi của bạn cũng sẽ hữu ích để đưa ra đề xuất tốt hơn.

Nếu có nhiều chuyển động động, chẳng hạn như một trận derby sụp đổ, bạn có thể muốn lưu thông tin mỗi khung hình, vì bạn nên cập nhật trình phát/diễn viên ở tốc độ khung hình nhất định.

2

tôi sẽ chỉ đơn giản nói rằng cách tốt nhất để ghi lại một phát lại của một trò chơi hoàn toàn phụ thuộc vào bản chất của trò chơi. Là lưới dựa trên không phải là vấn đề; vấn đề là hành vi có thể đoán trước theo sau sự thay đổi trạng thái, tần suất có đầu vào mới cho hệ thống, cho dù có dữ liệu ngẫu nhiên được tiêm vào bất kỳ thời điểm nào, v.v. Bạn có thể lưu trữ toàn bộ trò chơi cờ vua bằng cách ghi lại từng bước di chuyển, nhưng điều đó sẽ không hiệu quả đối với một game bắn súng góc nhìn người đầu tiên mà không có lượt rẽ rõ ràng. Bạn có thể lưu trữ một game bắn súng người đầu tiên bằng cách ghi nhận thời gian chính xác của mỗi đầu vào, nhưng điều đó sẽ không hiệu quả đối với RPG mà kết quả của một đầu vào có thể được sửa đổi bởi kết quả của một cuộn xúc xắc ngẫu nhiên. Ngay cả ý tưởng dường như không rõ ràng khi chụp nhanh nhất có thể không đủ tốt nếu thông tin quan trọng xuất hiện ngay lập tức và không tồn tại dưới bất kỳ hình thức nào có thể bắt được.

Điều thú vị này rất giống với vấn đề bạn gặp phải khi kết nối mạng. Làm thế nào để một máy tính đảm bảo rằng một máy tính khác được nhận biết về trạng thái trò chơi, mà không phải gửi toàn bộ trạng thái trò chơi đó ở tần số cao không chính xác? Cách tiếp cận điển hình kết thúc là một hỗn hợp riêng biệt của các thông báo sự kiện và cập nhật trạng thái, có lẽ là những gì bạn cần ở đây.

1

Tôi đã làm điều này một lần bằng cách mượn ý tưởng từ nén video: khung hình chính và khung trung gian. Về cơ bản, cứ sau vài giây bạn sẽ lưu lại trạng thái hoàn chỉnh của thế giới. Sau đó, mỗi lần cập nhật trò chơi, bạn lưu tất cả các thay đổi cho trạng thái thế giới đã xảy ra kể từ lần cập nhật trò chơi cuối cùng. Các chi tiết (tần suất bạn lưu các khung hình chính là gì? Chính xác được tính là 'thay đổi trạng thái thế giới') sẽ phụ thuộc vào loại thông tin trò chơi bạn cần bảo tồn.

Trong trường hợp của chúng tôi, thế giới bao gồm nhiều đối tượng trò chơi, hầu hết trong số đó vẫn giữ nguyên tại bất kỳ thời điểm nào, vì vậy cách tiếp cận này đã tiết kiệm cho chúng ta rất nhiều thời gian và bộ nhớ. di chuyển. Trong của bạn, sự cân bằng có thể khác nhau.

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