Более простой способ проверить столкновение?

Я работаю над заданием для университета, где мне нужно создать игру Breakout в Visual Studio 2010 с использованием C# Win Forms. На данный момент я концентрируюсь на том, чтобы разрушить только один кирпич, поэтому у меня есть механика, прежде чем расширять ее.

Чтобы уточнить мою текущую программу: я использую поле изображения в качестве графического объекта и таймер для создания эффекта анимации. Мяч может пропускать в каждом кадре от 1 до 10 пикселей — это часть создания случайного начального вектора для мяча.

Это прекрасно работает до тех пор, пока не нужно проверить, «попал» ли мяч в кирпич, который я нарисовал. У меня есть оператор if, который проверяет, находится ли мяч в любой из координат на поле изображения, которое соответствует контуру кирпича. Я знаю, что с логикой все в порядке, потому что иногда она работает. Однако из-за различий в «прыжках» положения мяча мне нужно добавить буферную область +/- 5 пикселей к моему оператору if.

Вот здесь и возникает проблема, потому что мое if утверждение (на самом деле два) и так действительно сложное:

// Checks if ball hits left side or top of brick
if (((x >= brickX) && (x <= (brickX + 50)) && (y == brickY)) ||
    ((y >= brickY) && (y <= (brickY + 20)) && (x == brickX)))
{
    brickHit = true;
}
// Check if ball hits right side or bottom of brick
else if ((((x >= brickX) && (x <= brickX + 50)) && (y == (brickY + 20))) ||
    (((y >= brickY) && (y <= brickY + 20)) && (x == brickX + 50)))
{
    brickHit = true;
}

Для пояснения: x и y — координаты шара, а кирпич X и кирпич Y — координаты верхнего левого угла прямоугольного кирпича (который имеет ширину 50 пикселей и высоту 10 пикселей).

Есть ли способ упростить приведенные выше операторы if? Если я смогу сделать их проще, я знаю, что будет намного проще добавить в "буфер" (который должен быть только 5 пикселей с каждой стороны контура кирпича», чтобы мяч мог менять положение).

Если нужны дополнительные разъяснения, спрашивайте — я пишу этот вопрос в 5:12 утра, поэтому знаю, что могу быть немного неясным.


person Saladin Akara    schedule 13.11.2010    source источник


Ответы (3)


brickHit = new Rectangle(brickX,brickY,50,20).Contains(x,y);

Добавление буфера:

int buffer = 5;
brickHit = new Rectangle(brickX,brickY,50,20).Inflate(buffer,buffer).Contains(x,y);

Класс Rectagle иногда может пригодиться.

person Lilith River    schedule 13.11.2010
comment
Ооо, мило. Однако вопрос: возвращает ли это значение true/false? - person Saladin Akara; 13.11.2010
comment
@Saladin @Computer Не хочу быть придирчивым, но 1. Inflate возвращает void, вы не можете вызывать .Contains для него. Вам нужно создать прямоугольник, выполнить Inflate как отдельный вызов, а затем вызвать его, а также 2. обратить внимание на Inflate, он только перемещает увеличение размера кирпича вниз и вправо, если вам нужно Буфер +5 слева и сверху, вам нужно сначала сместить прямоугольник, если вам просто нужно пространство слева, справа и снизу, затем Смещение (-5, 0), а затем Раздувание (10, 5) - person pstrjds; 13.11.2010

Один из способов, которым вы могли бы упростить это (и я могу неправильно понять вашу спецификацию), но вы можете сделать прямоугольник из границ кирпича и проверить, содержит ли ваша точка x, y.

Rectangle rec = new Rectangle(brickX, brickY, 50, 20);
rec.Offset(-5, -5);
rec.Inflate(10, 10);
if (rec.Contains(new Point(x,y))
{
    brickHit = true;
}
person pstrjds    schedule 13.11.2010
comment
Это действительно имеет большой смысл. Но когда вы говорите сделать прямоугольник из границ коробки с картинками, имеете ли вы в виду, что кирпич будет того же размера, что и коробка с картинками? - person Saladin Akara; 13.11.2010
comment
Это было бы, если бы вы сделали только Box.Bounds (Bounds возвращает прямоугольник). Если вы хотите, вы можете надуть его, чтобы добавить +5 пикселей, которые вы ищете (надувание добавит количество к прямоугольнику). В вашем случае, если вам нужен буфер +5 вокруг, вам нужно будет переместить расположение прямоугольников (Offset (-5, -5)) и затем Inflate (10, 10). (Вы должны перепроверить математику, так как уже поздно, но я думаю, что это то, что вы ищете). Содержит возвращает логическое значение, указывающее, что указанная точка содержится в прямоугольнике. - person pstrjds; 13.11.2010
comment
Я обновил код в своем ответе на «Смещение и раздувание прямоугольника». Теперь у вас должен получиться прямоугольник, который на +5 больше со всех сторон. - person pstrjds; 13.11.2010
comment
@Саладин только что перечитывал. Я получил границы коробки с картинками, потому что думал, что это кирпич. Я не так тебя поняла. Если поле с изображением не является кирпичом, вам нужно сделать прямоугольник с вашими кирпичами X и Y и размерами, которые вы описали. - person pstrjds; 13.11.2010

Это сработало для меня:

var rect1 = new System.Drawing.Rectangle(pictureBox1.Location,
pictureBox1.Size);
var rect2 = new System.Drawing.Rectangle(pictureBox2.Location, 
pictureBox2.Size);

if (rect1.IntersectsWith(rect2))
{
  //code when collided
}
person Community    schedule 10.11.2017