如何创建将某个实体移动到某个位置的方向向量

问题描述

一般说明:

我正在构建这个游戏,我必须根据旋转面向的位置将某个球移动到一个位置,基本上 背景中有一堆块和一些障碍物,并且实现了碰撞检测算法,因此球在碰撞时会返回其原始位置

问题:

我需要用一个方向向量移动球,但我不知道怎么做,我一直按住空格键移动,但我想要它,所以它在点击空格键时自行移动 带有一个方向向量

目标:

再一次,我希望它在单击空格键时使用方向向量自行移动。碰撞时,我想让球反射到相反的角度,想象一下你把一个球扔到一堵墙上,然后它跑到另一堵墙上,然后最终停下来,这怎么可能?

代码

void collisionDetection(Entity* ball,Entity* block)
{
    //Collision detection function
    //Radius
    const float blockRadius = 5.0f;
    const float ballRadius = 2.0f;

        //block coords
        float xBlock = block.GetX;
        float yBlock = block.GetY;
        float zBlock = block.GetZ;

        //ball coords
        float xBall,yBall,zBall;
        xBall = ball.GetX;
        yBall = ball.GetY;
        zBall = ball.GetZ;

        //max boundaries + radius
        float xMax,yMax,zMax;
        xMax = xBall + blockRadius + ballRadius;
        yMax = yBall + blockRadius + ballRadius;
        zMax = zBall + blockRadius + ballRadius;

        //min boundaries - radius
        float xMin,yMin,zMin;
        xMin = xBall - blockRadius - ballRadius;
        yMin = yBall - blockRadius - ballRadius;
        zMin = zBall - blockRadius - ballRadius;


        //main process
if ((xBlock > xMin && xBlock < xMax) && (yBlock > yMin && yBlock < yMax) && (zBlock > zMin && zBlock < zMax))
        {
            ball.SetPosition(0,2,0);
        }
    }

void main()
{
//Blocks
std::vector<Entity*> blocks; //Declaring a vector for the blocks
float xPosition = -55; //Initial position of the wall of blocks

//For loop that automatically renders the blocks & puts them in place with proper distance between them
    for (int i = 0; i < 10; i++)
    {
        blocks.push_back(blockEntity.Spawn(xPosition,5,120));
        xPosition += 12; //incrementing the value of x so the blocks generate with proper distance between them
    }

ballEntity.Spawn(0,0);

if(Key_(Space).isHeld)
{
ball.MoveZ(0.3f);
}

//Detecting the collision
for (Entity* block : blocks)
        {
                collisionDetection(ball,block);
        }
}

解决方法

也许是牛顿方程? 该实体具有速度、加速度(y 方向为 -9.81 m/s^2)。确定方程后,您可以计算速度的各个分量(x、y 和 z)并相应地更新每个分量(简单的三角计算)。

单击空格键后,您只需应用加速并更新值即可。您需要不断更新被调用以匹配 FPS 的 Draw()/Update() 函数中的值。 因此,您需要一个 main 循环,它在一秒钟内多次调用 Draw() 或 Update() 函数。通用模板可以是 -

while(true) {
  // run at 120FPS,per cycle budget ~8.3ms
  long long start_time = getCurrentTimeNano();
  ReadInput();
  Update();
  DetectCollisions();
  Draw();
  long long budget_used = getCurrentTimeNano() - start_time;
  sleep(clamp(8300000LL - budget_used,0LL,8300000LL));
}

在检测到碰撞并获得发生碰撞的球体上的点后,您可以计算一个垂直于该点的法向矢量,面朝外。现在您可以申请执行相同的操作(计算单个组件并不断更新)。

更好的方法是拥有一个模型矩阵,其中包含实体的平移、旋转信息,将这些坐标映射到相机视图(1,-1 之间)的视图矩阵,最后是投影矩阵(正交/透视)。

如果您想更好地理解数学,可以查看this link

,

假设球的位置将由一个 2D 向量表示,表示为 P。

P = [P1,P2]

要在 2D 平面中移动这个 P,您需要一种推动或力或任何改变您的矢量位置并产生一个新矢量作为位置的东西:

P#1 = P#0 + Vchange

P#1:T=1 时的位置; P#0:T=0 时的位置。

现在

    // imagine your ball started with certain position
    if(Key_(Space).isClicked)
    {
       while(condition) { // condition for your game to keep running
          // Start 
          ball.Move(vector(...)) // vector of change
          for (Entity* block : blocks)
          {
                if (collisionDetection(ball,block))
                {
                   ball.Move(vector(...)) // vector of opposite direction to flee the collision
                }
          } 
       }
    }

更多灵感: