Игра "Воллейбол" на GTK

Воллейбол

Задача: создать игру "Воллейбол", смоделировать законы физики, действующие на мяч и игроков
Использованный API: GTK/GDK
Среда разработки: XCode(MacOS X), Code::Blocks(Linux & Windows)
Компилятор: GCC v4

Главной задачей в игре "Воллейбол" является определение пересечений мяча с игроками и сеткой, а также моделирование полета мяча и удара.

Пересечение окружности с прямой определяется достаточно просто: необходимо определить расстояние от центра окружности до прямой. Если оно меньше радиуса - прямая и окружность пересеклись.

Пересечение окружности с окружностью находится аналогично. Если расстояние между центрами меньше суммы радиусов - окружности пересеклись.

Во время пересечения игрока и шара необходимо определить новую скорость объектов. Это делается так:

a) Найти X_Axis
 
X_Axis = | (center2 - center1) |;
 
b) Найти проекции
 
U1x= X_Axis * (DotProduct(X_Axis, U1))
U1y= U1 - U1x
U2x =-X_Axis * (DotProduct(-X_Axis, U2))
U2y =U2 - U2x
 
c) Найти новые скорости
 
     (U1x * M1)+(U2x*M2)-(U1x-U2x)*M2
V1x= --------------------------------
               M1+M2
     (U1x * M1)+(U2x*M2)-(U2x-U1x)*M1
V2x= --------------------------------
               M1+M2
 
Где M1 и M2 - массы объектов.
 
d) Найти окончательные скорости
 
V1y=U1y
V2y=U2y
V1=V1x+V1y
V2=V2x+V2y

Моя функция, занимающаяся вычислением новых скоростей

void NewSpeed(circle_object *first, circle_object *second) {
	vector xaxis,U1x,U1y,U2x,U2y,V1x,V1y,V2x,V2y;
	float a, b;
	xaxis = VectorNorm(VectorSubs(second->position, first->position));
	a = DotProduct(xaxis, first->action.speed);
	U1x = VectorMulScalar(xaxis, a);
	U1y = VectorSubs(first->action.speed, U1x);
	xaxis = VectorNorm(VectorSubs(first->position, second->position));
	b = DotProduct(xaxis, second->action.speed);
	U2x = VectorMulScalar(xaxis, b);
	U2y = VectorSubs(second->action.speed, U2x);
	V1x = VectorMulScalar(VectorSubs(VectorSum(VectorMulScalar(U1x, first->action.weight), VectorMulScalar(U2x, second->action.weight)), VectorMulScalar(VectorSubs(U1x, U2x), second->action.weight)), 1/(first->action.weight + second->action.weight));
	V2x = VectorMulScalar(VectorSubs(VectorSum(VectorMulScalar(U1x, first->action.weight), VectorMulScalar(U2x, second->action.weight)), VectorMulScalar(VectorSubs(U2x, U1x), first->action.weight)), 1/(first->action.weight + second->action.weight));
	V1y = U1y;
	V2y = U2y;
	first->action.speed = VectorSum(V1x, V1y);
	second->action.speed = VectorSum(V2x, V2y);
}

Движение основано на движении под действием гравитации. Для этого используется уравнение Эйлера.

Speed_New = Speed_Old + Acceleration*TimeStep
Position_New = Position_Old + Speed_New*TimeStep

Вид данного уравнения в коде

prms->ball.action.speed = VectorSum(prms->ball.action.speed, prms->ball.action.acceleration);
prms->ball.position = VectorSum(prms->ball.position, prms->ball.action.speed);

Ключевые слова: 
Воллейбол, столкновения, движение
ВложениеРазмер
Volley.zip1.04 Мб