ইচ্ছাকৃত অসম্পূর্ণতার সাথে বিপরীতমুখী / এনইএস স্টাইল পদার্থবিজ্ঞান পুনরুদ্ধার করা


16

পটভূমি:

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

মাধ্যাকর্ষণটি প্লেয়ারের ওয়াই গতিতে 0.25 / ফ্রেমের হারে যুক্ত হয়।

খেলোয়াড় যখন লাফ দেয়, তখন তার ওয়াই গতি -4.64453125 এ সেট হয়। জাম্পের বাকী বাকী বাকী অংশটি মাধ্যাকর্ষণতে রেখে গেছে।

প্লেয়ারটি আরোহণের সাথে সাথে তার উল্লম্ব বেগটি 0.25 / ফ্রেমের হারে 0 তে রূপান্তর করে। প্লেয়ারের বেগ যখন শূন্যের চেয়ে কম মানের কাছে পৌঁছায়, তবে वेगটি ভিন্ন ধাঁচের পরে পরিবর্তন হয়। প্রতি ফ্রেমে অবিচ্ছিন্নভাবে 0.25 দ্বারা কমার পরিবর্তে, এটি এই ধরণটি অনুসরণ করে:

[1.75, -0.25, -0.25, -0.25, 1.75, -0.25, -0.25, -0.25, 1.75, ...]

এটি পূর্ণসংখ্যার ওভারফ্লোতে কিছু করার আছে বলে মনে হচ্ছে।

ডেটা:

এখানে মূল থেকে ডেটা ফেলা হয়। এটি বেগের একটি টেবিল।

Jump Curve

Y-Hi Y-Lo    Decimal        Change/Frame
4    165     4.64453125     ?
4    101     4.39453125     -0.25
4    37      4.14453125     -0.25
3    229     3.89453125     -0.25
3    165     3.64453125     -0.25
3    101     3.39453125     -0.25
3    37      3.14453125     -0.25
2    229     2.89453125     -0.25
2    165     2.64453125     -0.25
2    101     2.39453125     -0.25
2    37      2.14453125     -0.25
1    229     1.89453125     -0.25
1    165     1.64453125     -0.25
1    101     1.39453125     -0.25
1    37      1.14453125     -0.25
0    229     0.89453125     -0.25
0    165     0.64453125     -0.25
0    101     0.39453125     -0.25
0    37      0.14453125     -0.25
-1   229     -1.89453125    1.75
-1   165     -1.64453125    -0.25
-1   101     -1.39453125    -0.25
-1   37      -1.14453125    -0.25
-2   229     -2.89453125    1.75
-2   165     -2.64453125    -0.25
-2   101     -2.39453125    -0.25
-2   37      -2.14453125    -0.25
-3   229     -3.89453125    1.75
-3   165     -3.64453125    -0.25
-3   101     -3.39453125    -0.25
-3   37      -3.14453125    -0.25
-4   229     -4.89453125    1.75
-4   165     -4.64453125    -0.25
-4   101     -4.39453125    -0.25
-4   37      -4.14453125    -0.25
-5   229     -5.89453125    1.75
-5   165     -5.64453125    -0.25
-5   101     -5.39453125    -0.25
-5   37      -5.14453125    -0.25
-6   229     -6.89453125    1.75

সমস্যা:

আমার গেমটিতে আমি এই প্রভাবটি অর্জন করতে সক্ষম হইনি। বেগ যখন শূন্যের চেয়ে কম হয় তবে এটি উপরে বর্ণিত প্যাটার্নের পরিবর্তে নিয়মিত 0.25 দ্বারা হ্রাস পেতে থাকে। সম্পূর্ণ এবং ভগ্নাংশ অংশ পৃথকভাবে সঞ্চয় করার পরিবর্তে, আমি সেগুলি একক ফ্লোটে একসাথে সঞ্চয় করছি।

