前言
在深化对C语言图形编程的探索中,前面文章中实现了一个旋转的三维小球动画。今天,我的创意火花再次被点燃,设想将碰撞检测机制融入这个三维小球项目中,使动画更加生动逼真。更进一步,我希望在小球发生碰撞的瞬间,能够伴随有声音效果,以增强用户的沉浸感。这里使用Windows API中的Beep函数能够实现基本的音频反馈。
期待
可以将这个旋转的小球应用到各种的二维绘图中,实现三维效果。如台球游戏,多球碰撞等。
源码
///////////////////////////////////////////////////
// 程序名称:小球碰撞
// 编译环境:Mictosoft Visual Studio 2022, EasyX_20200315(beta)
// 作 者:luoyh <2864292458@qq.com>
// 最后修改:2024-8-21
// 公 众 号:C语言研究
//
void HideSphere(float R, int alfa, int beta, int HideFlag, int X, int Y);
int main()
{
initgraph(800, 600);
BeginBatchDraw();
// 小球的初始位置与速度
int x = 320, y = 240; // 初始位置
int dx = 2, dy = 2; // 初始速度
// 小球半径
int radius = 200;
int alfa = 45;
int beta = 30;
// 主循环
while (true)
{ // 当没有按键按下时循环
// 绘制小球
HideSphere(radius, alfa, beta, 1, x, y);
// 移动小球
x += dx;
y += dy;
alfa = x;
beta = y;
// 碰撞检测
if (x + radius >= getwidth() || x - radius <= 0)
{
dx = -dx; // 水平方向反弹
Beep(20, 10);
}
if (y + radius >= getheight() || y - radius <= 0)
{
dy = -dy; // 垂直方向反弹
Beep(20, 10);
}
// 延时,减少动画速度
Sleep(1);
FlushBatchDraw();
cleardevice();
}
EndBatchDraw();
_getch();
}
void HideSphere(float R, int alfa, int beta, int HideFlag, int X, int Y)
{
int i, j, k;
float x[4], y[4], z[4], x1[4], y1[4], z1[4], sx[4], sy[4];
double a1, a2, b1, b2, c, d, xn, yn, zn, vn;
c = alfa * PI / 180.0;
d = beta * PI / 180.0;
for (j = 0; j < 180; j = j + 5)
{
a1 = j * PI / 180.0;
a2 = (j + 5) * PI / 180.0;
for (i = 0; i < 360; i = i + 5)
{
b1 = i * PI / 180.0;
b2 = (i + 5) * PI / 180.0;
x[0] = R * sin(a1) * cos(b1); y[0] = R * sin(a1) * sin(b1); z[0] = R * cos(a1);
x[1] = R * sin(a2) * cos(b1); y[1] = R * sin(a2) * sin(b1); z[1] = R * cos(a2);
x[2] = R * sin(a2) * cos(b2); y[2] = R * sin(a2) * sin(b2); z[2] = R * cos(a2);
x[3] = R * sin(a1) * cos(b2); y[3] = R * sin(a1) * sin(b2); z[3] = R * cos(a1);
for (k = 0; k < 4; k++)
{
x1[k] = x[k] * cos(c) - y[k] * sin(c);
y1[k] = x[k] * sin(c) * cos(d) + y[k] * cos(c) * sin(d) + z[k] * sin(d);
z1[k] = -x[k] * sin(c) * sin(d) - y[k] * cos(c) * sin(d) + z[k] * cos(d);
sx[k] = X - x1[k];
sy[k] = Y - z1[k];
}
xn = (y1[2] - y1[0]) * (z1[3] - z1[1]) - (y1[3] - y1[1]) * (z1[2] - z1[0]);
yn = -(x1[2] - x1[0]) * (z1[3] - z1[1]) + (x1[3] - x1[1]) * (z1[2] - z1[0]);
zn = (x1[2] - x1[0]) * (y1[3] - y1[1]) - (x1[3] - x1[1]) * (y1[2] - y1[0]);
vn = sqrt(xn * xn + yn * yn + zn * zn);
xn = xn / vn;
yn = yn / vn;
zn = zn / vn;
if (!HideFlag || yn >= 0.0)
{
moveto(sx[0], sy[0]);
lineto(sx[1], sy[1]);
lineto(sx[2], sy[2]);
lineto(sx[3], sy[3]);
lineto(sx[0], sy[0]);
}
}
}
}
效果