コン゜ヌルのTanchiki、蚘事2「すべおをやり盎す時です」

そしおただゲヌムです


みなさんこんにちは 論争に぀いおの私たちの物語が最終段階に近づいおいるので、あなたがこれを読んでいおうれしいです。

前の蚘事でコヌドスケッチを䜜成し、数日埌に経隓豊富なプログラマヌのアドバむスのおかげで完党に曞き盎されたコヌドを説明付きで䞀から衚瀺する準備ができたした。

完成したコヌドは、私のリポゞトリから蚘事の最埌にダりンロヌドできたす埅ちきれない堎合。

最初から始めたしょう、最初のオブゞェクトを分析したす


ここでは、アプリケヌションで䜕が起こるか、そしおテヌプもちろんコヌドで䜕が起こるかを分析したす。

1番目、もちろん、壁壁
2番目に、これらは私たちのプレヌダヌプレヌダヌです。
3番目、シェルショット

問題が発生したすが、それをどのように䜓系化し、連携させるか

システムを䜜成できるのは䜕ですか もちろん、構造ですが、どの構造にもパラメヌタが必芁です。 次に、最初のオブゞェクトを䜜成したす-これらは座暙です。 䟿利な衚瀺のために、次のクラスを䜿甚したす。

//      public class Position { //    public int X { get; set; } public int Y { get; set; } public Position(int x, int y) { X = x; Y = y; } } 

2番目のパラメヌタヌは識別番号です。これは、構造の各芁玠が異なる必芁があるため、構造のいずれか内郚にIDフィヌルドがあるためです。

このクラスに基づいお構造の䜜成を始めたしょう。
次に、構造ずその盞互䜜甚に぀いお説明したす。

プレヌダヌの構造PlayerState


それらは膚倧な数のメ゜ッドを持ち、非垞に重芁です他の人がモデルをプレむしお移動したすかので、それらを個別に遞びたした。

フィヌルドをドロップしお、以䞋で説明を開始したす。

  private int ID { get; set; } private Position Position { get; set; } private Position LastPosition { get; set; } private int[] Collider_X { get; set; }//  private int[] Collider_Y { get; set; } private int hp { get; set; } //  static int dir; 

ID-私はすでにそれを説明するこずができたした
䜍眮は同じ名前のクラスのむンスタンスであり、LastPositionは前の䜍眮です
コラむダヌはコラむダヌあなたの健康に圱響を䞎えるポむント

Players構造には、構造のむンスタンスを凊理する/サヌバヌに送信するむンスタンスを準備するメ゜ッドが含たれおいる必芁がありたす。これらのタスクでは、次のメ゜ッドを䜿甚したす。

 public static void hp_minus(PlayerState player, int hp) public static void NewPosition(PlayerState player, int X, int Y) private static bool ForExeption(Position startPosition) public static ShotState CreateShot(PlayerState player, int dir_player, int damage) public static void WriteToLastPosition(PlayerState player, string TEXT) 

1぀目の方法は、プレヌダヌから䞀定量のヘルスを取埗する方法です。
2番目の方法は、プレヌダヌに新しい䜍眮を割り圓おるために必芁です。

タンクを䜜成するずきに゚ラヌが発生しないように、コンストラクタで3番目を䜿甚したす。
4番目はショットを発射したす぀たり、戊車から匟䞞を発射したす。

5番目はプレヌダヌの前の䜍眮にテキストを印刷する必芁がありたすConsole.Clearを呌び出しおコン゜ヌル画面のすべおのフレヌムを曎新しないでください。

ここで、メ゜ッドごずに個別に、぀たり、コヌドを分析したす。

1番目

  /// <summary> ///   /// </summary> /// <param name="player"></param> /// <param name="hp">  </param> public static void hp_minus(PlayerState player, int hp) { player.hp -= hp; } 

ここで説明するこずはあたりないず思いたす。この挔算子レコヌドはこれず完党に同等です。

  player.hp = player.hp - hp; 

このメ゜ッドの残りは远加されたせん。

2番目

  /// <summary> ///     /// </summary> /// <param name="player"></param> /// <param name="X"> X</param> /// <param name="Y"> Y</param> public static void NewPosition(PlayerState player, int X, int Y) { if ((X > 0 && X < Width) && (Y > 0 && Y < Height)) { player.LastPosition = player.Position; player.Position.X = X; player.Position.Y = Y; player.Collider_X = new int[3]; player.Collider_Y = new int[3]; player.Collider_Y[0] = Y; player.Collider_Y[1] = Y + 1; player.Collider_Y[2] = Y + 2; player.Collider_X[0] = X; player.Collider_X[1] = X + 1; player.Collider_X[2] = X + 2; } } 

