OpenGL中的蠕虫爬行运动
Worm-Crawling Motion in OpenGL?
我正在努力找出一种在OpenGL中执行以下行为的有效方法。
我正在制作一个类似蠕虫的家伙的动画(基本上我想要一个有某种可见眼睛的矩形——没有什么复杂的),它应该通过在前面扩展到两倍的长度,然后从后面缩回到原来的大小来移动。蠕虫到达窗口边缘时会反转方向。
我在调整动作方面有很大的困难,在定位眼睛方面也有一些小困难。如果我简单地画两个多边形,一个接一个地画它们的相对位置,我能指望后者画在前者之上吗?我此刻的运动呈现出一个无限循环,我很难从概念上改变为另一种方法。我无法计算出具有加倍/收缩运动和有效接近终止的环路结构。
下面的当前代码:
#define GLUT_DISABLE_ATEXIT_HACK
#include <GL/glut.h>
#include <GL/gl.h>
float wormX = 0;
float wormY = 0;
float wormWidth = 100;
float wormHeight = 75;
bool wormCrawl = true;
void timer( int value )
{
const int w = glutGet(GLUT_WINDOW_WIDTH);
if( wormX + wormWidth >= w / 2 ) //If worm hits edge, reverse direction!
{
wormX = 2;
}
while( wormCrawl )
{
wormX += 2; //Move the worm
wormWidth = 2*wormWidth; //Extend the front
wormWidth = (1/2)*wormWidth; //Retract the back
}
glutTimerFunc( 16, timer, 0 );
glutPostRedisplay();
}
void display()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
const int w = glutGet(GLUT_WINDOW_WIDTH);
const int h = glutGet(GLUT_WINDOW_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( -w/2, w/2, -h/2, h/2, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
const float leftCorner = wormX;
const float rightCorner = leftCorner + wormWidth;
const float bottomCorner = wormY;
const float topCorner = bottomCorner + wormHeight;
//Worm
glBegin(GL_POLYGON);
glColor3f(0.0, 1.0, 0.0);
glVertex2d(leftCorner, topCorner);
glVertex2d(rightCorner, topCorner);
glVertex2d(rightCorner, bottomCorner);
glVertex2d(leftCorner, bottomCorner);
glEnd();
//Worm eye
glBegin(GL_POLYGON);
glColor3f(0.0, 0.0, 0.0);
glVertex2d(leftCorner, topCorner);
glVertex2d(leftCorner + 10, topCorner);
glVertex2d(leftCorner + 10, bottomCorner);
glVertex2d(leftCorner, bottomCorner);
glEnd();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow ("Inchworm Crawl");
glutDisplayFunc(display);
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 0;
}
因此,首先,我们想让生活变得更轻松,您应该尝试将蠕虫抽象为一个类。我想你可能想在之后继续发展,但无论如何,这仍然是一个很好的做法。这也将使我们的抽签更加容易。
好吧,假设我们现在有了Worm
类,该类将有自己的draw函数,我们希望在主函数中尽可能简单地保持display()
函数中的draw调用。想象一下,如果你想画另一条蠕虫,你将不得不做什么。
所以在你的蠕虫类中,你的draw()
方法看起来像这样:
void Worm::draw()
{
const float leftCorner = wormX;
const float rightCorner = leftCorner + wormWidth;
const float bottomCorner = wormY;
const float topCorner = bottomCorner + wormHeight;
//Worm
glBegin(GL_POLYGON);
glColor3f(0.0, 1.0, 0.0);
glVertex2d(leftCorner, topCorner);
glVertex2d(rightCorner, topCorner);
glVertex2d(rightCorner, bottomCorner);
glVertex2d(leftCorner, bottomCorner);
glEnd();
//Worm eye
glBegin(GL_POLYGON);
glColor3f(0.0, 0.0, 0.0);
glVertex2d(leftCorner, topCorner);
glVertex2d(leftCorner + 10, topCorner);
glVertex2d(leftCorner + 10, bottomCorner);
glVertex2d(leftCorner, bottomCorner);
glEnd();
}
好吧,这只是它的基础,但我仍然没有回答你的实际问题。我不确定你使用的是哪种版本的免费供过于求,但希望你有最新的。一般来说,如果您计划进行的不仅仅是渲染,则应尽量远离glutmainloop();
。它基本上阻止了您在渲染循环之外执行任何逻辑,这实际上意味着程序中的所有内容都将锁定到帧速率。相反,您应该考虑在主函数中编写一个游戏循环,然后每当您想要渲染帧时,它都会调用glutmainloopevent()
。
因此,现在更多的是移动,一旦你创建了游戏循环,从逻辑上讲,你可以把所有的更新功能都放在这里,在循环结束时,你可以调用glutmainloopevent()
,注意这个循环也将是一个半无限循环。当某些标志为真时,它会运行,然后一旦你的蠕虫蠕动足够,你就可以终止它。:P
因此,现在我们可以为蠕虫类添加更多的功能来移动蠕虫并增加其宽度,我们可以将其称为move()
。为了简化事情,我们可以给蠕虫添加一个标志,告诉它是应该缩小还是生长。这只是一个在创建蠕虫对象时初始化为false的布尔值。
void Worm::move(bool direction)
{
if(growing)
{
wormWidth += 1;
if(wormWidth > thresholdWidth)
{
growing = false;
}
}
else
{
wormWidth += 1;
if(wormWidth > thresholdWidth)
{
growing = false;
}
}
if(direction)
{
wormx += 1;
}
else
{
wormx -= 1;
}
}
现在我还没有测试过这个可以,但我想它应该能做一些接近你想要的事情。我目前在我的工作电脑上没有过多的设置,也没有openGL。但如果这并不能完全满足你的需求,请给我一些评论,我下班回家后可以看一看。
最后一件需要注意的事情是,你也会在游戏循环中调用你的移动函数,现在对于你的游戏循环,你可能只需要一个while循环来完成这一操作,但最终你可以将其设置为每秒只更新X次,每秒绘制Y次。
需要注意的一点是,因为你每帧画的东西不超过一个,所以这不会有什么不同。你可以继续绘制你的蠕虫,这就是gLClear()
函数为你所做的,它正在清除当前颜色缓冲区中的所有内容,如果你正忙于明确使用3D的应用程序,你也需要添加深度缓冲区,否则,事情就不会按照正确的顺序绘制,你可能会遇到z战,或者一些事情被背后的东西所吸引。
希望我没有切中要害,这篇文章对你有一定的价值!
祝你好运!
- 粒子系统:所有粒子都朝同一方向运动
- 如何组合许多连续的图像来模拟逼真的运动模糊?
- 太空入侵者 – 2D 矢量运动算法
- 在虚幻引擎中使用运动控制器组件,C++而不是蓝图
- OpenCV的卡尔曼滤波器过渡矩阵如何处理时间(如t和t^2)进行运动预测?
- 如何使用OpenCV作为运动检测器(而不是寻找视频输出)
- 一维阵列的运动检测(神经网络或其他选项?
- 使用带有 PIR 传感器的米利斯检测连续运动
- C++:地下城爬行者 - 更新数组时出现问题
- 在 GTKMM 中捕捉鼠标运动
- C++编译错误是由于使用 std::move 时运动构造函数与其他非运动构造函数之间的冲突
- 在何处更改参考代码以从 HEVC 编码的视频中提取运动矢量
- C++ SFML 精灵运动无法按预期工作
- 编码域中的DCT系数和运动矢量提取
- 视觉C SDL2圆形运动
- setCursor()有时在鼠标快速运动中失败
- 用C++睡眠特定的鼠标运动
- SDL 乒乓球运动错误
- SFML意外的SF ::顶点运动
- OpenGL中的蠕虫爬行运动