一个模拟橡皮筋的程序。
struct Vector
{
float x, y;
void operator += (Vector v) { x += v.x; y += v.y; }
void operator -= (Vector v) { x -= v.x; y -= v.y; }
void operator *= (Vector v) { x *= v.x; y *= v.y; }
Vector operator + (Vector v) { Vector t; t.x = x + v.x; t.y = y + v.y; return t; }
Vector operator - (Vector v) { Vector t; t.x = x - v.x; t.y = y - v.y; return t; }
Vector operator * (Vector v) { Vector t; t.x = x * v.x; t.y = y * v.y; return t; }
};
struct Node
{
Vector p; // 坐标
Vector v; // 速度
} node1[NODES], node2[NODES], *p1 = &node1[0], *p2 = &node2[0];
void Init()
{
Node n = { {320, 240}, {0} };
for (int i = 0; i < NODES; i++)
{
node1[i] = node2[i] = n;
}
}
void Update(int mx, int my)
{
p1[0].p.x = (float)mx;
p1[0].p.y = (float)my;
p2[0] = p1[0];
static Vector g = { 0, GRAVITY }; // 重力
static Vector sa = { 0.01f, 0.01f };
static Vector sv = { 0.99f, 0.99f };
Vector a;
for (int i = 1; i < NODES - 1; i++)
{
a = (p1[i - 1].p - p1[i].p) + (p1[i + 1].p - p1[i].p) + g;
a *= sa;
p2[i].v = p1[i].v + a;
p2[i].v *= sv;
p2[i].p = p1[i].p + p2[i].v;
}
a = (p1[NODES - 2].p - p1[NODES - 1].p) + g;
a *= sa;
p2[NODES - 1].v = p1[NODES - 1].v + a;
p2[NODES - 1].v *= sv;
p2[NODES - 1].p = p1[NODES - 1].p + p2[NODES - 1].v;
Node* t = p1; p1 = p2; p2 = t;
}
void Render()
{
moveto((int)p1[0].p.x, (int)p1[0].p.y);
for (int i = 1; i < NODES; i++)
{
lineto((int)p1[i].p.x, (int)p1[i].p.y);
}
}
void DrawFPS()
{
static DWORD fps = 0;
static DWORD t = GetTickCount();
static TCHAR str[64];
if (++fps >= 100)
{
DWORD tt = GetTickCount();
_stprintf(str, _T("FPS: %d"), 100 * 1000 / (tt - t));
t = tt;
fps = 0;
}
outtextxy(0, 0, str);
}
void main()
{
initgraph(640, 600);
BeginBatchDraw();
setlinestyle(PS_SOLID, 3);
// 设置初始位置和速度
Init();
MOUSEMSG m = GetMouseMsg();
while (!_kbhit() || _getch() != 27) // 按ESC退出
{
while (MouseHit()) m = GetMouseMsg();
for (int i = 0; i < ITER; i++) Update(m.x, m.y);
cleardevice();
Render();
DrawFPS();
FlushBatchDraw();
Sleep(10);
}
EndBatchDraw();
closegraph();
}
结果: