zoukankan      html  css  js  c++  java
  • [翻译]XNA 3.0 Game Programming Recipes之twentyone

    PS:自己翻译的,转载请著明出处格
                                                  4-4 使用加速控制速度
    问题
        您想使您的模型很好的加速,而不是将从停止到立即全速,反之亦然。图4-9显示了你想要的这种增加速度。
    解决方案
        加入加速速,您可以定义您的模型以多快的速度增加。这是一个数量值的速度你想把它添加到当前模型的每一祯的速度中。
    它是如何工作的
        您将需要掌握你的模型旋转和它的位置 ,因为您需要知道哪个方向是前进方向。在这个例子中,你让模型只围绕Up的y轴旋转,同时只能在X和Z坐标轴上移动他们的位置。见4-7节如果您想模型离开表面,这要完全根据X和Z坐标。
         此外,由于模型的下一个速度基于你当前的速度,你会需要追踪当前的速度。而不是只储存了一些速度,你将存储速度矢量。这包含模型当前准备去的速度矢量的方向,而其长度显示的速度。因此,这三个变量添加到您的类中:
    1 Vector3 modelPosition=new Vector3();
    2 float modelYRot=0;
    3 Vector3 modelVelocity=new Vector3();
        您还可以定义模型的最大加速度和转弯速度:
    1 const float modelMaxAcceleration=30.0f;
    2 const float modelMaxTurnSpeed=0.002f;
        在你的Update方法中,检索的数量秒钟过去直到最后一祯,测试用户想要模型如何移动:
     1 float elapsedSeconds=(float)gameTime.ElapsedGameTime.Miliseconds/1000.0f;
     2 float forwardReq=0;
     3 float angleReq=0;
     4 if(keyState.IsKeyDown(Keys.Up))
     5     forwardReq+=1.0f;
     6 if(keyState.IsKeyDown(Keys.Down))
     7     forwardReq-=1.0f;
     8 if(keyState.IsKeyDown(Keys.Left))
     9     angleReq+=1.0f;
    10 if(keyState.IsKeyDown(Keys.Right))
    11     angleReq-=1.0f;
         forwardReq值将会是正值,如果用户想要模型向前加速。它也可能会是负值如果模型减速或者向后加速。angleReq包含了模型是否应该向左还是向右。
    Acceleration on Ice
        这一段代码添加了加速的基础代码
    1 Matrix rotMatrix=Matrix.CreateRotationY(angle);
    2 Vector3 forwardDir=Vector3.Transform(new Vector3(0,0,-1),rotMatrix);
    3 velocity=velocity+elapsedTime*forwardReq*maxAccel*forwardDir;
    4 modelPosition+=velocity;
    5 modeYRot+=rotationReq*maxRotSpeed*velocity.Length();
          头两行计算当前模型的前进向量,这是需要知道到哪个方向模型的加速度。这个前进向量是靠将默认的(0,0,-1)前进向量围绕Up的y轴旋转得到。
    注意:在此节,模型只能被围绕y轴旋转,所以前进的方向依靠围绕着Up的y轴旋转。见2-3,2-4节,如需有关计算前进向量的全三维或四元轮换参看上述章节。
          第二行代码是计算速度,是最重要的一个。从上一个速度开始,而第二个周期内增加了一个新的载向量基于用户输入。更多的时间已过去了直到最后一祯,更需要调整这个速度。 此外,用户需要较大的加速度,更需要调整速度。作为最后的因素,你采取的最大加速度into account。您乘所有三个因素,给你一个值,表明您是否需要调整你的速度在这一祯中。因为你需要一个Vector3去增加这个速度,你乘这值用forwardDir去获取向量,要添加到此帧中的速度。
    注意 如果没有旋转被应用,velocity和moveDirection都会指出相同的方向,这将导致velocity向量变大,模型速度变快。
         最后,这Vector3添加到您模型的位置 ,和模型的旋转被调整。您的模型移动的越快,它旋转的也越快。
         当您使用此代码,您会发现两个漏洞。首先,您的模型绝不会放慢, 它没有一个最高速度。你想要的速度增加如图4-9 和达到在某一个最高速度。使用此代码,您模型将以同样的速度继续加快。
         其次,如果模型会非常快朝一个方向,在您旋转模型后,它将仍然会朝同一方向。这很不错,如果您模型正在冰面上移动, 但总的来说,这不是你想要的。
    增加摩擦
        在现实生活中,你模型的速度将减少,因为在模型和空中,地面之间都有摩擦,当应用时,内部的机械摩擦。当模型停止加速,摩擦会导致速度下降,直到模型完全停止。 当你继续加速,摩擦将导致速度保持在某一个水平..
        您可以获取摩擦,减少上一个速度在以往的基础上,最重要的是。那个下一行添加摩擦到你的模型中:
    1 velocity=velocity*(1-friction*elapsedTime)+elapsedTime*forwardReq*maxAccel*forwarDir;
        时间越长之间的最后时限和这一祯,摩擦应对你的模型的影响,所以你乘摩擦价值所需的时间。
    Keeping Only the Forward Component
        虽然您的模型将加快用一个更加自然的方法,现在仍然动作有点笨拙当它旋转时(除非您要创建一个空间或冰打滑游戏) 。一般来说,您希望您的模型将只在其前进方向。
        为此,你想知道有多少目前的速度矢量是沿模型的前进后退方向 。这正是一个dot product做的: 它设计的速度(V)向量在前进向量(F)所示,图4-10,并返回投影向量(M)的长度

        在你更新你的速度之后,使用这个代码:
    1 float forwardSpeed=Vector3.Dot(velocity,forwardDir);
    2 velocity=forwardSpeed*forwardDir;
    3 modelPosition+=velocity*elapsedTime;
    4 modelYRot+=rotationReq*maxRotSpeed*forwardSpeed;
           该forwardSpeed变量显示速度向量的前进组成部分的长度。您用前进方向乘以这个值和存储它作为新的速度向量。这样,你确信模型将只沿着它的前进方向移动。
    注意:forwardSpeed变量的一个额外优点是一个正数不管模型是前进还是后退。这对velcotiy.Length()是矛盾的,它总返回一个正值。
    代码
        Accelerate方法列出了模型下一个调整的位置,速度和旋转, 同时加速到一个值。您可能需要添加这些连同最大的加速度和模型结构内的旋转速度。此外,您需要传递用户的输入,以及摩擦价值。
     1 private float Accelerate(ref Vector3 position,ref float angle,ref Vector3 velocity,float forwardReq,float rotationReq,float elapsedTime,float maxAccel,float maxRotSpeed,float friction)
     2 {
     3      Matrix rotMatrix=Matrix.CreateRotationY(angle);
     4      Vector3 forwardDir=Vector3.Transform(new Vector3(0,0,-1),rotMatrix);
     5      velocity=velocity*(1-friction*elapsedTime)+elapsedTime*forwardReq*maxAccel*forwardDir;
     6      float forwardSpeed=Vector3.Dot(velocity,forwardDir);
     7      velocity=forwardSpeed*forwardDir;
     8      modelPosition+=velocity*elapsedTime;
     9      modelYRot+=rotationReq*maxRotSpeed*forwardSpeed;
    10      return forwardSpeed;
    11 }
        该方法返回forwardSpeed变量,这是负数,如果该模型将向后面运动。
    课外阅读
      你可以扩展物体的加速度,用多个加速度影响这个模型,例如重力。为此,您可以总和这些加速度并把这个总和作为forwardDir
  • 相关阅读:
    android touch screen keyboard input移植记录
    共享内存示例代码如下:
    AF
    AF
    etc/fstab的内容是什么意思? 转载
    android 中如何添加新的键值,实现更多功能
    etc/fstab的内容是什么意思? 转载
    IPC框架分析 Binder,Service,Service manager
    共享内存示例代码如下:
    HDU 6125 Free from square (状压DP+分组背包)
  • 原文地址:https://www.cnblogs.com/315358525/p/1535805.html
Copyright © 2011-2022 走看看