মোটামুটি ভাল গাড়ী চলন তৈরি করা এতটা কঠিন নয় (তবে এই পোস্টটি বেশ দীর্ঘ হবে)। শারীরিকভাবে গাড়ী চলাচল করতে গাড়ি চালানোর জন্য আপনাকে বেশ কয়েকটি মৌলিক বাহিনী "অনুকরণ" করতে হবে।
(সমস্ত কোডের নমুনাগুলি সিউডোকোড)
ত্বরণ
প্রথমত, আপনার স্পষ্টতই ত্বরণ প্রয়োজন। নিম্নলিখিত লাইনের মতো সাধারণ কিছু করতে হবে:
acceleration_vector = forward_vector * acceleration_input * acceleration_factor
forward_vector
- একটি ভেক্টর গাড়ির একই দিক নির্দেশ করছে।
acceleration_input
- ইনপুটটি বিরতিতে থাকতে হবে [-1, 1]।
acceleration_factor
- ত্বরণের মান (পিক্সেল / সেকেন্ড ^ 2, বা আপনার ইউনিট যাই হোক না কেন)।
চালনা
স্টিয়ারিং মোটামুটি সহজ। বস্তুত, কি করবে হয় ঘোরাতে গাড়ী এটা অন্য কিছু দিক নির্দেশ লাভ করার উদ্দেশ্যে সম্মুখে ভেক্টর।
steer_angle = steer_input * steer_factor
new_forward_vector = rotate_around_axis(forward_vector, up_vector, steer_angle)
তবে, আপনি এখানে কোনও জটিলতার মুখোমুখি হতে পারেন। যদি আপনার ইনপুটটি কোনও কীবোর্ডের মাধ্যমে হয় তবে এর মান হয় -1 বা 1 হবে যার অর্থ আপনার গাড়ি তাত্ক্ষণিকভাবে চালু হবে। আপনি খুব সাধারণ লিনিয়ার ইন্টারপোলেশন (লারপিং) ব্যবহার করে এটি ঠিক করতে পারেন:
amount = time_since_last_frame * steer_lerp_factor
forward_vector = lerp(forward_vector, new_forward_vector, amount)
পরিমাণটি সময়ের উপর নির্ভর করে যেমন আপনার চলাচল আপনার ফ্রেমের হারের উপর নির্ভর করে না। পরিমাণটি [0, 1] এর মধ্যে হওয়া উচিত এবং এটি যত কম হবে, পুরানো এবং নতুন ভেক্টরগুলির মধ্যে মসৃণ স্থানান্তরটি হবে।
(এই মুহুর্তে আপনি যে গাড়ী বাহা হবে এমনকি যদি এটি এখনও স্থায়ী হয় পাবেন। যে প্রতিরোধ করার জন্য, সংখ্যাবৃদ্ধি steer_angle
দ্বারা current_speed / max_speed
, যেখানে max_speed
একটি ধ্রুবক আপনি দ্বারা সংজ্ঞায়িত।)
চলন্ত
এখন আমরা ত্বরণটি প্রয়োগ করব এবং এর গতিবেগ, ত্বরণ এবং স্টিয়ারিংয়ের উপর ভিত্তি করে গাড়িটিকে একটি নির্দিষ্ট সংখ্যক পিক্সেল স্থানান্তর করব। আমরা গাড়ীর গতি এমন সীমাবদ্ধ করতে চাই যা এটি অতুলনীয় দ্রুত গতিতে শেষ না হয়।
current_speed = velocity_vector.norm()
if (current_speed < max_speed)
{
velocity_vector += acceleration_vector * time_since_last_frame
}
position_vector += velocity_vector * time_since_last_frame
আপনার গাড়ী এখন স্লাইড হয়
যদি আমি ঠিক বলে থাকি তবে আপনি যখনই বরফের মতো ঘুরছেন তখন আপনার গাড়িটি এখন স্লাইডিংয়ের মতো প্রদর্শিত হবে। কারণ কোন ঘর্ষণ নেই। একটি আসল গাড়িতে সেখানে একটি উচ্চতর পার্শ্বীয় ঘর্ষণ (চাকার কারণে ঘুরতে পারছে না: পি)।
পার্শ্বীয় বেগ কমাতে হবে। এটি সম্পূর্ণরূপে হ্রাস না করে আপনি গাড়িটি প্রবাহিত হওয়ার মতো করে তুলতে পারেন।
lateral_velocity = right_vector * dot(velocity_vector, right_vector)
lateral_friction = -lateral_velocity * lateral_friction_factor
যেহেতু আমরা ঘর্ষণ সম্পর্কে কথা বলছি, আপনিও একটি বল (ঘর্ষণের) রাখতে চাইতে পারেন যা আপনার বেগকে হ্রাস করে যে আপনি যখন ত্বরণ বন্ধ করে দিবেন, আপনার গাড়িটি অবশেষে থামবে।
backwards_friction = -velocity_vector * backwards_friction_factor
গাড়িটি চালনার জন্য আপনার কোডটি এখন দেখতে এইরকম হওয়া উচিত:
// Friction should be calculated before you apply the acceleration
lateral_velocity = right_vector * dot(velocity_vector, right_vector)
lateral_friction = -lateral_velocity * lateral_friction_factor
backwards_friction = -velocity_vector * backwards_friction_factor
velocity_vector += (backwards_friction + lateral_friction) * time_since_last_frame
current_speed = velocity_vector.norm()
if (current_speed < max_speed)
{
velocity_vector += acceleration_vector * time_since_last_frame
}
position_vector += velocity_vector * time_since_last_frame
নোট বন্ধ হচ্ছে
আমি উল্লেখ করেছি যে আপনি স্টিয়ারিংয়ে কীভাবে লার্পিং প্রয়োগ করবেন; আমি মনে করি ত্বরণের জন্য এবং সম্ভবত স্টিয়ার এঙ্গলের জন্য আপনার একই জিনিসটি করার প্রয়োজন হতে পারে (আপনাকে পূর্বের ফ্রেম থেকে তাদের মানগুলি সংরক্ষণ করতে হবে এবং এটি থেকে lerp করতে হবে)। এছাড়াও গাড়ীর সাথে সম্পর্কিত সমস্ত ভেক্টরগুলির (এগিয়ে, ডান, উপরে) দৈর্ঘ্য 1 হওয়া উচিত।
এছাড়াও, ঘর্ষণ আমি এখানে দেখানো থেকে কিছুটা জটিল। আপনার সর্বদা এটি নিশ্চিত করা উচিত যে গাড়িটি থামিয়ে দেওয়ার জন্য প্রয়োজনীয় ত্বরণের চেয়ে এর দৈর্ঘ্য আর কখনও বেশি নয় (অন্যথায় ঘর্ষণটি গাড়ীটিকে বিপরীত পথে সরিয়ে তুলবে)। সুতরাং আপনার মতো কিছু হওয়া উচিত:
dt = time_since_last_frame
backwards_friction.resize(min(backwards_friction.norm(), velocity_vector.norm() / dt))
lateral_friction.resize(min(lateral_friction.norm(), lateral_velocity.norm() / dt))