今回やること
- 下の段と重なっていないマスは点灯しないようにする
- 1つも重なっていなければゲームオーバー
完成品はこちら
ellie-app.com
解説
下の段と重なっていないマスは点灯しないようにする
止めたPoint
からy-1
して、stoppedLightPoints
にあるかどうか見たらOK
update
KeyDown keyType -> case keyType of Space -> let isStacked { x, y } = if List.isEmpty model.stoppedLightPoints then True else List.any (\p -> p == { x = x + 1, y = y }) model.stoppedLightPoints stackedPoints = List.filter isStacked model.lightPoints in ( { model | stoppedLightPoints = model.stoppedLightPoints ++ stackedPoints , lightPoints = setStartPoints nextRow 3 } , Cmd.none )
isStacked
で重なっているかどうか判定
最初の行は重なりがないため、停止済みのPoint
があるかどうかを判定するようにした
stackedPoints
で重なっているPoint
のみ保存しstoppedLightPoints
に保存するようにした
1つも重なっていなければゲームオーバー
- ゲームの状態を持つようにする
- 1つも重なっていなければゲームオーバー
- 重なっているマスがあれば継続
- ついでに
Space
でリスタートできるようにする
Model
type GameState = Playing | GameOver
ゲーム進行中とゲームオーバーを状態として持つようにした
これを各パターンマッチに追加していく
→コンパイラが全部教えてくれるので凄い楽だった
subscriptions
subscriptions : Model -> Sub Msg subscriptions model = case model.gameState of GameOver -> Browser.Events.onKeyDown (D.map KeyDown keyDecoder) Playing -> Sub.batch [ Browser.Events.onAnimationFrame Blinking , Browser.Events.onKeyDown (D.map KeyDown keyDecoder) ]
ゲーム進行中ならボックスの点滅とキーイベントの監視
ゲームオーバー状態ならキーイベント(リスタート用)のsubscription
を定義
update
case model.gameState of GameOver -> case msg of KeyDown keyType -> case keyType of Space -> initialModel () Other -> ( model , Cmd.none ) Blinking _ -> ( model , Cmd.none ) Playing ->
GameState
のパターンマッチを追加
GameOver
状態でSpace
を押すと初期状態に戻りリスタート出来るようにした
パターンマッチがネストするのちょっとどうにか出来ないかなーとここで思った
view
view : Model -> Html Msg view model = let rowBaseSplitedBox = splitBox 7 model.boxList in div [] [ div [] (List.map showBoxRow rowBaseSplitedBox) , div [] [ text <| showGameMessage model.gameState ] ] showGameMessage : GameState -> String showGameMessage gameState = case gameState of Playing -> "PRESS 'SPACE' TO STOP BOX" GameOver -> "GAME OVER! PRESS 'SPACE' TO TRY AGAIN"
ゲーム進行中はスペースで止められること
ゲームオーバー時はSPACE
でリスタートできる
をメッセージとして出すようにした
まとめ
- 状態をもたせてパターンマッチして簡単に処理できた
- パターンマッチネストするケースもう少しきれいに書きたい
- 調べたけど速度の変更がイマイチうまく行かなかった
そもそも速度はsubscription
でいいのか?
Process.sleep
を組み合わせてTask
でどうにかするのか?
そもそもラグが生まれるのはupdate
の問題だからではないのか?
→Blinking
とkeyDown
のタイミングの問題
あたりをぐるぐる悩んでた
次回はこのあたりをなんとかクリアしたい