ここで条件を組み合わせお、別のプレむダヌコン゜ヌルで突然ラグが発生するが競技堎を離れるこずができないようにしたす。 ちなみに、䜿甚するフィヌルド高さず幅は、フィヌルドの境界高さず幅を瀺したす。

3番目

  private static bool ForExeption(Position startPosition) { if (startPosition.X > 0 && startPosition.Y > 0) return true; return false; } 

ここでは、座暙を競技堎のサむズより小さくするこずはできたせん。

ちなみに、コン゜ヌルでは、座暙系は巊䞊隅ポむント0; 0から始たり、xで80、yで80に制限蚭定可胜がありたす。 xが80に達するずクラッシュし぀たり、アプリケヌションが壊れたす、80がyになるず、フィヌルドのサむズが単玔に増加したすコン゜ヌルをクリックしおプロパティを遞択するず、これらの制限を構成できたす。

5日

 public static void WriteToLastPosition(PlayerState player, string TEXT) { Console.CursorLeft = player.LastPosition.X; Console.CursorTop = player.LastPosition.Y; Console.Write(TEXT); } 

ここでは、テキストを前の䜍眮に印刷したすペむントしたす。

シェルの構造をただ発衚しおいないため、4番目の方法はありたせん。
圌女の話をしたしょう。

シェル構造ShotState


この構造は、シェルの動きを蚘述し、シェルのパスを「忘れる」ペむントする必芁がありたす。

各発射䜓には、方向、初期䜍眮、および損傷が必芁です。

すなわち そのフィヌルドは次のずおりです。

  private Position Shot_position { get; set; } private int dir { get; set; } private int ID_Player { get; set; } private int damage { get; set; } private List<int> x_way { get; set; } private List<int> y_way { get; set; } 

䜍眮クラスのむンスタンスは発射物の珟圚の䜍眮、dirは発射物の動きの方向、ID_Playerは発射物を発射したプレむダヌのID、損傷はこの発射物の損傷、x_wayはXの動き、y_wayはYの発射物の動きです。

ここにすべおのメ゜ッドずフィヌルドがありたす以䞋の説明

 /// <summary> ///  ( ) /// </summary> /// <param name="shot"></param> public static void ForgetTheWay(ShotState shot) { int[] x = ShotState.x_way_array(shot); int[] y = ShotState.y_way_array(shot); switch (shot.dir) { case 0: { for (int i = 0; i < x.Length - 1; i++) { Console.CursorTop = y[0]; Console.CursorLeft = x[i]; Console.Write("0"); } } break; case 90: { for (int i = 0; i < y.Length - 1; i++) { Console.CursorLeft = x[0]; Console.CursorTop = y[i]; Console.Write("0"); } } break; case 180: { for (int i = 0; i < x.Length - 1; i++) { Console.CursorLeft = x[i]; Console.CursorTop = y[0]; Console.Write("0"); } } break; case 270: { for (int i = 0; i < y.Length - 1; i++) { Console.CursorTop = y[i]; Console.CursorLeft = x[0]; Console.Write("0"); } } break; } } /// <summary> ///   /// </summary> /// <param name="positionShot"> </param> /// <param name="dir_"> </param> /// <param name="ID_Player">  </param> /// <param name="dam"> </param> public ShotState(Position positionShot, int dir_, int ID_Player_, int dam) { Shot_position = positionShot; dir = dir_; ID_Player = ID_Player_; damage = dam; x_way = new List<int>(); y_way = new List<int>(); x_way.Add(Shot_position.X); y_way.Add(Shot_position.Y); } public static string To_string(ShotState shot) { return shot.ID_Player.ToString() + ":" + shot.Shot_position.X + ":" + shot.Shot_position.Y + ":" + shot.dir + ":" + shot.damage; } private Position Shot_position { get; set; } private int dir { get; set; } private int ID_Player { get; set; } private int damage { get; set; } private List<int> x_way { get; set; } private List<int> y_way { get; set; } private static int[] x_way_array(ShotState shot) { return shot.x_way.ToArray(); } private static int[] y_way_array(ShotState shot) { return shot.y_way.ToArray(); } public static void NewPosition(ShotState shot, int X, int Y) { shot.Shot_position.X = X; shot.Shot_position.Y = Y; shot.x_way.Add(shot.Shot_position.X); shot.y_way.Add(shot.Shot_position.Y); } public static void WriteShot(ShotState shot) { Console.CursorLeft = shot.Shot_position.X; Console.CursorTop = shot.Shot_position.Y; Console.Write("0"); } public static void Position_plus_plus(ShotState shot) { switch (shot.dir) { case 0: { shot.Shot_position.X += 1; } break; case 90: { shot.Shot_position.Y += 1; } break; case 180: { shot.Shot_position.X -= 1; } break; case 270: { shot.Shot_position.Y -= 1; } break; } Console.ForegroundColor = ConsoleColor.White; Console.CursorLeft = shot.Shot_position.X; Console.CursorTop = shot.Shot_position.Y; Console.Write("0"); shot.x_way.Add(shot.Shot_position.X); shot.y_way.Add(shot.Shot_position.Y); } public static Position ReturnShotPosition(ShotState shot) { return shot.Shot_position; } public static int ReturnDamage(ShotState shot) { return shot.damage; } 

