অ-পূর্ণসংখ্যার গতির মান - এটি করার কোনও পরিষ্কার উপায় আছে কি?


21

পিক্সেল-ভিত্তিক গেমটিতে আমার চরিত্রটি সরিয়ে দেওয়ার জন্য প্রায়শই আমি গতির মান যেমন 2.5 ব্যবহার করতে চাই। যদিও আমি তা করি তবে সাধারণত সংঘর্ষ সনাক্তকরণ আরও বেশি কঠিন হয়ে যায়। সুতরাং আমি এই জাতীয় কিছু করা শেষ:

moveX(2);
if (ticks % 2 == 0) { // or if (moveTime % 2 == 0)
    moveX(1);
}

আমি যতবার লিখতে হয় আমি ভিতরে ভিতরে ক্রিঙ্ক করে থাকি, অ-পূর্ণসংখ্যার গতির মানগুলির সাথে কোনও চরিত্রকে সরিয়ে দেওয়ার কোনও ক্লিনার উপায় আছে বা আমি চিরকালের জন্য এটি আটকে থাকব?


11
আপনি কি নিজের পূর্ণসংখ্যা ইউনিটকে আরও ছোট করে তৈরি করা বিবেচনা করেছেন (উদাহরণস্বরূপ, ডিসপ্লে ইউনিটের 1/10 তম) এর পরে 2.5 অনুবাদ করে 25 তে এবং আপনি এখনও এটিকে সমস্ত চেকের জন্য পূর্ণসংখ্যা হিসাবে বিবেচনা করতে পারেন এবং প্রতিটি ফ্রেমকে ধারাবাহিকভাবে ট্রিট করতে পারেন।
ডিএমগ্রিগরি

6
আপনি ব্রেসেনহ্যাম লাইন অ্যালগরিদম গ্রহণ করার বিষয়ে বিবেচনা করতে পারেন যা কেবলমাত্র পূর্ণসংখ্যা ব্যবহার করে প্রয়োগ করা যেতে পারে।
n0rd

1
এটি সাধারণত পুরানো 8 বিট কনসোলগুলিতে করা হয়। নির্দিষ্ট পয়েন্ট পদ্ধতিগুলির সাথে সাবপিক্সেল চলাচল কীভাবে বাস্তবায়িত হয় তার উদাহরণের জন্য এই জাতীয় নিবন্ধগুলি দেখুন: টাসভিডিয়োস.আর
লুকাস

উত্তর:


13

Bresenham

পুরাতন সময়ে, লোকেরা যখন লাইন এবং চেনাশোনাগুলি আঁকার জন্য তাদের নিজস্ব বেসিক ভিডিও রুটিনগুলি লিখছিল তখন সে জন্য ব্রেসেনহ্যাম লাইন অ্যালগরিদম ব্যবহার করা শোনা যায় নি।

ব্রেনহ্যাম এই সমস্যাটি সমাধান করে: আপনি পর্দার একটি লাইন আঁকতে চান যা dxপিক্সেলগুলি অনুভূমিক দিকের দিকে চালিত করে যখন একই সময়ে dyউল্লম্ব দিকটিতে পিক্সেল বিস্তৃত করতে পারে। লাইনগুলিতে একটি সহজাত "ভাসমান" চরিত্র রয়েছে; আপনার পূর্ণসংখ্য পিক্সেল থাকলেও, আপনি যুক্তিযুক্ত প্রবণতা দিয়ে শেষ করেন।

অ্যালগরিদম যদিও দ্রুত হতে হবে, যার অর্থ এটি কেবল পূর্ণসংখ্যার গাণিতিক ব্যবহার করতে পারে; এবং এটি কোনও গুণ বা বিভাগ ছাড়াই চলে যায়, কেবল সংযোজন এবং বিয়োগফল।

আপনি আপনার ক্ষেত্রে এটি মানিয়ে নিতে পারেন:

  • আপনার "এক্স দিকনির্দেশ" (ব্রেসেনহ্যাম অ্যালগরিদমের নিরিখে) আপনার ঘড়ি।
  • আপনার "y দিকনির্দেশ" হ'ল মানটি যা আপনি বাড়িয়ে তুলতে চান (অর্থাত্ আপনার চরিত্রের অবস্থান - যত্নবান, এটি আসলে আপনার স্প্রাইটের "y" নয় বা স্ক্রিনে যা কিছু আছে, আরও বিমূর্ত মান)

