2013-05-10 22 views
7

Tôi đang ở điểm trong Khách du lịch của mình Tôi đang cố xử lý các cập nhật độc lập với người chơi đối với trạng thái trò chơi. Để tham khảo, dự án là here (nhánh devel là một liên quan cho câu hỏi này).Chức năng Banana Traveler - Sự kiện độc lập về Timer và người chơi

Libraries/Universe/GameState.hs có chức năng, updateGS xử lý tất cả cập nhật trình phát cho trạng thái trò chơi. EventNetwork trông giống như thế này ngay bây giờ.

makeNetworkDescription :: AddHandler PlayerCommand -> 
          AddHandler() -> 
          TChan GameState -> 
          IO EventNetwork 
makeNetworkDescription addCommandEvent tickHandler gsChannel = compile $ do 
    eInput <- fromAddHandler addCommandEvent 
    eTick <- fromAddHandler tickHandler 
    let bGameState = accumB initialGS $ updateGS <$> eInput 
    eGameState <- changes bGameState 
    reactimate $ (\n -> (atomically $ writeTChan gsChannel n)) <$> eGameState 

Vấn đề trong việc thực hiện hẹn giờ này là tất cả các ví dụ tôi đã xem có trường hợp sử dụng khác với mô phỏng vật lý của tôi. Không có vật lý nào tham gia vào trò chơi này. Tôi đang cố gắng sử dụng bộ hẹn giờ để trạng thái trò chơi được đánh giá độc lập với các hành động của người chơi. Bây giờ, điều duy nhất tôi muốn quản lý là du lịch không gian. Khi được triển khai hoàn toàn, di chuyển từ hành tinh này sang hành tinh khác sẽ thay đổi số củathành Right Hyperspace. Những gì cần phải xảy ra bây giờ, là khi một số tick xảy ra, số tiền tăng thêm là distanceTraversed. Sau đó, nếu distanceTraversed bằng địa chỉ totalDistanceAgent của trở thành Left Planet.

Vì vậy, điều đó sẽ trông như thế nào từ quan điểm của EventNetwork?

let bHyperspace = accumB initialGS $ foo <$> eTick 

tại để kết hợp hành vi

let bBaz = (++) <$> bGameState <*> bHyperspace 

Đây có phải là đi đúng hướng?

Trả lời

2

Câu hỏi có phần mơ hồ và không dễ trả lời, nhưng tôi sẽ cố hết sức.

Trước tiên, hãy nhìn vào mã của bạn, tôi thấy thật lạ khi bạn đã "thuê ngoài" logic trò chơi thực tế cho loại GameState nguyên khối và chức năng updateGS. Bây giờ, đây không phải là một điều xấu để làm, nó chỉ là không có lợi ích từ việc sử dụng FRP trong phong cách này. Bạn có thể xóa hoàn toàn chức năng makeNetworkDescription và đăng ký một trình xử lý đồng đều với addCommandEvent bằng tay.

Lợi ích của FRP là bạn có thể lập mô hình trạng thái trò chơi dưới dạng mạng lưới các hành vi và sự kiện. Nếu nhà nước là mô-đun đủ, sau đó điều này sẽ đơn giản hóa mã đáng kể.


Thứ hai, liên quan đến câu hỏi của bạn về cách tạo mô hình du lịch vũ trụ.

Dưới đây là một cách để làm điều đó:

-- indicates whether hyperspace travel is currently happening 
bTravelling :: Behavior t Bool 

-- increment travel distance, but only when travelling 
bTravelDistance :: Behavior t Distance 
bTravelDistance = accumB 0 $ (+1) <$> whenE bTravelling eTick 

-- calculate player location from travel distance 
bPlayerLocation :: Behavior t Location 
bPlayerLocation = 
    (\distance -> if distance > total then Left Planet else Right HyperSpace) 
    <$> bTravelDistance 

Bạn có thể muốn lặp lại quá trình này nhiều lần trong một trò chơi, mặc dù. Thật không may, phản ứng chuối hiện không cung cấp một "đầu tiên làm điều này, sau đó làm điều đó" loại trừu tượng. Có chuyển đổi sự kiện động, nhưng nó có thể hơi khó sử dụng.

+0

Tôi đã nhận ra rằng updateGS sẽ là một vấn đề, nhưng tôi đã lưu câu hỏi đó cho một ngày khác. –