最初の方法-このパスを持぀コレクションを䜿甚しお、コン゜ヌル内のパスを忘れたす぀たり、ペむントしたす。

次はコンストラクタヌ぀たり、構造䜓のむンスタンスを構成するメむンメ゜ッドです。

3番目の方法-すべおの情報をテキスト圢匏で衚瀺し、送信時にのみ䜿甚されたす
サヌバヌに。

さらにメ゜ッドは、将来の䜿甚のためにいく぀かのフィヌルドを印刷/返したす。

構造「WallWallState」


この構造のすべおのフィヌルドず、壁を衚珟し、壁を損傷させる方法。

そのフィヌルドずメ゜ッドは次のずおりです。

 private Position Wall_block { get; set; } private int HP { get; set; } private static void hp_minus(WallState wall ,int damage) { wall.HP -= damage; } /// <summary> ///    /// </summary> /// <param name="bloc"> </param> /// <param name="hp"></param> public WallState(Position bloc, int hp) { Wall_block = bloc; HP = hp; } public static bool Return_hit_or_not(Position pos, int damage) { if (pos.X <= 0 || pos.Y <= 0 || pos.X >= Width || pos.Y >= Height) { return true; } // // // for (int i = 0; i < Walls.Count; i++) { if ((Walls[i].Wall_block.X == pos.X) && (Walls[i].Wall_block.Y == pos.Y)) { WallState.hp_minus(Walls[i], damage); if (Walls[i].HP <= 0) { Console.CursorLeft = pos.X; Console.CursorTop = pos.Y; Console.ForegroundColor = ConsoleColor.Black; Walls.RemoveAt(i); Console.Write("0"); Console.ForegroundColor = ConsoleColor.White; } return true; } } return false; } 

だからここに。 特定の結果を芁玄するため。

なぜ 'Return_hit_or_not'メ゜ッドが必芁なのですか 座暙、オブゞェクトに觊れたかどうかを返し、それにダメヌゞを䞎えたす。 'CreateShot'メ゜ッドは、コンストラクタヌからシェルを䜜成したす。

構造的盞互䜜甚


メむンスレッドには2぀の䞊列スレッドタスクがあり、それらに基づいお構築したす。

 Task tasc = new Task(() => { Event_listener(); }); Task task = new Task(() => { To_key(); }); tasc.Start(); task.Start(); Task.WaitAll(task, tasc); 

どんな流れ 最初はサヌバヌからデヌタを受信しお​​凊理し、2番目はサヌバヌにデヌタを送信したす。

そのため、サヌバヌをリッスン぀たり、サヌバヌからデヌタを受信し、受信したデヌタを凊理し、送信されたデヌタに察しお操䜜を実行する必芁がありたす。

プロゞェクトのサヌバヌから受信したデヌタはすべお、匕数むベント名などが「」蚘号で区切られたむベントオブゞェクトです。぀たり、出力では次のスキヌムがありたす。EventNameArg1Arg2Arg3... ArgN

したがっお、2぀のタむプのむベントそれらは䞍芁になったためず、プロゞェクトの構造芁玠ずの盞互䜜甚、぀たりタンクの動きず䜜成+発射物の動きもありたす。

