7
EXPORT int linear_model(igame, timediff, paddle_action)
8
struct gameplay *igame;
10
int (*paddle_action)(const float[2], struct gameball *);
13
if (igame->status != gamestatus_running) return PONG_ARGINVALID;
15
for (int idx= 0; idx <= 1; idx++)
16
igame->ball.pos[idx]+= igame->ball.dir[idx] * timediff;
17
// reflections (in the right order)
18
int condition= PONG_SUCCESS;
19
while (outside(&igame->ball)) {
20
if (outby(igame->ball.pos[0]) * igame->ball.dir[0] > outby(igame->ball.pos[1]) * igame->ball.dir[1]) {
21
// determine where the ball had passed the paddle
22
int border= (igame->ball.pos[0] > .5f);
23
if (fabs(igame->ball.dir[0]) < GAME_NUM_EPS)
26
// try avoiding endless loops caused by paddle implementation issues
27
if (lasttouch == border) return PONG_INTERROR;
30
float crosstime= ( ((float)border) - igame->ball.pos[0] ) /igame->ball.dir[0]; // solve linear equation
31
if (crosstime >GAME_NUM_EPS)
32
return PONG_INTERROR; // back through time
33
if (hit(&igame->pad[border], igame->ball.pos[1] + igame->ball.dir[1] *crosstime)) {
34
// bounce off the paddle
35
float cpos_abs= igame->ball.pos[1] + igame->ball.dir[1] *crosstime;
36
float where[2]= { border, 0.5 }; // x coordinate
38
if (igame->pad[border].size >0) // y coordinate relative to its size
40
- igame->pad[border].mean + igame->pad[border].size/2)
41
/ igame->pad[border].size;
43
if ((condition= paddle_action(where, &igame->ball)) != PONG_SUCCESS)
45
// compute the new ball position after the direction and velocity have been set by paddle_action()
47
for (int idx= 0; idx<= 1; idx++) // forward from the time of collision based on the new motion vector
48
igame->ball.pos[idx]= where[idx] + igame->ball.dir[idx] *(-crosstime);
50
condition= PONG_PADHIT;
54
igame->pad_attr[!border].score++; // <-- the model decides on the scoring system
58
// bounce off the wall
59
int border= (igame->ball.dir[1] > 0);
60
igame->ball.pos[1]= (2.f * (float)border) - igame->ball.pos[1];
61
igame->ball.dir[1]*= (-1.f);
63
// try avoiding endless loops caused by paddle implementation issues
64
if (lasttouch == border+2) return PONG_INTERROR;