2013-05-10 6 views
7

나는 여행자의 시점에 있습니다. 게임 상태에 대한 플레이어 독립적 인 업데이트를 처리하려고합니다. 참고로이 프로젝트는 here입니다 (이 질문에 대해서는 devel 지점이 해당됩니다).기능적인 바나나 여행자 - 타이머와 플레이어에 독립적 인 이벤트

Libraries/Universe/GameState.hs에는 게임 상태에 대한 모든 플레이어 업데이트를 처리하는 기능, updateGS이 있습니다. EventNetwork은 지금이 모양입니다.

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 

이 타이머를 구현 문제는 내가 바라 보았다 모든 예제는 광산, 물리 시뮬레이션 다른 사용 사례를 가지고있다. 이 게임에는 물리학이 없습니다. 게임 상태를 플레이어 동작과 독립적으로 평가하도록 타이머를 사용하려고합니다. 현재로서는 내가 관리하고 싶은 것은 초 공간 여행이다. 한 행성에서 다른 행성으로 완전히 이동하면 Agentlocation에서 Right Hyperspace으로 바뀝니다. 지금 일어날 필요가있는 것은 tick이 발생하면 distanceTraversed이 하나씩 증가합니다. 그런 다음 distanceTraversedtotalDistance과 일치하면 Agent의 위치는 Left Planet이됩니다.

그렇다면 EventNetwork의 관점에서 볼 때 무엇입니까?

let bHyperspace = accumB initialGS $ foo <$> eTick 

지금 행동
let bBaz = (++) <$> bGameState <*> bHyperspace 

이 바른 길인가

을 결합?

답변

2

질문은 다소 모호하고 대답하기 쉽지 않지만 최선을 다할 것입니다.

먼저 코드를 살펴보면, 실제 게임 플레이 로직을 모 놀리 식 GameState 유형과 updateGS 기능으로 "아웃소싱"한다는 것이 이상하다는 것을 알았습니다. 자, 이것은 나쁜 일은 아니며 단지 FRP를이 스타일로 사용하면 아무런 이점이 없다는 것입니다. makeNetworkDescription 기능을 모두 제거하고 addCommandEvent으로 짝수 thandler를 직접 등록 할 수 있습니다.

FRP의 장점은 게임 상태를 행동 및 이벤트 네트워크로 모델링 할 수 있다는 것입니다. 상태가 모듈화되어 있으면 코드를 크게 단순화합니다.


둘째, 초 공간 이동 모델링에 관한 질문.

-- 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 

당신은 아마 게임에서이 과정을 여러 번 반복합니다,하지만 :

여기에 그것을 할 수있는 한 가지 방법입니다. 불행히도, 반응성 바나나는 현재 "먼저 이것을하고 그 다음에는"그런 추상화를 제공하지 않습니다. 동적 이벤트 전환이 있지만 다소 다루기 힘들 수 있습니다.

+0

나는 updateGS가 문제가 될 것이라는 것을 깨달았지만 다른 날은 그 질문을 저축하고있었습니다. –