"x / y" এখানে পর্দার অবস্থান নয়, তবে আপনার সময়কালের একটি মাত্রার মান। স্পষ্টতই, যদি আপনার স্প্রিটটি স্ক্রিন জুড়ে একটি স্বেচ্ছাসেবী দিকে চলমান থাকে তবে আপনার একাধিক ব্রেসেনহ্যাম আলাদাভাবে চলবে, 2 ডি এর জন্য 2, 3 ডি 3 এর জন্য।

উদাহরণ

ধরা যাক আপনি নিজের অক্ষরের একটিতে 0 থেকে 25 পর্যন্ত একটি সরল আন্দোলনে আপনার চরিত্রটিকে সরিয়ে নিতে চান। এটি 2.5 গতিতে এগিয়ে চলেছে, এটি ফ্রেম 10 এ পৌঁছাবে।

এটি (0,0) থেকে (10,25) "লাইনের অঙ্কন" সমান। ব্রেকেনহ্যামের লাইন অ্যালগোরিটম ধরুন এবং এটিকে চালিয়ে দিন। আপনি যদি এটি সঠিকভাবে করেন (এবং আপনি যখন এটি অধ্যয়ন করেন তখন খুব তাড়াতাড়ি আপনি এটি কীভাবে করবেন তা স্পষ্ট হয়ে যাবে), তবে এটি আপনার জন্য ("0,0), (1,2), (2,) 11" পয়েন্ট "তৈরি করবে 5), (3,7), (4,10) ... (10,25)।

অভিযোজন উপর ইঙ্গিত

আপনি যদি সেই অ্যালগরিদম গুগল করেন এবং কিছু কোড খুঁজে পান (উইকিপিডিয়ায় এটির উপর একটি বৃহত চুক্তি রয়েছে), আপনার কয়েকটি বিষয় লক্ষ্য রাখতে হবে:

  • এটি স্পষ্টতই সব ধরণের dxএবং জন্য কাজ করে dy। আপনি একটি নির্দিষ্ট ক্ষেত্রে আগ্রহী যদিও (যেমন, আপনার কখনই হবে না dx=0)।
  • স্বাভাবিক প্রয়োগ, পর্দায় অর্ধেই বিভিন্ন ক্ষেত্রে থাকবে কিনা তার উপর নির্ভর করে dxএবং dyইতিবাচক, নেতিবাচক, এবং এছাড়াও কিনা abs(dx)>abs(dy)বা না। আপনি অবশ্যই এখানে যা প্রয়োজন তা চয়ন করুন। আপনাকে বিশেষভাবে নিশ্চিত করতে হবে যে 1প্রতিটি টিক দিয়ে যে দিকটি বাড়িয়েছে তা সর্বদা আপনার "ঘড়ি" দিক is

আপনি যদি এই সরলীকরণ প্রয়োগ করেন তবে ফলাফলটি খুব সহজ হবে এবং কোনও বাস্তব থেকে সম্পূর্ণ মুক্তি পাবে।


1
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। ৮০ এর দশকে সি on৪ তে প্রোগ্রাম করা গেমস এবং 90 এর দশকে পিসির ফ্র্যাক্টালগুলি থাকার পরেও আমি যেখানেই এড়াতে পারি সেখানে ভাসমান পয়েন্ট ব্যবহার করে ক্রাইং করি। বা অবশ্যই, আজকের প্রসেসরের সর্বজনীন এফপিইউগুলির সাথে, পারফরম্যান্স যুক্তিটি বেশিরভাগই মোট, তবে ভাসমান পয়েন্ট গণিতের এখনও অনেক বেশি ট্রানজিস্টর প্রয়োজন, আরও শক্তি আঁকতে, এবং অনেক প্রসেসর ব্যবহার না করার সময় তাদের এফপিইউ পুরোপুরি বন্ধ করে দেবে। সুতরাং ভাসমান পয়েন্ট এড়ানো আপনার মোবাইল ব্যবহারকারীদের এত দ্রুত ব্যাটারি খালি না করার জন্য আপনাকে ধন্যবাদ জানাতে সক্ষম হবে।
গুন্ট্রাম ব্লহম মনিকার

@ গুট্রামব্লহম ফিক্সড পয়েন্ট ব্যবহার করার সময় গ্রহণযোগ্য উত্তর পুরোপুরি ঠিকঠাক কাজ করে, যা আমি মনে করি এটি করা ভাল উপায়। নির্দিষ্ট পয়েন্ট সংখ্যাগুলি সম্পর্কে আপনি কেমন অনুভব করেন?
leetNightshade

এটি 8-বিট এবং 16-বিট দিনের মধ্যে তারা কীভাবে করেছিল তা খুঁজে পাওয়ার পরে গ্রহণযোগ্য উত্তরে এটি পরিবর্তন করে।
সঁচায়ক

26

আপনি যা চান ঠিক তা করার একটি দুর্দান্ত উপায় রয়েছে।

একটি floatবেগ ছাড়াও আপনার একটি দ্বিতীয় floatপরিবর্তনশীল থাকা দরকার যা বাস্তব বেগ এবং বৃত্তাকার বেগের মধ্যে একটি পার্থক্য ধারণ করে এবং জমা করবে । এই পার্থক্যটি তখন বেগের সাথেই মিলিত হয়।

#include <iostream>
#include <cmath>

int main()
{
    int pos = 10; 
    float vel = 0.3, vel_lag = 0;

    for (int i = 0; i < 20; i++)   
    {
        float real_vel = vel + vel_lag;
        int int_vel = std::lround(real_vel);
        vel_lag = real_vel - int_vel;

        std::cout << pos << ' ';
        pos += int_vel;
    }
}

আউটপুট:

10 10 11 11 11 12 12 12 12 13 13 14 14 14 15 15 15 15 15 16


5
আপনি বেগ এবং অবস্থান উভয়ই ভাসমান (বা স্থির অবস্থান) ব্যবহার করে এবং কেবলমাত্র শেষের দিকে পুরো পূর্ণসংখ্যার অবস্থানে গোল করে কেন এই সমাধানটিকে পছন্দ করেন?
কোডসইনচাউস

@ কোডস ইনচাউস আমি এর চেয়ে আমার সমাধানটিকে পছন্দ করি না। আমি যখন এই উত্তরটি লিখছিলাম তখন আমি এটি সম্পর্কে জানতাম না।
হলিব্ল্যাকগ্যাট

16

সংঘর্ষ ও রেন্ডারিংয়ের জন্য চলাচলের জন্য ভাসমান মান এবং পূর্ণসংখ্যার মানগুলি ব্যবহার করুন।

এখানে একটি উদাহরণ:

class Character {
    float position;
public:
    void move(float delta) {
        this->position += delta;
    }
    int getPosition() const {
        return lround(this->position);
    }
};

যখন আপনি সরান আপনি move()ভগ্নাংশের অবস্থান জমে যা ব্যবহার । তবে সংঘর্ষ এবং রেন্ডারিং getPosition()ফাংশনটি ব্যবহার করে অবিচ্ছেদ্য অবস্থানগুলির সাথে ডিল করতে পারে।


নোট করুন যে কোনও নেটওয়র্ক গেমের ক্ষেত্রে ওয়ার্ল্ড সিমুলেশনের জন্য ভাসমান পয়েন্টের ধরণগুলি ব্যবহার করা জটিল হতে পারে। উদাহরণস্বরূপ gafferongames.com/networking- for-game-programmers/… দেখুন ।
লাইওরি

@ লিওরি যদি আপনার একটি স্থির বিন্দু বর্গ থাকে যা ফ্লোটের জন্য ড্রপ-ইন প্রতিস্থাপনের মতো কাজ করে, তবে কি বেশিরভাগ ক্ষেত্রেই এই সমস্যাগুলি সমাধান হয় না?
leetNightshade

@ লিটনাইটশেড: বাস্তবায়নের উপর নির্ভর করে।
লাইওরি

1
আমি বলব সমস্যাটি বাস্তবে অস্তিত্বহীন, আধুনিক নেটওয়ার্ক গেমটি চালাতে সক্ষম এমন কোন হার্ডওয়্যারের আইইইই 754 ফ্লোট নেই ???
সোপেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.