これまではカードを出すと出したプレイヤーのカードが1枚減り、中央に表示されていたカードが変化しました。今回はプレーヤーによって出されたカードが中央へむかって流れるように移動します。そのため誰がカードを出したのかがわかりやすいです。

ではどのようにすればいいのでしょうか?

フォーム上をカードが流れるように移動させるには?

まず出されたカードが表示されるPanelを作成します。これを移動させます。

ただループ文をつくって座標を変えていく方法ではすぐに終わってしまうのでカードが流れるように移動してみえません。そこでループ文のなかに

を入れます。

これでカードが流れるように中央にむかって移動してみえるようになります。

デザイナを使って新しいPanelを追加します。新しく追加されたパネルの名前はpanelPutCardとします。

CardExクラス

移動するためにはそのカードがどこから出てきたかを知る必要があります。

今回はカードにそのカードはどこから出てきたのかを知る変数を持たせることにしました。

しかしCardクラスを変更することはできません。自作のライブラリだから変更してもいいのだが・・・

ライブラリはそのままにしたいので、ここではこれを継承してCardExというクラスを作成します。

CardExクラスをつくった以上は生成するカードもCardExクラスからつくることになります。ただし格納先はこれまでと同じです。

次にカードを出すときにそのプレーヤーが出したことがわかるようにフィールド変数に代入します。

どのカードを出すのかを決めるメソッドはPlayerクラスのPutCardメソッドでした。戻り値をCardからCardExに変更しています。

CenterCardプロパティを変更する

それから出されたカードが移動する場所は中央なので、CenterCardプロパティに手を入れれば簡単にすみそうです。

ところで・・・

Taskを極めろ!async/await完全攻略 – Qiita

要点を引用すると

TaskをWaitしてはいけないと聞いたことはありますね?
理由はもちろんデッドロック。ちょっとWaitを呼んでみるだけで、予想よりもずっと簡単にデッドロックを発生させることができてしまいます。

しかし!対策はあります!

特定のスレッドに戻りたくても戻れないために発生するデッドロックならば、「特定のスレッドに戻らなくても良い」ようにすればいいのではないでしょうか。そのためのメソッドが、ConfigureAwait(false)です。

await後に戻る先のスレッドを指定しないようにできます。そうすれば、続きの実行は適当な空いているスレッドに割り当てられ、上のようなデッドロックが発生することはなくなります。

長くなってしまいましたが、ConfigureAwait(false)があれば問題ないということです。なのでTaskをWaitすることにします。ConfigureAwait(false)をつけないとどうなるか実験してみたら動かなくなってしまった。

自分のカードを出したときの処理

自分がカードを出すときはカードに自分が出したことがわかるようにフィールド変数に値をいれておく必要があります。