-
Notifications
You must be signed in to change notification settings - Fork 1
/
ball.cpp
118 lines (101 loc) · 3.45 KB
/
ball.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "ball.hpp"
#include "racket.hpp"
#include <math.h>
bool Ball::handleRacketCollision(Racket* racket)
{
vector2df racket_size = racket->getSize();
vector2df racket_pos = racket->getPosition();
if ((fabs(racket_pos.X - m_position.X) > racket_size.X / 2.0 + m_radius)
|| (fabs(racket_pos.Y - m_position.Y) > racket_size.Y / 2.0 + m_radius))
{
racket->fail();
return false;
}
vector2df racket_velocity = racket->getVelocity();
m_velocity.X += racket_velocity.X * 0.3;
m_velocity.Y += racket_velocity.Y * 0.3;
m_velocity.Z *= -1;
return true;
}
// ----------------------------------------------------------------------------
bool Ball::handleCollision(Racket* backRacket, Racket* frontRacket)
{
// Right Wall
if (m_position.X + m_radius > m_hmap_size.X)
{
m_velocity.X *= -1;
m_position.X = m_position.X - 2 * (m_position.X + m_radius - m_hmap_size.X);
}
else // Left Wall
if (m_position.X - m_radius < -m_hmap_size.X)
{
m_velocity.X *= -1;
m_position.X = m_position.X + 2 * (fabs(m_position.X) + m_radius - m_hmap_size.X);
}
// Top
if (m_position.Y + m_radius > m_hmap_size.Y)
{
m_velocity.Y *= -1;
m_position.Y = m_position.Y - 2 * (m_position.Y + m_radius - m_hmap_size.Y);
}
else // Floor
if (m_position.Y - m_radius < -m_hmap_size.Y)
{
m_velocity.Y *= -1;
m_position.Y = m_position.Y + 2 * (fabs(m_position.Y) + m_radius - m_hmap_size.Y);
}
// front Wall ~ near lookAt << ai's side >>
if (m_position.Z + m_radius > m_hmap_size.Z)
{
if (!handleRacketCollision(frontRacket))
return false;
m_position.Z = m_position.Z - 2 * (m_position.Z + m_radius - m_hmap_size.Z);
}
else // back Wall ~ near camera << player side >>
if (m_position.Z - m_radius < -m_hmap_size.Z)
{
if (!handleRacketCollision(backRacket))
return false;
m_position.Z = m_position.Z + 2 * (fabs(m_position.Z) + m_radius - m_hmap_size.Z);
}
return true;
}
// ----------------------------------------------------------------------------
Ball::Ball(vector3df pos, double radius, vector3df hmap_size)
{
m_position = pos;
m_radius = radius;
m_hmap_size = hmap_size;
m_velocity = vector3df(0, 0, 0);
}
// ----------------------------------------------------------------------------
/** This function simulate the ball's path, until it reaches the plain defined
* by map_size.Z and dir
* \return <x,y> coordinates of the ball's centerpoint
*/
vector2df Ball::calculatePath(Racket* backRacket,
Racket* frontRacket,
int dir)
{
if (m_velocity.Z * dir <= 0)
return vector2df(0, 0);
Ball* testball = new Ball(m_position, m_radius, m_hmap_size);
testball->setVelocity(m_velocity);
float z;
do
{
testball->animate(1, backRacket, frontRacket);
z = fabs((testball->getPosition()).Z) + m_radius * 1.2;
} while (z < m_hmap_size.Z);
vector2df result = vector2df(testball->getPosition().X,
testball->getPosition().Y);
delete testball;
return result;
} // calculatePath
// ----------------------------------------------------------------------------
bool Ball::animate(int dt, Racket* backRacket, Racket* frontRacket)
{
m_position += m_velocity * dt;
if (!handleCollision(backRacket, frontRacket)) return false;
return true;
}