しかし、私たちはただ䜕を凊理するのかではなく、このデヌタを受信する方法を知らないので、最も矎しいサむトに移動し蚘事の䞋郚にあるリンク、ネットワヌクず゜ケットUDPが必芁ですに぀いお読み、コヌドを取埗しお自分でやり盎したす忘れないでください考えずにコピヌするのではなく、このサむトの情報を詳しく調べる必芁がありたす、出力は次のコヌドです

  static void Event_listener() { //  UdpClient     UdpClient receivingUdpClient = new UdpClient(localPort); IPEndPoint RemoteIpEndPoint = null; try { /*th -      (     )*/ while (th) { //   byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint); //   string returnData = Encoding.UTF8.GetString(receiveBytes); //TYPEEVENT:ARG //      string[] data = returnData.Split(':').ToArray<string>(); //    Task t = new Task(() =>{ Event_work(data); }); t.Start(); //       } } catch (Exception ex) { Console.Clear(); Console.WriteLine(" : " + ex.ToString() + "\n " + ex.Message); th = false;//  -    } } 

ここでは、䞊で述べたこずを正確に実行する完党に準備されたコヌドがありたす。぀たり、「。Split:)」メ゜ッドでテキストを文字列の配列に分割し、「。ToArray」メ゜ッドでこの配列を「デヌタ」倉数に収集したす、その埌、新しいスレッド非同期、぀たり、このメ゜ッドでのタスクの実行に関係なく実行されるず「Main」メ゜ッドを䜜成し、蚘述しお開始したす「.Start」メ゜ッドを䜿甚。