এই প্রভাবটি কীভাবে অর্জন করা যায়?


1
সত্যি কথা বলতে, আমি তার সর্বাধিক জাম্পের উচ্চতা / দৈর্ঘ্য পিক্সেলের জন্য কাজ করতে স্ক্রিনশট নিয়েছি এবং এটি আপনার বর্তমান ফাংশনটিকে যতটা সম্ভব সম্ভব দেখতে পঠন করি। আপনি বলছেন যে অনর্থক উদ্দেশ্যমূলক, তাই এটির কারণে কোনও সমস্যা হওয়া উচিত নয়?
জোনাথন কনেল

আমি মনে করি আপনি যে অংশটি বেগ পরিবর্তন করছেন সেটিকে আপনার পোস্ট করতে হবে এবং কোডটিতে সমস্যা এবং আপনার প্রয়োজনীয়তাটি সঠিকভাবে বর্ণনা করতে হবে।
Ali1S232

2
@ গেজেট কি? সমস্যাটি তিনি ঠিক বর্ণনা করেছিলেন।
মাইক সেমদার

@ মাইকসেমদার: আমি কীভাবে তার কোডের উপর ভিত্তি করে সমাধান দেওয়ার জন্য পদার্থবিজ্ঞানের ইঞ্জিন প্রয়োগ করেছিলাম তা সম্পর্কে আমি আগ্রহী।
Ali1S232

আপনার আরও বিশদ বিবরণ প্রয়োজন হলে আমাকে জানান, আমি টিএল; ডাঃ এর প্রতিক্রিয়া পাব এই ভয়ে আমি একটি বিশাল পোস্ট লিখতে চাইনি।
জ্যাক দ্য হিউম্যান

উত্তর:


16
one byte for the whole number and another for the fractional part

মূলত আপনাকে low0.25 বিয়োগ করতে কেবল 64 টি বিয়োগ করতে হবে কারণ একটি 8 বিটের মানের 256 মান থাকতে পারে, তাই 256 * 0.25 = 64 যখন low1 থেকে বিয়োগও হয় high

দাবি অস্বীকার: codeণাত্মক সংখ্যার ক্ষেত্রে এই কোডটি ইচ্ছাকৃতভাবে ভুল, প্রশ্নটিতে বর্ণিত সংখ্যাসূচক ব্যঙ্গতাকে মডেল করার কথা। তুলনামূলক কারণে স্থির পয়েন্ট শ্রেণি পরিচালনা করা একটি সঠিক নেতিবাচক সংখ্যা বাস্তবায়ন এই উত্তরের নীচে পাওয়া যাবে।

struct velocity
{
    char high;
    unsigned char low;

    // fall -0.25
    void fall()
    {
        if(low < 64) --high;
        low -= 64;;
    }

    // convert to a float
    float toFloat() const
    {
        float ret = high;
        float frac = (float)low / 256.0f;
        if(high >= 0) ret += frac;
        else ret -= frac;
        return ret;
    }

    // convert from float
    void fromFloat(float f)
    {
        high = (char)f;
        float frac = f - high;
        low = (unsigned char)(frac * 256.0f);
    }
};

velocity v;
v.high = 4;
v.low = 165;    
for(int i = 0; i < 30; ++i)
{
    printf("%2d     %3d   %f\n", v.high, v.low, v.toFloat());
    v.fall();
}

সম্পাদনা : আমি ভাসা এবং ভাসা এবং আউটপুট থেকে রূপান্তরটি যুক্ত করেছি

উত্পন্ন আউটপুটটি আপনার টেবিলের মতোই:

 4     165   4.644531
 4     101   4.394531
 4      37   4.144531
 3     229   3.894531
 3     165   3.644531
 3     101   3.394531
 3      37   3.144531
 2     229   2.894531
 2     165   2.644531
 2     101   2.394531
 2      37   2.144531
 1     229   1.894531
 1     165   1.644531
 1     101   1.394531
 1      37   1.144531
 0     229   0.894531
 0     165   0.644531
 0     101   0.394531
 0      37   0.144531
