/// <summary> /// Нахождение зоны поражения игрока /// </summary> /// <param name="player">Объект игрока</param> /// <returns></returns> private List<Rectangle> GetShotRadiusRectangles(Player player) { List<Rectangle> shotRadRects = new List<Rectangle>(); shotRadiusRectangles.Add(CellCoords(player.Y, player.X)); //восток for (int i = 1; i <= player.Weapon.Radius; i++) { if (player.X + i < ColumnCount) { shotRadRects.Add(CellCoords(player.Y, player.X + i)); if (tableLayoutPanel.GetControlFromPosition(player.X + i, player.Y) != null)//если попался камень или противник break;//дальше не стреляет } } //запад for (int i = 1; i <= player.Weapon.Radius; i++) { if (player.X - i > -1) { shotRadRects.Add(CellCoords(player.Y, player.X - i)); if (tableLayoutPanel.GetControlFromPosition(player.X - i, player.Y) != null)//если попался камень или противник break;//дальше не стреляет } } //юг for (int i = 1; i <= player.Weapon.Radius; i++) { if (player.Y + i < RowCount) { shotRadRects.Add(CellCoords(player.Y + i, player.X)); if (tableLayoutPanel.GetControlFromPosition(player.X, player.Y + i) != null)//если попался камень или противник break;//дальше не стреляет } } //север for (int i = 1; i <= player.Weapon.Radius; i++) { if (player.Y - i > -1) { shotRadRects.Add(CellCoords(player.Y - i, player.X)); if (tableLayoutPanel.GetControlFromPosition(player.X, player.Y - i) != null)//если попался камень или противник break;//дальше не стреляет } } //юго-восток for (int i = 1; i < player.Weapon.Radius; i++) { if (player.X + i < ColumnCount && player.Y + i < RowCount) { shotRadRects.Add(CellCoords(player.Y + i, player.X + i)); if (tableLayoutPanel.GetControlFromPosition(player.X + i, player.Y + i) != null)//если попался камень или противник break;//дальше не стреляет } } //северо-восток for (int i = 1; i < player.Weapon.Radius; i++) { if (player.X + i < ColumnCount && player.Y - i > -1) { shotRadRects.Add(CellCoords(player.Y - i, player.X + i)); if (tableLayoutPanel.GetControlFromPosition(player.X + i, player.Y - i) != null)//если попался камень или противник break;//дальше не стреляет } } //северо-запад for (int i = 1; i < player.Weapon.Radius; i++) { if (player.X - i > -1 && player.Y - i > -1) { shotRadRects.Add(CellCoords(player.Y - i, player.X - i)); if (tableLayoutPanel.GetControlFromPosition(player.X - i, player.Y - i) != null)//если попался камень или противник break;//дальше не стреляет } } //юго-запад for (int i = 1; i < player.Weapon.Radius; i++) { if (player.X - i > -1 && player.Y + i < RowCount) { shotRadRects.Add(CellCoords(player.Y + i, player.X - i)); if (tableLayoutPanel.GetControlFromPosition(player.X - i, player.Y + i) != null)//если попался камень или противник break;//дальше не стреляет } } return shotRadRects; }
/// <summary> /// Функция хождения игрока /// </summary> /// <param name="pl"></param> public void Turn(Player pl) { pl.NextPosX = user.X - pl.X; pl.NextPosY = user.Y - pl.Y; Coords DP = DamagePos(pl); if(DP.X!=0 && DP.Y!=0)//если атака идёт по диагонали { if(Math.Abs(DP.X)>pl.Weapon.Radius-1) { DP.X = Math.Sign(DP.X) * (pl.Weapon.Radius - 1); DP.Y = Math.Sign(DP.Y) * (pl.Weapon.Radius - 1); } } else//если атака идёт в сторону { if (Math.Abs(DP.X) > pl.Weapon.Radius || Math.Abs(DP.Y) > pl.Weapon.Radius) { DP.X = Math.Sign(DP.X) * pl.Weapon.Radius; DP.Y = Math.Sign(DP.Y) * pl.Weapon.Radius; } } if (DP.X + pl.X == user.X && DP.Y + pl.Y == user.Y)//если пользователь в зоне обстрела и досягаем // && { MessageBox.Show("Вы проиграли! Вас убил игрок "+pl.Name+"."); EndGame(); } else//тогда ходим { bool[,] variousSteps = new bool[3, 3]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { variousSteps[i, j] = true; } } if (pl.X == 19)//если игрок на правой границе { for (int j = 0; j < 3; j++) { variousSteps[2, j] = false; } } else if (pl.X == 0)//если игрок на левой границе { for (int j = 0; j < 3; j++) { variousSteps[0, j] = false; } } if (pl.Y == 19)//если игрок на нижней границе { for (int i = 0; i < 3; i++) { variousSteps[i, 2] = false; } } else if (pl.Y == 0)//если игрок на верхней границе { for (int i = 0; i < 3; i++) { variousSteps[i, 0] = false; } } List<Coords> ableSteps = new List<Coords>(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (variousSteps[i, j]) { Coords C = new Coords(); C.X = i; C.Y = j; ableSteps.Add(C); } } } List<Coords> subAbleSteps = ableSteps.ToList(); foreach (Coords C in subAbleSteps) { if (tableLayoutPanel.GetControlFromPosition(pl.X - 1 + C.X, pl.Y - 1 + C.Y) != null) ableSteps.Remove(C); } Random r = new Random(); int k = r.Next(ableSteps.Count); Coords Coords = new Coords(); //старые координаты игрока Coords.X = pl.X; Coords.Y = pl.Y; //удалить текущего игрока из словаря положений PlayerCoords.Remove(Coords); pl.X = pl.X - 1 + ableSteps[k].X; pl.Y = pl.Y - 1 + ableSteps[k].Y; //новые координаты игрока Coords.X = pl.X; Coords.Y = pl.Y; //добавить текущего игрока с новыми координатами в словарь положений PlayerCoords.Add(Coords, pl); } }
private void btNewGame_Click(object sender, EventArgs e) { tableLayoutPanel.Controls.Clear(); tableLayoutPanel.Visible=false; RowCount = tableLayoutPanel.RowCount; ColumnCount = tableLayoutPanel.ColumnCount; PlayerCoords.Clear(); BarrierCoords.Clear(); players.Clear(); barriers.Clear(); rips.Clear(); userMoveRectangles.Clear(); userShotRectangles.Clear(); shotRadiusRectangles.Clear(); Player Ashe = new Player("Эш", picbAshe); Player Kayle = new Player("Кайла", picbKayle); Player Nidalee = new Player("Нидали", picbNidalee); Player Sivir = new Player("Сивир", picbSivir); Player Vi = new Player("Ви", picbVi); players.Add(Ashe); players.Add(Kayle); players.Add(Nidalee); players.Add(Sivir); players.Add(Vi); Coords C = new Coords(); Random r = new Random(); //Размещение препятствий for (int i = 0; i < 40; i++) { barriers.Add(new Barrier()); barriers[barriers.Count - 1].Picture.BackgroundImage = (Bitmap)picbStone.BackgroundImage.Clone(); barriers[barriers.Count - 1].Picture.BackgroundImageLayout = ImageLayout.Zoom; bool done = false; while (!done) { C.X = r.Next(20); C.Y = r.Next(20); //проверка занятости ячейки if (tableLayoutPanel.GetControlFromPosition(C.X, C.Y) == null) { tableLayoutPanel.Controls.Add(barriers[barriers.Count - 1].Picture, C.X, C.Y); barriers[barriers.Count - 1].X = C.X; barriers[barriers.Count - 1].Y = C.Y; done = true; } } BarrierCoords.Add(C, barriers[barriers.Count - 1]); } //Размещение персонажей foreach (Player pl in players) { bool done = false; while (!done) { C.X = r.Next(20); C.Y = r.Next(20); //проверка занятости ячейки if(tableLayoutPanel.GetControlFromPosition(C.X, C.Y) == null) { tableLayoutPanel.Controls.Add(pl.Picture, C.X, C.Y); pl.X = C.X; pl.Y = C.Y; PlayerCoords.Add(C, pl); done = true; } } } user = new UserPlayer("Удир", picbUdyr, "StoneSword");//создание пользовательского игрока bool[,] ableUserPoses = new bool[20, 20]; for (int i = 0; i < 20; i++) { for (int j = 0; j < 20; j++) { ableUserPoses[i, j] = true; } } foreach(Player pl in players) { List<Rectangle> shotArea = GetShotRadiusRectangles(pl); //простреливаемые места недоступны foreach (Rectangle rect in shotArea) { ableUserPoses[MapX2Cell(rect.X + 2), MapY2Cell(rect.Y + 2)] = false; } pl.Picture.MouseClick += user.MouseClick;//чтобы нажатие на игрока обрабатывалось игроком пользователя } foreach(Barrier barrier in barriers) { ableUserPoses[barrier.X, barrier.Y] = false;//места, заняты барьерами, недоступны barrier.Picture.MouseClick += user.MouseClick;//чтобы нажатие на барьер обрабатывалось игроком пользователя } List<Coords> ablePoses = new List<Coords>();//список непростреливаемых и доступных мест for (int i = 0; i < 20; i++) { for (int j = 0; j < 20; j++) { if (ableUserPoses[i, j]) { C.X = i; C.Y = j; ablePoses.Add(C); } } } int k = r.Next(ablePoses.Count);//выбор случайного из свободных мест user.X = ablePoses[k].X; user.Y = ablePoses[k].Y; tableLayoutPanel.Controls.Add(user.Picture, user.X, user.Y);//размещение пользовательского игрока на поле боя tableLayoutPanel.Visible = true; context = BufferedGraphicsManager.Current; grafx = context.Allocate(tableLayoutPanel.CreateGraphics(), new Rectangle(0, 0, tableLayoutPanel.Width, tableLayoutPanel.Height)); tableLayoutPanel.MouseClick += user.MouseClick; user.mapX = MapX2Cell;//привязка для UserPlayer user.mapY = MapY2Cell; user.isBusy = IsBusy; user.damagePos = DamagePos; user.step = CheckCellUnderStep; user.endStep = AIActions; gameIsRunning = true; }
public Coords DamagePos(Player player) { Coords C = new Coords(); int dx = Math.Sign(player.NextPosX); int dy = Math.Sign(player.NextPosY); int count = Math.Abs(player.NextPosX); if (count == 0) count = Math.Abs(player.NextPosY); for (int i = 1; i < count + 1; i++) { C.X = player.X + dx * i; C.Y = player.Y + dy * i; if (IsBusy(C) || (C.X==user.X && C.Y==user.Y))//если на пути атаки встретился игрок или барьер { break;//выходим из просчёта траектории атаки } } if (count != 0) { C.X -= player.X; C.Y -= player.Y; } return C; }