Из истории видеоигр мы знаем, что Pong – это симулятор настольного тенниса: мячик двигается по экрану по линейной траектории и, если он ударяется о периметр игрового поля или об одну из нарисованных ракеток, его траектория изменяется в соответствии с углом столкновения. Эту траекторию, а также само перемещение мяча по этой траектории мы и будем сегодня рассчитывать. Как ни странно, для этого нам понадобятся знания из курса 7 класса средней школы (привет тем, кто считает, что математика нужна только учителям математики).
Траектория в соответствии с углом столкновения может рассчитываться разными способами. Я предлагаю такой: от центра ракетки мяч отражается с очень малым углом; чем дальше от центра, тем больше угол отражения. Если он ударился правее от центра, то и мяч будет отлетать в правую сторону, если левее, то в левую.Рис. 1
Этот принцип будет соблюдаться и для всех стен периметра игрового поля, которое имеет размер 620x460.
Теперь нам нужно вывести формулу, которая будет определять точку, в которую отлетит мяч при соударении. Например, мяч отпрыгивает от координаты [x1=1;y1=-5] (см. рис. 1), угол мы знаем (угол = x1*10). Чтобы получить координату [x2;y2], продолжим линию до пересеченья с осью Oy. Таким образом, мы получим два подобных друг другу треугольника. Нам известен катет и противолежащий угол, найдем длину стороны С1 (см. рис. 2):
C1=x1/tg(угол альфа).
Из свойств подобных треугольников известно, что отношение периметров и длин биссектрис, медиан, высот и серединных перпендикуляров равно коэффициенту подобия, а коэффициент подобия — число k, равное отношению сходственных сторон подобных треугольников. Итак, длина С2=(расстояние от y1 до y2)+C1; коэффициент подобия k=C2/C1. Теперь осталось найти координату x2. Для этого коэффициент подобия k умножим на x1 (свойство подобных треугольников).
Рис. 2
В данном случае координата y2 будет равна 5.Если же мяч оттолкнется от точки x1=3, то y2=5 нам уже не подойдет, и нам нужно будет рассчитать точку соприкосновения с правой стенкой. Также продолжим линию до пересечения с осью Oy, получим два подобных треугольника, у одного из которых мы будем знать катет и противолежащий угол. Нам известно, что стена находится на x=8. Найдем сторону B1 (см. рис. 3): B1=x/tg(угол альфа). Чтобы найти сторону B2, нам нужно узнать во сколько раз она меньше стороны B1. Это легко сделать, найдя отношение точек x/x1. Отсюда B2=B1/(x/x1). Под сторонами A1, B1, C1 подразумеваются полные стороны треугольника, а не до соприкосновения со сторонами A2, B2, C2. Когда эти две стороны треугольников найдены, можем найти координату y2: y2=B1-B2.
Рис. 3
Теперь перейдем к движению мяча по найденной траектории. Нам нужно, чтобы мяч переместился из точки (x1,y1) в точку (x2,y2). Распишем всё сразу на языке программирования С++.
-
double Ball::Move()
-
{ int bool=0;
-
int x,y,a,b;
-
double L,t0,vx,vy;
-
int v=5;//скорость перемещения
-
int t=0;//время
-
// вектор перемещения = (x2-x1,y2-y1);
-
L=sqrt(pow((x2-x1),2)+pow((y2-y1),2));// длина вектора
-
vx=(x2-x1)/L*v;// проекции скорости на x
-
vy=(y2-y1)/L*v;// проекции скорости на y
-
t0=L/v;// время движения по пути
-
while(t<t0){
-
if(t+1>=t0) bool=1;
-
x=x1+vx*t;//вычисляем координаты точки
-
y=y1+vy*t;
-
setcolor(4);//устанавливаем цвет контура мяча
-
setfillstyle(1,4);//метод закраски и цвет мяча
-
fillellipse(x,y,10,10);//координаты мяча и его радиус (если указать, разные
-
// цифры, то получится овал)
-
delay(10);
-
if(bool!=1){// стираем мяч
-
setcolor(getbkcolor());
-
setfillstyle(1,getbkcolor());
-
fillellipse(a,b,15,15);}
-
a=x;b=y;
-
t+=1;}}
На этом пока всё. Как видите, игрострой – это сплошная математика и физика. О программной реализации расчета отражения мяча поговорим в следующей статье. Также в следующих постах я расскажу о том, как добавить ракетки для игроков, компьютера, как компьютер будет отбивать мяч – ведь это всё-таки игра, и компьютер должен поддаваться :-)