コンソールのTanchiki、記事1:「議論からコードの記述まで」

おそらくあなたは少しバックグラウンドから始める必要があります:私は何らかの形でペアに座っていたので、コンソールで最も簡単な戦車(Dendivsky戦車のような)を作成する可能性について同級生と議論することにしましたが、ネットワークでプレイします。



私たちはまだコンピューターネットワークを持っていなかったので、自分ですべてをゼロから学ばなければなりませんでした。 おそらく、選択したテキストの30ページを読んで、このトピックに関する4つの講義を聞いた後、私は非常に退屈してこれをさらに聞くのが面倒になり、最終的にプロジェクトを開始しました。



さて、準備はいいですか? さあ始めましょう!



この記事は短くなりますが、参考になります(私のような初心者向け)。



執筆の時点で、私は少数の言語しか知らず、それぞれの言語の選択と、これらの同じ戦車の開発にどの程度適しているかについて話し合っていました。 しかし、知識に基づいて、私はこのようなすべてを配布することにしました:



C#-クライアント(学習する最も簡単な言語として)

Rust-サーバー(最も安全で高速なサーバー)

PHP / html / css / javascript-サイト(これは可能です)



パート1:問題の説明



ポイントを証明するために私がしなければならなかった主なことは単純な戦車でしたが、私は普遍的なクライアントを作ることにしました。 どう? -これは、サーバーがWinFormとコンソールの両方に対して等しく最適化されている場合です(Winformで優れた戦車が必要なため)。



そのため、タスクは次のとおりです。3つのアプリケーションを開発する必要があります。1つ目はWinForm(標準Windowsウィンドウ)、2つ目はコンソール(ダンディーエミュレータ)、3つ目はサーバー自体です。



パート2:アイデアと欠陥...



良いアプリケーションは何をする必要がありますか? -設計中にこの質問をしたところ、頭の中に「早く」という答えがありました。



これはどういう意味ですか? -データの受信/送信の複数のストリームで作業する必要があるという事実。 シェルはタンクが引かれるまで待つことができず、タンクは壁が移動するまで引かれることができません。



FPSが低下したり、何かをレンダリングする時間がなかったり、それらがあなたを殺したとき、それがいかに不快かを知っています。 そのような状況はすべきではありません!



考えて、私はそれらをこの方法で配布することにしました:



1番目のストリーム(メイン)-押されたキーをサーバーに送信する必要があります。

2番目のストリームは、タンクの座標を取る必要があります。

3番目の壁座標。

シェルの4番目の座標。



また、ゲーム中にタンカーがコミュニケーションをとるためのチャットルームを作成することも望まれました(突然別の部屋に移動します)が、これはまだ実装されていません。



ストリームには少し特異性があります。最初は単純な送信者(つまり、最小限の計算を整理してサーバーに送信)でなければならず、残りは常にアプリケーション内のすべてを受け入れて描画する必要があります。 コードの形式では、すべてが次のようになります。



static async void Tank_coordinate() { //   await Task.Run( () => { }); } static async void Coordinate_wall() { //   await Task.Run( () => { }); } static async void Shot() { //   await Task.Run( () => { /*  :     ,     */ }); } static void To_key() { //   }
      
      





このすべての後、データをサーバーに送信するためのデータを整理するためのいくつかのオプションがあり、その後、講義が始まりました。 選択は素晴らしかったです:Intov / String変数ですべてを整理し、それらを通して描画するか、データの構造を作成します。 リンクを台無しにしたくありませんでした。 フォーラムで1時間のグーグル検索を行った後、2番目のフォーラムで解決しました。構造の形でデータを整理するはるかに簡単であり、ドキュメントの作成がより便利になるからですコードを読んで変数を探します)。 私たちの新しいタスクは、フィールドが押されたキー、プレイヤーの座標、戦車の回転角、そして(コンソールの場合)-最後のキャラクターの位置と、できれば何らかのレンダリングコントロールを担当する構造を作成することです。 なぜ最後が必要なのですか? -連携する座標を使用しないように(増加/減少/サーバーに送信)



間違いは何でしたか? -あなたは私に尋ねます。



最初は、httpモデルのジャングルに登り始めました(httpでやりたいと思っていました)が、一定時間後、tcpで行う方が良いことがわかりました(より少ない問題とラストに対処する方が簡単です)。



フローとアイデアを決めました。次に何をしますか?



そして、友人、それは最も興味深いでしょう。



パート3:構造とメソッドの作成Main()。 開発フェーズ1の終了



せっかちな読者がすぐにコピーして貼り付けられるように、すぐにコードをスローします。



 //    //       /// <summary> ///  ( ) /// </summary> public struct player_coor { public static void new_player_coor (int x_, int y_, string dir_, ConsoleKey key_, int last_x_, int last_y_) { x = x_; y = y_; dir = dir_; key = key_; last_x = last_x_; last_y = last_y_; } static int x = 2;//  static int y = 2;// static string dir;//  static ConsoleKey key;//  static int last_x;// static int last_y;// 'y'  'x' } static void Main(string[] args) { }
      
      





しかし、これは最も便利なコードではありません;最良のオプションが提案されています: norver



次のようになります。



 //      public class Position { //    public int X { get; set; } public int Y { get; set; } public Position(int x, int y) { X = x; Y = y; } } //   ,  "player_coor" public struct PlayerState { //         //  ,     //      /// <summary> ///   /// </summary> /// <param name="startPosition"> </param> /// <param name="dir_">   ()</param> /// <param name="key_"> </param> /// <param name="lastPosition">  </param> public PlayerState(Position startPosition, int dir_, ConsoleKey key_, Position lastPosition) { StartPosition = startPosition; LastPosition = lastPosition; dir = dir_; key = key_; } private Position StartPosition { get; set; } private Position LastPosition { get; set; } //  static int dir; //  static ConsoleKey key; } static void Main(string[] args) { //    Position,   2, 2 var startPosition = new Position(2, 2); //    Position,   5, 10 var currentPosition = new Position(5, 10); //    PlayerState var currentState = new PlayerState(startPosition, int, ConsoleKey.UpArrow, currentPosition); //          Position Console.WriteLine("X={0}, Y={1}", startPosition.X, startPosition.Y); }
      
      







ちょっとした発言:この記事の続きを書いている間、数値変数をテキスト変数よりも格納する方がはるかに簡単であることがわかりました。そのため、dir変数(つまり、位置)に整数値を格納します。



これは最も単純なコードですが、素晴らしい仕事をします。将来のアプリケーションをストリーミングします。



スレッドの小さな説明:スレッドはSystem.Threadingスペースを介して作成されます。 クラスのインスタンスと同じ方法で作成しますが、stream引数でvoid関数を指定します。

ストリームを作成した後、.Start()メソッドで開始し、.Abort()メソッドで無効化(例外をスロー)できますが、これは同期モデルです(つまり、ナイフとフォークで食べますが、フォークで取るまでカットできません)。非同期(私たちは食べて掃除機をかけ、同時に足で+100500のアプローチでベンチプレスを行います)。



そこで、最初の「擬似コード」とプロジェクトの主要なポイント/アイデアを書きました。 最初の段階は終わり、私たちの無知は終わりました。そして機能を開発し、汗をかかなければなりません。



どうもありがとうございました:



lairunsafePtrvlreshetdomix32vadimturkovmyxonorverの記事のアイデアと編集。



あなたの願いやアイデアを待って、力があなたと一緒に来ます!



All Articles