-1     229   -1.894531
-1     165   -1.644531
-1     101   -1.394531
-1      37   -1.144531
-2     229   -2.894531
-2     165   -2.644531
-2     101   -2.394531
-2      37   -2.144531
-3     229   -3.894531
-3     165   -3.644531
-3     101   -3.394531
-3      37   -3.144531
-4     229   -4.894531
-4     165   -4.644531
-4     101   -4.394531
-4      37   -4.144531
-5     229   -5.894531
-5     165   -5.644531
-5     101   -5.394531
-5      37   -5.144531
-6     229   -6.894531

বিপরীতে এই নির্দিষ্ট পয়েন্ট শ্রেণিটি নেতিবাচক সংখ্যাগুলি সঠিকভাবে পরিচালনা করে:

#include <iomanip>
#include <iostream>

struct fixed_point
{
    union
    {
        struct
        {
            unsigned char low;
            signed char high;
        };
        short s;
    };

    float toFloat() const
    {
        fixed_point tmp;
        if(high < 0) tmp.s = ~s;
        else tmp.s = s;

        float ret = tmp.high;
        float frac = (float)tmp.low / 256.0f;
        ret += frac;
        if(high < 0) ret = 0 - ret;
        return ret;
    }

    void fromFloat(float f)
    {
        float tmp;
        if(f < 0.0f) tmp = -f;
        else tmp = f;

        high = (char)tmp;
        float frac = tmp - high;
        low = (unsigned char)(frac * 256.0f);

        if(f < 0.0f) s = ~s;
    }

    fixed_point operator+(const fixed_point &fp) const
    {
        fixed_point ret;
        ret.s = s + fp.s;
        return ret;
    }

    fixed_point operator-(const fixed_point &fp) const
    {
        fixed_point ret;
        ret.s = s - fp.s;
        return ret;
    }

    void print(const char *msg) const
    {
        std::cout << msg << ":" << std::endl;
        std::cout << std::hex << std::uppercase;
        // cout'ing the hex value for a char is kind of a pain ..
        unsigned int _high = 0;
        memcpy(&_high, &high, 1);
        std::cout << "  high : 0x" << std::setfill('0') << std::setw(2) << _high << std::endl;
        unsigned int _low = 0;
        memcpy(&_low, &low, 1);
        std::cout << "  low  : 0x" << std::setfill('0') << std::setw(2) << _low << std::endl;
        std::cout << "  all  : 0x" << std::setfill('0') << std::setw(4) << s << std::endl;
        std::cout << "  float: " << toFloat() << std::endl;
        std::cout << std::endl;
    }
};

1
@ জ্যাক হ্যাঁ নিশ্চিত, আমার অবস্থানের কাঠামোটি দেখুন, আমি ফ্লোট ফাংশনে একটি রূপান্তর যুক্ত করেছি যা ঠিক এটি করে।
মাইক সেমদার

1
@ জ্যাক এছাড়াও ফ্লোট রূপান্তর থেকে একটি যোগ করেছে
মাইক সেমদার

1
@ মাইক আপনি স্যার, একজন ভদ্রলোক। সাহায্যের জন্য ধন্যবাদ. এটি আমাকে ট্র্যাক এ ফিরে আসবে।
জ্যাক দ্য হিউম্যান

1
@ জ্যাক আপনাকে খুব স্বাগত জানাই, বিশেষত এইরকম চমৎকার প্রশ্নের জন্য আপনাকে সাহায্য করতে পেরে আনন্দিত :)
মাইক সেমডার

1
@ জ্যাক আপনার আগ্রহের ক্ষেত্রে, আমি একটি নির্দিষ্ট পয়েন্ট শ্রেণি যুক্ত করেছি যা তুলনার জন্য
theণাত্মক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.