This set of programs were origionaly
meant to be written in java to go with the whole web-based project
theme, but java is too slow, and too unfamiliar... so pick your OS and
download the thing.
|
|
My crowning achevement! The only thing missing is "shocks" to damped
the springs. But this at least demonstrates conservation of mechanical
energy. it won't stop shaking!
|
Download source code and executable: Windows
Linux
In reading the source code, know that this is the only function to be
concerned about understanding. The other functions are only init and
helper functions
void MoveSprites(SDL_Surface *screen, Uint32 background)
{
static int old =
0; <----
static int newx =
1;
<---- new and old frames..
acceleration is based on an instant of a neighboring nodes, x/y
variables
float force;
<--- scalar value of the sum of all the spring
forces for a node
float dx, dy,
d;
<--- sin, cos and hypot
int l;
<--loop counter
int sumx = 0;
<---sum of y forces
int sumy = 0;
<----sum of x forces
int i, nupdates;
SDL_Rect area;
SDL_Rect *dstrect =
NULL; <-- ignore
nupdates = 0;
SDL_FillRect(screen,
dstrect, 0); <-- ignore
/* Move the sprite, bounce
at the wall, and draw */
for ( i=0; i<numsprites;
++i ) {
for(l = 0; l<8 && nodes[i].neigbor[l] != NULL;l++) {
dx = nodes[i].neigbor[l]->x[old] - nodes[i].x[old];
dy = nodes[i].neigbor[l]->y[old] - nodes[i].y[old];
if((dx == 0.0f)&&(dy == 0.0f))
d = 0;
else if (dx == 0.0f) {
d = fabsf(dy);
dy=dy/d;
}
else if (dy == 0.0f) {
d = fabsf(dx);
dx=dx/d;
}
else {
d = sqrt(float(dx*dx)+(dy*dy)); //pythagorean distance
dx /= d;
dy /= d;
}
d -= nodes[i].ne[l]; //get distance relative to equalibrium
force = (200.0*d);
if ( force > 0 )
force -= 10;
// printf(
"positive\n" );
else
force += 10;
// printf(
"negative\n" );
sumx += dx*force; //cos*k*d
sumy += dy*force; //sin*k*d
}
nodes[i].vx += (sumx*time_elapsed) + right * 0.1;
nodes[i].vy += (sumy*time_elapsed) + down * 0.1;
nodes[i].x[newx] = nodes[i].x[old] + (nodes[i].vx*time_elapsed);
nodes[i].y[newx] = nodes[i].y[old] + (nodes[i].vy*time_elapsed);
if (nodes[i].x[newx] < sprite_w/2) {
nodes[i].x[newx] = sprite_w/2;
nodes[i].vx *= 0.0;
// nodes[i].vx = -nodes[i].vx;
}
if (nodes[i].x[newx] > (screen->w - sprite_w/2)) {
nodes[i].x[newx] = screen->w - sprite_w/2;
nodes[i].vx *= 0.0;
// nodes[i].vx = -nodes[i].vx;
}
if (nodes[i].y[newx] < sprite_w/2) {
nodes[i].y[newx] = sprite_w/2;
nodes[i].vy *= 0.0;
// nodes[i].vy = -nodes[i].vy;
}
if (nodes[i].y[newx] > (screen->h - sprite_w/2)) {
nodes[i].y[newx] = screen->h - sprite_w/2;
nodes[i].vy *= -0.0;
// nodes[i].vy = -nodes[i].vy;
}
sumx = 0;
sumy = 0;
}
for ( i=0; i<numsprites;
i+=2 ) {
for(l = 0; l<8 && nodes[i].neigbor[l] != NULL; l++) {
drawline(screen, (int)nodes[i].neigbor[l]->x[newx],
(int)nodes[i].neigbor[l]->y[newx], (int)nodes[i].x[newx],
(int)nodes[i].y[newx]);
}
}
for ( i=0; i<numsprites;
++i ) {
area.x = (int)nodes[i].x[newx] - sprite_w/2;
area.y = (int)nodes[i].y[newx] - sprite_w/2;
SDL_BlitSurface(sprite, NULL, screen, &area);
sprite_rects[nupdates++] = area;
}
i = old;
old = newx;
newx = i;
SDL_UpdateRect(screen, 0, 0,
0, 0);
/* Update the screen! */
if ( (screen->flags &
SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
SDL_Flip(screen);
} else {
SDL_UpdateRects(screen, nupdates, sprite_rects);
}
}