2

選択時にボタンを強調表示したい(水色の背景)。そのために、次のコードを書きました。

players : Input Int
players = input 1

playerSelection : Element
playerSelection = flow right [ 
      color (buttonPressed 1) (button players.handle 1 "Solo")
    , color (buttonPressed 2) (button players.handle 2 "2P")
    , color (buttonPressed 3) (button players.handle 3 "3P")
    , color (buttonPressed 4) (button players.handle 4 "4P")
    ]

buttonPressed : Int -> Color
buttonPressed p = if players.signal == p then lightBlue else white

これをコードの残りの部分で実行すると、次のエラー メッセージが表示されます。

   if | players.signal == p -> lightBlue
      | True -> white

  Expected Type: Int
    Actual Type: Signal.Signal Int

問題は、players.signal が Signal Int であることです。これを通常の数値に置き換えると、プログラムは正常に動作します。ただし、ボタンを選択すると水色になり、別のボタンを選択すると再び白くなるボタンが必要です。比較目的で信号を通常の整数に変換する方法はありますか? 外部比較メソッドを作成してそのメソッドにシグナルを持ち上げようとしましたが、このメソッドの結果は使用できないシグナルブールになります。私がしたことを説明するには:

buttonPressed : Int -> Color
buttonPressed p = if equals p <~ players.signal then lightBlue else white

equals : Int -> Int -> Bool
equals a b = a == b

アップデート

信号を呼び出し元の関数に「より高く」移動しようとしましたが、問題は残っています。すべてのコードを表示することもできます (それほど多くはありません。最初にこれを実行する必要がありました)。

heartbeat = every (second/50)

data Player = One | Two | Three | Four

-- STARTING SCREEN
players : Input Int
players = input 1

beginState : Int -> Element
beginState ps = collage 600 600 [
      move (0,270) (toForm (playerSelection ps))
    ]

playerSelection : Int -> Element
playerSelection ps = flow right [
      color (buttonPressed 1 ps) (button players.handle 1 "Solo")
    , color (buttonPressed 2 ps) (button players.handle 2 "2P")
    , color (buttonPressed 3 ps) (button players.handle 3 "3P")
    , color (buttonPressed 4 ps) (button players.handle 4 "4P")
    ]

buttonPressed : Int -> Int -> Color
buttonPressed p ps = if p == ps then lightBlue else white

playState : Element
playState = draw

draw : Element
draw = collage 1024 768 [
      filled black (rect 1024 768)
    ]

endState : String -> Element
endState p = plainText (show p ++ " has won!")

startGame : Signal Element
startGame = foldp (\_ _ -> draw) (beginState <~ players.signal) Keyboard.space

main : Signal Element
main = startGame

私の最終目標が最初に何であるかを説明します。ゲームは開始画面 (beginState) で開始されます。この画面で、プレイヤーは以下をカスタマイズできます:
- ニックネーム (文字列を返すテキストフィールド)
- コントロール (wasd、矢印キー、方向のためにユーザーが定義した任意のキー)
- プレイヤーの数

スペースバーを入力すると、ゲームが開始され、これらのパラメーターは変更できなくなります。これはstartGameで確認できます。実際のゲームがどのように機能するかは、このトピックとはほとんど関係ありませんが、開始画面からのカスタマイズされたオプションがゲームの仕組みに転送されることを期待していることを知っておくことは重要です. したがって、プレーヤーごとの特定のアクションの入力キーは、コントロール テキスト フィールドで選択された文字と一致する必要があります。選択したプレイヤーの数によって、ゲーム内で作成されるオブジェクトが決まります。このゲームの playState は、現在 holder に置き換えられていdrawます。

問題について: Int の代わりに Signal Int を取得するため
、呼び出しによってプレイヤーの数を単純に要求できないことをゆっくりと学習しています。これは、たとえば を呼び出して、挿入する char を取得players.signalできないことを意味します(Char の代わりに Signal Char を取得するため)。問題は基本的に、他のプログラミング言語で変数を使用する場合と同様に、シグナルからの情報をどのように保存して渡すかということです。controls.signalKeyboard.directions

このコードに取り組めば取り組むほど、シグナルの仕組みを理解していないことに気づきます。あなたの例(Apanatshka)では、Signal Intの代わりにIntを引数として期待するplayerSelectionにシグナルを持ち上げているのがわかります。これを適用しようとすると (この更新セクションのコードを参照)、次のエラーが発生します。

Type error on line 76, column 35 to 63:
       beginState <~ players.signal

  Expected Type: Signal.Signal Graphics.Element.Element
    Actual Type: Graphics.Element.Element

何が間違っている可能性があるのか​​ 、一般的な考えがわかりました。1 つの関数から 2 つのシグナルが送信されていますが、1 つのみを想定しています。正直なところ、beginState のように、シグナルがより適切な位置に伝播されるのを見たいと思います。

beginState : Element
beginState = collage 600 600 [
      move (0,270) (toForm (playerSelection <~ players.signal))
    ]

しかし、toForm は Element の代わりに Signal Element 引数を取得するため、再び問題が生じます。players.signal技術的には信号をメインに配置することもできますが、ゲームが開始されて信号が Int パラメータとして渡されると不要になるため、非常に悪い予感がします。

私が達成したいことが明確であることを願っています。そして、私の問題を簡単に要約すると
: - 信号からの情報をどのように保存して渡すのですか? players.signal

4

1 に答える 1