[翻译]XNA 3.0 Game Programming Recipes之twenty-one
生活随笔
收集整理的這篇文章主要介紹了
[翻译]XNA 3.0 Game Programming Recipes之twenty-one
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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 。
????????????????????????????????????????????? 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 。
轉載于:https://www.cnblogs.com/315358525/archive/2009/07/31/1535805.html
總結
以上是生活随笔為你收集整理的[翻译]XNA 3.0 Game Programming Recipes之twenty-one的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一步步教你如何用疯狂.NET架构中的通用
- 下一篇: 改……