Отслеживание столкновения змеи и фрукта
Отслеживание момента поедания змеей фрукта осуществляется в функции Timer_Tick, где проверяется совпадение позиции головы змеи с позицией фрукта, хранящейся в поле FoodPosition (функция PlaceFood отвечает за размещение фрукта). Условие проверки выглядит так:
if (NewHeadPosition == FoodPosition)
{
// Змея съела фрукт
}
Действия после поедания фрукта
При совпадении позиций выполняются следующие действия:
- Создание нового фрукта: вызов функции PlaceFood для отображения фрукта в новой случайной позиции.
- Увеличение змейки: вызов функции EatFood.
Функция EatFood
Функция EatFood не принимает и не возвращает значений. В ней выполняются следующие действия:
- Создание нового сегмента: создание объекта Rectangle (назовем его NewSnake) с помощью функции CreateSnakeSegment. Позиция нового квадрата устанавливается равной FoodPosition.
- Отображение нового сегмента: добавление NewSnake в GameCanvas с помощью GameCanvas.Children.Add(NewSnake).
// ... в функции EatFood ...
Rectangle NewSnake = new Rectangle();
CreateSnakeSegment(NewSnake, FoodPosition);
GameCanvas.Children.Add(NewSnake);
// ...
На этом этапе новый квадрат появляется, но остается статичным. Для его движения вместе со змеей, необходимо объединить все сегменты змеи в один список.
Список сегментов змеи и его использование
Создадим список Snake типа List<Rectangle> для хранения всех сегментов змеи:
private List<Rectangle> Snake = new List<Rectangle>();
При создании головы змеи (SnakeHead) добавим её в список Snake:
Snake.Add(SnakeHead);
В функции EatFood также добавим новый сегмент в список Snake:
Snake.Add(NewSnake);
Движение змеи
Для синхронного движения всех сегментов, список Snake перебирается в обратном порядке. В цикле для каждого элемента устанавливается позиция, равная позиции предыдущего элемента:
for (int i = Snake.Count - 1; i > 0; i--)
{
Snake[i].SetValue(Canvas.LeftProperty, Snake[i - 1].GetValue(Canvas.LeftProperty));
Snake[i].SetValue(Canvas.TopProperty, Snake[i - 1].GetValue(Canvas.TopProperty));
}
Это обеспечивает движение всех сегментов за головой.
Удаление фрукта
Для удаления фрукта после поедания используется функция Remove из GameCanvas.Children:
GameCanvas.Children.Remove(GameCanvas.Children.OfType<Image>().FirstOrDefault());
Теперь игра включает поедание фруктов и увеличение длины змеи. Сложность можно повысить, уменьшив размер окна или уменьшив интервал таймера, что увеличит скорость игры. В дальнейшем можно добавить механизм проигрыша.