/// <summary> /// Метод проверяет столкновение с яблоком /// </summary> /// <returns></returns> private bool IsAte() { if (GameAuxFunctions.VDist(applePosition, playerPosition[0]) < AppleOffs) { return(true); } return(false); }
/// <summary> /// Метод проверяет съедение объекта /// Функция возвращает в качестве X номер элемента для удаления, /// в качестве Y - номер текстуры, от которого зависит количество очков /// </summary> /// <returns></returns> private Vector2 IsAte() { for (int i = 0; i < eatable.Count; i++) { if (GameAuxFunctions.VDist(playerPosition, eatable[i].Position) < (playerAnimation.FrameWidth + eatableTextures[0].Width) / 2 - 20) { return(new Vector2(i, eatable[i].TextureNumber)); } } // Не было съедения return(new Vector2(-1, 0)); }
///////////////////////////////////////////////////////////////////////////////// // ПРОВЕРКА СТОЛКНОВЕНИЙ /// <summary> /// Метод проверяет столкновение данной точки с любой точкой стенок или тела змейки /// </summary> /// <param name="Collaptor">Проверяемая точка</param> /// <param name="WithBody">Проверка столкновения с телом</param> private bool IsCollapted(Vector2 Collaptor, bool WithBody) { // Чтобы не тестировать с каждым обновлением все камни уровня, // имеет смысл проверить только те клетки игры, которые находятся // на минимальном расстоянии от головы. Таких должно быть всего // четыре: на StoneOffs вверх, влево, вправо и вниз. По координатам // таких смещений легко посчитать масштабный индекс массива для // ближайшей позиции и проверить её collision Vector2[] V1 = new Vector2[] { new Vector2(Collaptor.X / Tile.Width + StoneOffs, Collaptor.Y / Tile.Height + StoneOffs), new Vector2(Collaptor.X / Tile.Width + StoneOffs, Collaptor.Y / Tile.Height - StoneOffs), new Vector2(Collaptor.X / Tile.Width - StoneOffs, Collaptor.Y / Tile.Height + StoneOffs), new Vector2(Collaptor.X / Tile.Width - StoneOffs, Collaptor.Y / Tile.Height - StoneOffs) }; // Проверка на столкновение со стенами for (int i = 0; i < V1.Length; i++) { // Вынужденное ограничение индекса (исключение может возникнуть // при генерации нового яблока) if (level.Tiles[(int)V1[i].X % (int)level.LevelSize.X, (int)V1[i].Y % (int)level.LevelSize.Y].Collision == TileCollision.Stone) { collaptedOn.X = (int)V1[i].X * Tile.Width + Tile.Width / 2; collaptedOn.Y = (int)V1[i].Y * Tile.Height + Tile.Width / 2; return(true); } } // Проверка на столкновение с собой (если требуется) if (WithBody) { for (int i = 1; i < playerPosition.Count; i++) { if (GameAuxFunctions.VDist(Collaptor, playerPosition[i]) < BodyOffs) { return(true); } } } // Не было столкновений return(false); }
///////////////////////////////////////////////////////////////////////////////// // ПРОРИСОВКА ИГРОВОГО ПОЛЯ /// <summary> /// Метод отрисовывает информационное поле игры (очки, уровень, состояние) /// </summary> private void DrawInfo() { string S1, S2 = String.Format(" В розыгрыше: {0,4:D} ", currentScore), S3 = String.Format(" Выигрыш: {0,6:D} ", score), S4 = String.Format(" Съедено: {0,5:D} ", ateApples), S5 = String.Format(" Осталось съесть: {0,2:D} ", applesQuantity - currentScore / SMult); if (isWorking) { S1 = String.Format(" УРОВЕНЬ {0,2:D} ", levelNumber + 1); } else { S1 = " ПАУЗА "; } float StrUp = Tile.Height * 0.15f, StrDown = BackBufferHeight - Tile.Height * 0.8f; // Векторы позиций для отображения элементов учитывают смещение камеры наблюдения Vector2 V1 = new Vector2(BackBufferWidth * 0.05f, StrUp) + level.CameraPosition, V2 = new Vector2(BackBufferWidth * 0.21f, StrUp) + level.CameraPosition, V3 = new Vector2(BackBufferWidth * 0.50f, StrUp) + level.CameraPosition, V4 = new Vector2(BackBufferWidth * 0.80f, StrUp) + level.CameraPosition, V5 = new Vector2(BackBufferWidth * 0.05f, StrDown) + level.CameraPosition, V6 = new Vector2(BackBufferWidth * 0.89f, StrDown) + level.CameraPosition, V7 = new Vector2(BackBufferWidth * 0.92f, StrDown) + level.CameraPosition; DrawShadowedString(defFont, S1, V1, SnakeGameColors.LRed); DrawShadowedString(defFont, S2, V2, SnakeGameColors.Yellow); DrawShadowedString(defFont, S3, V3, SnakeGameColors.Green); DrawShadowedString(defFont, S4, V4, SnakeGameColors.LBlue); // Если игра идёт, выводить строку "осталось съесть" if (isAlive) { DrawShadowedString(defFont, S5, V5, SnakeGameColors.Silver); } // Если есть музыка или звук, выводить соответствующий знак if (isMusic) { DrawShadowedString(defFont, "[\x266B]", V6, SnakeGameColors.Yellow); } else { DrawShadowedString(defFont, "[\x266B]", V6, SnakeGameColors.Black); } if (isSound) { DrawShadowedString(defFont, "[\x266A]", V7, SnakeGameColors.Yellow); } else { DrawShadowedString(defFont, "[\x266A]", V7, SnakeGameColors.Black); } // КОМПАС // Смена цвета стрелки компаса Color compasColor = SnakeGameColors.CompasRed; if (GameAuxFunctions.VDist(playerPosition[0], applePosition) < GameAuxFunctions.VDist(compasOffs, applePosition)) { compasColor = SnakeGameColors.CompasGreen; } // Положение стрелки компаса compasOffs = playerPosition[0]; compasPosition.X = (int)playerPosition[0].X; compasPosition.Y = (int)playerPosition[0].Y; Vector2 V8 = applePosition - playerPosition[0]; // Формула движения стрелки компаса и её отображение compasTurn = (float)Math.Acos(V8.X / GameAuxFunctions.VDist(V8, Vector2.Zero)) * GameAuxFunctions.NNSign(V8.Y, true); spriteBatch.Draw(compas, compasPosition, compasSize, compasColor, compasTurn, new Vector2(compas.Width, compas.Height) / 2, SpriteEffects.None, 0.0f); }