เนื่องจากบริบทของคำถามของคุณhttp://nodewar.com/มีข้อควรพิจารณาบางประการสำหรับโซลูชันของคุณ:
- คุณมีความเร็วเชิงมุมสูงสุด (ต่ำ) และแรงบิดสูงสุดเพียงพอที่จะไปถึงได้ในเวลาอันสั้น
- เสียงพึมพำและเป้าหมายของคุณแต่ละคนมีความเร็วและความเร่งภายนอกที่ไม่เกี่ยวข้องกับแรงขับ
- เป้าหมายที่คุณต้องการเปลี่ยนแปลงบ่อยครั้งมากที่พยายามตั้งเป้าหมายอย่างสมบูรณ์จะเป็นของเสีย คุณควรพยายามเข้าใกล้และแก้ไขมันทุกเฟรม
วิธีการเหล่านี้เป็นสิ่งที่ฉันตั้งใจจะทำงานเพื่อให้ได้อัตราเร่งที่ต้องการ
การเร่งความเร็วไม่ใช่ความเร็ว
เนื่องจากคุณมีความเร็วที่กำหนดไว้แล้วและเป้าหมายของคุณกำลังเคลื่อนที่คุณจึงไม่ต้องการแรงขับไปยังจุดใดจุดหนึ่ง คุณต้องการแรงผลักดันที่จะเปลี่ยนความเร็วของคุณเป็นสิ่งที่ควรจะเป็น ซึ่งหมายความว่าเรือของคุณต้องไม่ชี้ไปยังที่ที่มันกำลังแล่น แต่ไปในทิศทางที่มันควรเร่ง
// My target velocity is for maintaining a circular orbit.  Yours may differ.
// Earlier, I calculated total gravity and the perpendicular direction.
// You may wish to subtract gravity from your total, rather than match it.
var targetVel = o.lib.vec.times(lateralDir, targetVelMag);
var targetAccel = lv.sum(
  o.lib.vec.diff(targetVel, o.me.vel), 
  o.lib.vec.times(gravity, 1 / o.me.mass)  
);
หมุนไปทางขวา
คุณมีเวกเตอร์ความเร่งตอนนี้คุณต้องการที่จะใช้มัน กำหนดว่าคุณต้องหมุนนานแค่ไหน ฉันอาจใช้ขั้นตอนมากกว่าที่ต้องการในที่นี้ แต่พิกัดการหมุนทำให้ฉันสับสนและฉันคิดว่าค่าการหมุนของเรือที่ไม่ได้เปิดเป็นข้อบกพร่องใน API อยู่ดี
// convert acceleration to an angle
var polar = o.lib.vec.toPolar(targetAccel);
var traj = polar[1];
// constrain the angle to +/-2PI, because the ship's rotation is not limited 
// by default
var fixed_rot = o.lib.ang.rescale(o.me.rot);
// limit the correction to be +/-1PI
var traj_correction = traj - fixed_rot;
if (traj_correction > (Math.PI)){
  traj_correction = (2 * Math.PI) - traj_correction;
} else if (traj_correction < (-1 * Math.PI)){
  traj_correction = (2 * Math.PI) + traj_correction;
}
สูตรง่าย ๆ ไม่มีอันตรายใด ๆ ในการหมุนตลอดเวลาดังนั้นอย่ากังวลกับการใช้ค่าแรงบิดบางส่วน หากคุณต้องการการแก้ไขเล็กน้อยในความเร็วเชิงมุมคุณจะต้องทำการตัดสินใจนี้หลายครั้งต่อวินาที
if (traj_correction > 0){
  torque = 1;
} else if (traj_correction < 0){
  torque = -1;
}
สูตรที่เรียบง่ายน้อยลง จะมีจุดที่คุณไม่ต้องการที่จะเลี้ยวต่อไปเพราะในที่สุดคุณต้องการที่จะหยุด โชคดีที่หมวกความเร็วเชิงมุมหมายความว่าคุณสามารถชะลอความเร็วจากความเร็วเชิงมุมสูงสุดเป็นศูนย์ได้อย่างรวดเร็ว คุณจะต้องคำนวณเมื่อทำเช่นนั้น
var max_a_accel = c.MAX_TORQUE / o.me.m_i;
var a_deccel_time = Math.abs(o.me.a_vel) / max_a_accel;
// the same math as linear acceleration, now in angles.
var stopping_angle = 0.5 * max_a_accel * a_deccel_time * a_deccel_time;
if (stopping_angle >= Math.abs(traj_correction)){
  // slowdown required.  Reverse torque
  torque *= -1;
}
หลังจากปรับแต่งโค้ดด้านบนเพื่อให้เหมาะกับความต้องการของคุณเรือของคุณควรหมุนอย่างรวดเร็วและแม่นยำในทุกมุมที่คุณให้ไว้กับเป้าหมาย
ความเร็วในการชน
ดังนั้นเมื่อจะผลักดัน? อีกครั้งการเปลี่ยนแปลงอย่างรวดเร็วของเป้าหมายและปัจจัยอื่น ๆ สร้างความยากลำบากอย่างมากในการแก้ไขปัญหาที่แน่นอน อย่าพยายาม
// if the heading is close to the final value, thrust.
if (Math.abs(traj_correction ) < 0.02) {  // about 1 degree
  if (true 
      // some logical test, in case you don't want to accelerate past
      // a maximum speed, or some such.  Not required for your stated purpose.
     ){
    thrust = 1;
  } 
}
สำหรับกรณีที่คุณต้องการแรงขับเพียงบางส่วนคุณสามารถพึ่งพาความจริงที่ว่าคุณสามารถเลือกได้ระหว่าง 0 ถึง 1 ครั้งหลายครั้งต่อวินาที สิ่งนี้จะช่วยให้คุณมีแรงขับเพียงบางส่วนโดยไม่เปลี่ยนแปลงค่าจริง
โชคดี!