, который определяет действия программы в зависимости от нажатой клавиши. Батон хлеба движется с той же скоростью, что и кусочек сыра. На этой стадии при запуске программы пользователь может перемещать батон хлеба по всему экрану, в то время как кусочек сыра по-прежнему самостоятельно двигается по экрану.
Обнаружение столкновений
Для контроля
столкновений в играх используются прямоугольные области. Конечно, здесь далеко до реализма, так как предметы не всегда имеют прямоугольную форму. Но в некоторых случаях пользователь может и не заметить этого. Ограничивающий прямоугольник вокруг изображения хлеба выглядит так, как показано на рис. 11.4.
Рис. 11.4. Ограничивающий прямоугольник для объекта
Две точки позволяют оперировать координатами верхнего левого и нижнего правого углов прямоугольника. В .NET Compact Framework существует структура
RECTANGLE
, использующая эти координаты для реализации прямоугольника. Несколько методов используют эту структуру для обнаружения пересечения двух прямоугольников. С их помощью и можно обнаружить столкновение объектов. Ранее использовавшиеся переменные надо заменить структурой
RECTANGLE
, в которой будет содержаться информация о местонахождении объекта. Соответствующий код приведен в листинге 11.17.
Листинг 11.17
/// <summary>
/// Позиция и ограничивающий прямоугольник для сыра
/// </summary>
private Rectangle cheeseRectangle;
/// <summary>
/// Позиция и ограничивающий прямоугольник для батона хлеба
/// </summary>
private Rectangle breadRectangle;
Сразу после загрузки изображений надо ввести код, приведенный в листинге 11.18.
Листинг 11.18
// Получим координаты и ограничивающие прямоугольники
cheeseRectangle = new Rectangle(0, 0, cheeseImage.Width.cheeseImage.Height);
breadRectangle = new Rectangle(0, 0, breadImage.Width, breadImage.Height);
Теперь для вывода картинок на экран надо использовать в методе
этих прямоугольников можно перемещать объекты по экрану. В методе
updatePosition
надо заменить часть кода, отвечающую за движение сыра и батона, с учетом созданных переменных, как показано в листинге 11.20.
Листинг 11.20
private void updatePositions {
// Движение кусочка сыра
if (goingRight) {
cheeseRectangle.X += xSpeed;
} else {
cheeseRectangle.X -= xSpeed;
}
if ((cheeseRectangle.X + cheeseImage.Width) >= this.Width) {
goingRight = false;
}
if (cheeseRectangle.X <= 0) {
goingRight = true;
}
if (goingDown) {
cheeseRectangle.Y += ySpeed;
} else {
cheeseRectangle.Y -= ySpeed;
}
if ((cheeseRectangle.Y + cheeseImage.Height) >= this.Height) {
goingDown = false;
}
if (cheeseRectangle.Y <= 0) {
goingDown = true;
}
//
Управление батоном
if (keyArgs != null) {
switch (keyArgs.KeyCode) {
case Keys.Up:
breadRectangle.Y -= ySpeed;
break;
case Keys.Down:
breadRectangle.Y += ySpeed;
break;
case Keys.Left:
breadRectangle.X -= xSpeed;
break;
case Keys.Right:
breadRectangle.X += xSpeed;
break;
}
}
/// и далее...
Когда сыр ударяется о батон хлеба, он должен отскочить. Этого эффекта можно добиться, просто изменив направления движения по оси Y в методе
updatePosition
, как показано в листинге 11.21.
Листинг 11.21
// Проверка на столкновение
if (cheeseRectangle.IntersectsWith(breadRectangle)) {
goingDown = !goingDown;
}
Метод
IntersectsWith
принимает параметры прямоугольников. Если они пересекаются, то возвращается значение
True
, после чего меняется направление движения сыра.
Запустите программу и попытайтесь отбить батоном движущийся кусочек сыра. Вы увидите, как сыр отскочит после столкновения.
Столкновения батона и мяча
Хотя код вполне нормально работает, все-таки хочется больше реализма. Отвлечемся на минутку и рассмотрим пример столкновений мячей с круглым предметом (рис. 11.5).
Рис. 11.5. Столкновение круглых объектов
Когда мяч ударяется о круглый объект, он отскакивает обратно, как показано на рисунке. Программа должна уметь определять вид столкновения для каждого мяча. По схожему принципу должна работать и наша программа.
На рис. 11.6 показаны использующиеся три вида столкновений. Первое столкновение происходит при наезде правой нижней части сыра на прямоугольник батона. Во втором случае оба нижних угла изображения сыра одновременно пересекаются с прямоугольником батона. И третий случай реализуется, когда изображение сыра левой частью попадает на блокирующий прямоугольник.
Рис. 11.6. Виды столкновений
Нужно снова переписать код метода
updatePosition
для новой реализации модели столкновений, как показано в листинге 11.22.