เนื่องจากบริบทของคำถามของคุณ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 ครั้งหลายครั้งต่อวินาที สิ่งนี้จะช่วยให้คุณมีแรงขับเพียงบางส่วนโดยไม่เปลี่ยนแปลงค่าจริง
โชคดี!