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
  • 相关阅读:
    237. Delete Node in a Linked List
    430. Flatten a Multilevel Doubly Linked List
    707. Design Linked List
    83. Remove Duplicates from Sorted List
    160. Intersection of Two Linked Lists
    426. Convert Binary Search Tree to Sorted Doubly Linked List
    142. Linked List Cycle II
    类之间的关系
    初始化块
    明确类和对象
  • 原文地址:https://www.cnblogs.com/315358525/p/1535805.html
Copyright © 2011-2022 走看看