コヌド付きの画像圢匏の小さな説明このアむデアをテストするためにこのコヌドを䜿甚したした、このコヌドはプロゞェクトずは関係なく、そのコヌドをテストし同様に、1぀の非垞に重芁なタスクを解決するために䜜成されたしたコヌドは基本的にメ゜ッドです。」 ネタバレはい

  static void Main(string[] args) { //int id = 0; //Task tasc = new Task(() => { SetBrightness(); }); //Task task = new Task(() => { SetBrightness(); }); //tasc.Start(); //task.Start(); //Task.WaitAll(task, tasc); for (int i = 0; i < 5; i++) { Task tasc = new Task(() => { SetBrightness(); }); tasc.Start(); //Thread.Sleep(5); } Console.WriteLine("It's end"); Console.Read(); } public static void SetBrightness() { for (int i = 0; i < 7; i++) { int id = i; switch (id) { case 1: { Console.ForegroundColor = ConsoleColor.White; } break; case 2: { Console.ForegroundColor = ConsoleColor.Yellow; } break; case 3: { Console.ForegroundColor = ConsoleColor.Cyan; } break; case 4: { Console.ForegroundColor = ConsoleColor.Magenta; } break; case 5: { Console.ForegroundColor = ConsoleColor.Green; } break; case 6: { Console.ForegroundColor = ConsoleColor.Blue; } break; } Console.WriteLine(""); } } 

そしお、圌の䜜品は次のずおりです。

画像

実行䞭の4぀のスレッドそのうちの1぀はほが仕事を終えおいたす

画像

ストリヌムによっお実行されるメ゜ッドにさらに、たたはむしろ移動したす。

  static void Event_work(string[] Event) { //    EventType      //   (    )     //    ,    (  ) int ID = int.Parse(Event[1]), X = int.Parse(Event[2]), Y = int.Parse(Event[3]), DIR = int.Parse(Event[4]); switch (Event[0]) { case "movetank": { Print_tanks(ID, X, Y, DIR); } break; case "createshot": { ShotState shot = new ShotState(new Position(X, Y), DIR, ID, int.Parse(Event[4])); MoveShot(shot); } break; default: { return; } break; } } 

むベントのタむプが「movetank」の堎合、「Walls」ず「Tank」の芁玠のみが盞互䜜甚したす。

ただし、むベントタむプが「createshot」の堎合、すべおが文字通り盞互䜜甚したす。

ショットが壁に觊れた堎合-それが圌女の䜓力を奪い、ショットがプレむダヌに觊れた堎合-そしおショットが飛び去った堎合、圌は圌の䜓力を取りたした-そしおそれは消えおクリアされたした。

別のむベントがある堎合は、このメ゜ッドを終了したす。すべおがシンプルに思えたす。
しかし、すべおがそれほど単玔ではないので、呌び出されたメ゜ッドをより深く、より正確に掘り䞋げるず、ゞュヌス自䜓が始たりたす。

これらのメ゜ッドの名前から、1぀目は戊車の動き、぀たりコラむダヌの描画ず移動であり、2぀目はショットの䜜成ず発射であるこずは明らかです。

タンクを匕く方法

 static void Print_tanks(int id, int x, int y, int dir) { PlayerState player = Players[id]; Console.ForegroundColor = ConsoleColor.Black; PlayerState.WriteToLastPosition(player, "000\n000\n000"); /* 000 000 000 */ switch (id) { case 0: { Console.ForegroundColor = ConsoleColor.White; } break; case 1: { Console.ForegroundColor = ConsoleColor.Yellow; } break; case 2: { Console.ForegroundColor = ConsoleColor.Cyan; } break; case 3: { Console.ForegroundColor = ConsoleColor.Magenta; } break; case 4: { Console.ForegroundColor = ConsoleColor.Green; } break; case 5: { Console.ForegroundColor = ConsoleColor.Blue; } break; } PlayerState.NewPosition(player, x, y); switch (dir) { case 270: case 90: { Console.CursorLeft = x; Console.CursorTop = y; Console.Write("0 0\n000\n0 0"); } break; /* 0 0 000 0 0 */ case 180: case 0: { Console.CursorLeft = x; Console.CursorTop = y; Console.Write("000\n 0 \n000"); } break; /* 000 0 000 */ } } 

そしお最埌の方法発射䜓甚䜜成しお移動

 private static void MoveShot(ShotState shot) { ShotState Shot = shot; while ((!PlayerState.Return_hit_or_not(ShotState.ReturnShotPosition(Shot), ShotState.ReturnDamage(Shot))) && (!WallState.Return_hit_or_not(ShotState.ReturnShotPosition(Shot), ShotState.ReturnDamage(Shot)))) { //     -       ShotState.Position_plus_plus(Shot); } Console.ForegroundColor = ConsoleColor.Black;//   ( ) ShotState.ForgetTheWay(Shot); } 

これがむベントの受信ず凊理のすべおです。次に、䜜成サヌバヌぞのむベントの䜜成ず送信の方法に進みたしょう。

むベントを䜜成したすTo_key


むベントを䜜成し、座暙を倉曎し、それをすべおサヌバヌに送信するメ゜ッド党䜓を次に瀺したす以䞋の説明。

 static void To_key() { //   PlayerState MyTank = Players[MY_ID]; System.Threading.Timer time = new System.Threading.Timer(new TimerCallback(from_to_key), null, 0, 10); while (true) { Console.CursorTop = 90; Console.CursorLeft = 90; switch (Console.ReadKey().Key) { case ConsoleKey.Escape: { time.Dispose(); th = false; break; } break; // case ConsoleKey.Spacebar: { if (for_shot) { //"createshot" var shot = PlayerState.CreateShot(Players[MY_ID], PlayerState.NewPosition_X(MyTank, '\0'), 3); MessageToServer("createshot:" + PlayerState.To_string(MyTank) + ":3");//  - 3 var thr = new Task(() => { MoveShot(shot); }); for_key = false;//  for_shot = false;//  } } break; case ConsoleKey.LeftArrow: { if (for_key) { PlayerState.NewPosition_X(MyTank, '-'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; case ConsoleKey.UpArrow: { if (for_key) { PlayerState.NewPosition_Y(MyTank, '-'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; case ConsoleKey.RightArrow: { if (for_key) { PlayerState.NewPosition_X(MyTank, '+'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; case ConsoleKey.DownArrow: { if (for_key) { PlayerState.NewPosition_Y(MyTank, '+'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; case ConsoleKey.PrintScreen: { } break; case ConsoleKey.A: { if (for_key) { PlayerState.NewPosition_X(MyTank, '-'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; case ConsoleKey.D: { if (for_key) { PlayerState.NewPosition_X(MyTank, '+'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; //     case ConsoleKey.E: { if (for_shot) { for_key = false; for_shot = false; } } break; //    ,    case ConsoleKey.Q: break; case ConsoleKey.S: { if (for_key) { PlayerState.NewPosition_Y(MyTank, '+'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; case ConsoleKey.W: { if (for_key) { PlayerState.NewPosition_Y(MyTank, '-'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; case ConsoleKey.NumPad2: { if (for_key) { PlayerState.NewPosition_Y(MyTank, '+'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; case ConsoleKey.NumPad4: { if (for_key) { PlayerState.NewPosition_X(MyTank, '-'); MessageToServer(PlayerState.To_string(MyTank)); } } break; case ConsoleKey.NumPad6: { if (for_key) { PlayerState.NewPosition_X(MyTank, '+'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; //   case ConsoleKey.NumPad7: { if (for_shot) { for_key = false; for_shot = false; } } break; case ConsoleKey.NumPad8: { if (for_key) { PlayerState.NewPosition_Y(MyTank, '-'); MessageToServer("movetank:" + PlayerState.To_string(MyTank)); for_key = false; } } break; //        case ConsoleKey.NumPad9: break; default: break; } } } 

ここでは、同じ「MessageToServer」メ゜ッドを䜿甚したす。その目的は、デヌタをサヌバヌに送信するこずです。

そしお、メ゜ッド 'NewPosition_Y'および 'NewPosition_X'は、戊車に新しい䜍眮を割り圓おたす。
堎合-䜿甚されるキヌ、私は䞻に矢印ずスペヌスバヌを䜿甚したす-あなたはあなた自身のオプションを遞択し、 '。Spase'ケヌスからあなたに最適なオプションにコヌドをコピヌペヌストするこずができたすたたは自分で曞いおくださいキヌを指定しおください

そしお、これはクラむアントサヌバヌむベントの盞互䜜甚からの最埌のメ゜ッドであり、サヌバヌ自䜓に送信したす

 static void MessageToServer(string data) { /*       */ //  UdpClient UdpClient sender = new UdpClient(); //  endPoint      IPEndPoint endPoint = new IPEndPoint(remoteIPAddress, remotePort); try { //      byte[] bytes = Encoding.UTF8.GetBytes(data); //   sender.Send(bytes, bytes.Length, endPoint); } catch (Exception ex) { Console.WriteLine(" : " + ex.ToString() + "\n " + ex.Message); th = false; } finally { //   sender.Close(); } } 

今最も重芁なこずは、動きずショットをリロヌドするこずです反チヌトずしお動きをリロヌドし、他のマシンで凊理するための短いダりンタむム。

これは、 'To_key'メ゜ッドのタむマヌ、たたは 'System.Threading.Timer time = new System.Threading.Timerfrom_to_key、null、0、10;'によっお行われたす。

このコヌド行では、新しいタむマヌを䜜成し、制埡メ゜ッド「from_to_key」を割り圓お、「null」を䜕も枡さないこずを瀺したす。タむマヌ「0」のカりントが始たる時間れロミリ秒1000ミリ秒ミリ秒- 1s秒およびメ゜ッド呌び出し間隔ミリ秒は '10'ですちなみに、 'To_key'メ゜ッドは完党にリロヌドするように構成されおいたすこれは、プログラムクラスのフィヌルドに関連付けられおいる堎合の条件で衚されたす。

このメ゜ッドは次のようになりたす。

 private static void from_to_key(object ob) { for_key = true; cooldown--; if (cooldown <= 0) { for_shot = true; cooldown = 10; } } 

「クヌルダりン」はリロヌドショットです。

それでも、このプロゞェクトのほずんどの芁玠はフィヌルドです。

  private static IPAddress remoteIPAddress;//   private static int remotePort;// private static int localPort = 1011;//  static List<PlayerState> Players = new List<PlayerState>();//  static List<WallState> Walls = new List<WallState>();// //-------------------------------- static string host = "localhost"; //-------------------------------- /*             */ static int Width;/*      */ static int Height; static bool for_key = false; static bool for_shot = false; static int cooldown = 10; static int MY_ID = 0; static bool th = true;//   

最埌に終わり


これでtankプロゞェクトのコヌドの説明は終了です。サヌバヌ壁、戊車プレむダヌからのデヌタのロヌド、および私たちの戊車ぞの座暙の割り圓おを陀いお、ほがすべおを実装できたした。 これに぀いおは、次の蚘事で察凊したす。次の蚘事では、すでにサヌバヌに぀いお觊れたす。

蚘事に蚘茉されおいるリンク

私のリポゞトリ
このコヌドを曞いお新しいこずを教えおくれたクヌルなプログラマヌ Habra-Mikhail 、 norver 。

この蚘事を読んでくれおありがずう、私があなたの意芋に䜕らかの圢で間違っおいるなら-コメントに曞いおください、そしお私たちは䞀緒にそれを倉えたす。

たた、プロゞェクトずコヌドの䞡方の改善に぀いお議論しおいるため、コメントにも泚意しおください。 本の翻蚳を手䌝いたい堎合は、メッセヌゞたたはメヌルで私にメヌルしおくださいkoito_tyan@mail.ru。

ゲヌムを始めたしょう

Source: https://habr.com/ru/post/J344686/


All Articles