2013-03-20 63 views
6

Tôi đang cố gắng xây dựng một trò chơi dựa trên văn bản cơ bản khi tôi đang học Java. Tôi muốn có thể đếm các vòng trong trò chơi như một phương tiện quản lý nhịp độ của các sự kiện nhất định. Ví dụ, thay đổi phòng có thể được giới hạn một lần mỗi vòng (một giây, trong mã thử nghiệm.) Một sinh vật nhỏ có thể tấn công hoặc thay đổi phòng ở một tỷ lệ cao hơn, trong khi một lớn hơn có thể là cồng kềnh hơn. Tốt cho đến nay? Tuyệt quá.Thời gian xử lý trong trò chơi dựa trên văn bản (Java)

Vì vậy, tôi đã nấu món này và ngay lập tức nhận ra rằng tôi sẽ đánh một khối mỗi lần vòng lặp trong khi chờ người chơi nhập lệnh. Mã số:

private void startPlaying() { 
    //declare clock/round variables. 
    int lastRound = 0; 
    int currentRound = 0; 
    long lastTime = System.currentTimeMillis(); 
    long currentTime; 

    while (player.getIsPlaying()){ 
     //Clocking 
     currentTime = System.currentTimeMillis(); 
     if ((lastTime + 1000) < currentTime) { 
      lastTime = currentTime; 
      lastRound = currentRound; 
      currentRound++; 
      System.out.println("Current round:\t" + currentRound + "\tCurrent time:\t" + currentTime); //EDIT:NOTE: This is just a test line to observe the loop. 
     }//end if (Clocking) 

     Command command = new Command(); 
     String[] commandString = command.setAll(); //Array gets parsed elsewhere. 
     player.doCommand(commandString); 
     //Class Player extends Pawn extends Actor; Pawn has most command methods. 
    } 
    finishPlaying(); 
}//END STARTPLAYING() 

Vì vậy, đây là câu hỏi của tôi:

Có cách nào tôi có thể sử dụng một phương pháp riêng để đăng nhập lần/viên đạn đồng thời để các vòng lặp trong khi trình bày các cầu thủ với một dấu nhắc lệnh?

Nếu không, có cách nào khác để làm cho vấn đề này không phải là vấn đề mà tôi chưa thấy/thực hành chưa?

Trả lời

4

Hãy xem Concurrency tutorial. Với các luồng, bạn có thể đợi đầu vào của người dùng mà không dừng các tiến trình khác (và làm cho các tiến trình khác thực hiện cùng một lúc - không song song, nhưng chia sẻ thời gian).

+0

Tôi cho rằng hướng dẫn của Oracle sẽ là một nơi hợp lý hơn để bắt đầu.Bỏ phiếu khi tôi có danh tiếng. – eenblam

1

Nó được gọi là "vòng lặp trò chơi" cho phép trò chơi chạy trơn tru bất kể đầu vào của người dùng.

Giải pháp đơn giản nhất - tạo 2 chuỗi, cuộn sẽ đợi cho người dùng nhập và đặt nó vào ConcurrentLinkedQueue với dung lượng 1. Chuỗi thứ hai sẽ chạy vòng lặp trò chơi của bạn và nhập người dùng từ hàng đợi để xử lý nếu hàng đợi không trống .

Bạn có thể sử dụng bất kỳ cấu trúc dữ liệu nào bạn muốn trao đổi dữ liệu giữa 2 luồng, nó thậm chí có thể là biến chuỗi biến động. Các yêu cầu duy nhất đọc ghi truy cập vào biến này phải được đồng bộ bằng cách nào đó.

+0

Tuyệt vời, cảm ơn lời giải thích ngắn gọn. Tôi có lẽ sẽ cần phải dành một chút thời gian trong các tài liệu, nhưng điều đó nghe khá khả thi. – eenblam

1

Cuộc phiêu lưu văn bản trong thời gian thực? Nghe có vẻ thú vị. Tôi sẽ không đề nghị cố gắng làm đồng thời cho vấn đề cụ thể này, có những cách dễ dàng hơn.

Thông thường, bạn sẽ không kết hợp tính năng chặn khi nhập với thời gian tính bằng giây. Trừ khi bạn có trái tim của bạn đặt trên thiết kế này, tôi muốn đề nghị hoặc.

1) Không chặn người dùng nhập. Viết mã xử lý đầu vào của riêng bạn bằng cách kiểm tra để nhấn phím mỗi khung hình. Sau đó, bạn chỉ có thể tính toán sự khác biệt thời gian giữa các lần lặp. Ví dụ. một quái vật di chuyển 1 khối thứ hai, vì vậy nếu lặp vòng lặp hiện tại mất 100ms thì nó di chuyển 0,1 khối. (lưu các giá trị này dưới dạng float trong nội bộ, ngay cả khi bạn vẽ trên lưới văn bản.

2) Tăng thời gian trò chơi trong 've' dựa trên đầu vào của người dùng. Đây sẽ là kiểu NetHack/Roguelike. Quái vật có thể di chuyển quá nhiều khối trên mỗi lần đánh dấu, thay vì mỗi giây.

+0

Suy nghĩ về phương pháp đánh dấu, nhưng tôi không thể thấy rằng chuyển sang triển khai nhiều người chơi, đó sẽ là một dự án tốt đẹp cho tương lai. Tôi cũng đánh giá cao cách tiếp cận thay thế trong phương án 1, vì đó sẽ là một dự án khai sáng trong chính nó. Tôi có thể sẽ sử dụng chủ đề anyway chỉ để tìm hiểu chúng (mục tiêu ban đầu) và sau đó thực hiện xử lý đầu vào này trong thread đó. – eenblam

1

Có cách nào đó. Bạn sẽ cần phải đặt mã "Đếm vòng" trong Chủ đề của chính nó, vì vậy nó không bị chặn bởi người dùng đang chờ để nhập dữ liệu. Gói java.util.concurrency có thể trợ giúp việc này.

Nhìn vào Java Doc phương thức scheduleAtFixedRate() sẽ thực thi một lần chạy theo khoảng thời gian cố định. Mã "đếm tròn" sẽ được chuyển đến một lớp thực hiện giao diện runnable. Và điều này sẽ được thực hiện tại khoảng thời gian đã đặt. Điều này là hợp lý tiên tiến mặc dù.

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