Vòng lặp trò chơi phía máy chủ


8

Nhiều trò chơi java sử dụng thread.s ngủ () để điều khiển fps. Vì máy chủ không hiển thị đồ họa, vòng lặp trò chơi máy chủ có nên tiếp tục chạy chỉ tính thời gian delta không? Giống như ví dụ này:

long lastLoopTime = System.nanoTime();
final int TARGET_FPS = 60;
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;   

while (gameRunning)
{
   long now = System.nanoTime();
   long updateLength = now - lastLoopTime;
   lastLoopTime = now;
   double delta = updateLength / ((double)OPTIMAL_TIME);

   doGameUpdates(delta);
}

11
"Nhiều trò chơi java sử dụng thread.s ngủ () để điều khiển fps" Man, tôi hy vọng là không.
MichaelHouse

1
@ Byte56 Tôi sẽ không nói nhiều, nhưng một số có thể làm một việc như vậy. Mặc dù bedig là một cái gì đó phổ biến, cơ chế của nó không được xác định trước. Thread.Sleeplà cách đơn giản nhất, một số có thể chờ hệ điều hành bị gián đoạn. Bạn thậm chí có thể tính vSync như một cơ chế ngủ.
Ali1S232

Câu trả lời:


6

Có nhiều lý do tôi sẽ không đề xuất rằng:

  1. Tài nguyên máy tính có giá trị. ngay cả khi chúng là miễn phí, bạn không nên lãng phí chúng. hãy xem xét trường hợp hai hoặc nhiều máy chủ đang chạy đồng thời trên một máy tính. Nếu một phiên bản duy nhất của máy chủ tiêu thụ tất cả các chu kỳ CPU, các phiên bản khác sẽ đơn giản thất bại. Chắc chắn HĐH sẽ cố gắng xử lý hành vi tham lam này nhưng nó sẽ phải trả giá. Bạn sẽ không biết hệ điều hành sẽ tạm dừng quá trình của bạn ở đâu và đưa chu kỳ CPU cho người khác. Ngoài ra, bạn có thể muốn phát hành máy chủ của mình cùng với trò chơi thực tế, để người chơi có thể bắt đầu trò chơi LAN của riêng họ. Thật khó chịu nếu tôi dành một trong số các lõi CPU của mình chỉ để chạy một máy chủ trò chơi!

  2. Hầu hết các trò chơi, trò chơi được đồng bộ hóa đặc biệt, sử dụng bước thời gian cố định. đơn giản vì họ muốn có thể dự đoán những gì sẽ xảy ra phía khách hàng. Bước thời gian động rất tuyệt vời vì nhiều lý do miễn là bạn đang chạy một phiên bản duy nhất của trò chơi và nó sẽ không được đồng bộ hóa với bất kỳ nơi nào khác. Nó sẽ cấp cho bạn sức mạnh của hệ thống chạy trò chơi đến mức tối đa. Nhưng một lần nữa có một mức giá cho nó. Bạn sẽ không thể dự đoán điều gì sẽ xảy ra nếu bạn chạy lại trò chơi. xem xét va chạm vật lý đơn giản, trong đó một hộp đang va vào một hộp khác. Ngay cả thay đổi nhỏ nhất trong bước thời gian sẽ dẫn đến sự khác biệt lớn trong kết quả giải quyết va chạm.

  3. Có một lý do đơn giản tại sao mọi người sử dụng Thread.S ngủ như bạn đề xuất, bởi vì thêm độ chính xác sẽ không dẫn đến một trò chơi tốt hơn. Khi bạn đang chơi trò chơi, bạn thường không chú ý nếu một đối tượng tắt một hoặc hai pixel. Vì vậy, bạn sẽ không đạt được bất cứ điều gì bằng cách tăng độ chính xác. Ngoài ra còn có giới hạn độ rộng băng tần mạng, cả phía máy chủ và phía máy khách. Có nghĩa là bạn thường sẽ không thể gửi hơn 30-60 cập nhật mỗi giây. Vì vậy, tôi có thể hỏi tại sao bạn nên tính toán các trạng thái bạn chỉ đơn giản là sẽ vứt bỏ?

  4. Có nhiều trường hợp tăng độ chính xác có thể gây rắc rối. Ví dụ, mọi người có xu hướng sử dụng "Đồng bộ hóa dọc" để bộ đệm đồ họa không được cập nhật trong khi nó gửi dữ liệu tới màn hình (điều này có thể dẫn đến vỡ). Ngoài ra hầu hết các trò chơi sử dụng phao làm thùng chứa số chính nhưng chúng không chính xác. Bạn có thể không nhận thấy khi các số nằm trong khoảng từ 2 ^ -20 đến 2 ^ 20 nhưng ngoài phạm vi đó bạn sẽ thấy các hành vi không chính xác. Ví dụ: nếu bạn thử thêm 10 ^ -5 đến 10 ^ 5 thì đơn giản là bạn bỏ qua phần bổ sung của mình. Những lỗi này thường không hiển thị, nhưng khi bạn không có toàn quyền kiểm soát bước thời gian của mình, mọi thứ có thể trở nên tồi tệ. Trong trường hợp của bạn, vì không có kết xuất nào, tôi cho rằng thời gian cập nhật của bạn sẽ ở mức khoảng 10 ^ -4, nghĩa là tất cả các thay đổi cho các số trên 100 sẽ bị rối tung!

  5. Trong một số trò chơi, chỉ có các lệnh của người chơi sẽ tạo ra sự khác biệt không thể đoán trước. vì vậy bạn có thể chỉ muốn sử dụng máy chủ của mình để phát các lệnh của từng người chơi cho những người chơi khác. Trong những trường hợp này, bạn có thể chỉ cần đợi cho đến khi bất kỳ máy khách nào gửi máy chủ cập nhật. Không có gì để tính toán giữa các bản cập nhật đó, có nghĩa là khách hàng có thể làm mọi thứ (bên cạnh truyền rộng), vì vậy hãy để máy chủ chỉ thực hiện công việc của mình và để lại bất cứ điều gì khác cho khách hàng.


Cảm ơn, bạn đã làm điểm tốt ở đó. Tôi nghĩ rằng tôi không cần dấu thời gian thay đổi. Chỉ một điều nữa, bạn gợi ý gì về cơ chế ngủ?
Wolfrevo Kcats

@WlofrevoKcast Hoàn toàn dựa trên nhu cầu trò chơi của bạn, nhưng đối với hầu hết các trò chơi, bộ hẹn giờ ngôn ngữ nội bộ (hoặc ngắt thời gian của hệ điều hành) là lựa chọn đủ tốt.
Ali1S232

4

Bạn nên đọc cái này (Dấu thời gian bán cố định hoặc Hoàn toàn cố định?)cái này (Gaffer trên Trò chơi - Khắc phục Dấu thời gian của bạn) .

Tôi không chắc tại sao bạn lại đưa FPS mục tiêu vào logic máy chủ của mình. Tìm một bước thời gian cố định phù hợp với bạn và cập nhật theo đó.

Về cơ bản, bạn sẽ có một vòng lặp khác trong vòng while (gameRunning)lặp sẽ tích lũy thời gian cho đến khi nó sẵn sàng thực hiện cập nhật. Sau đó, bạn đang thực hiện cập nhật tại các khoảng thời gian cố định.

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.