এক্সট্রোপোলেশন সংঘর্ষ সনাক্তকরণ বিরতি দেয়


10

আমার স্প্রাইটের আন্দোলনে এক্সট্রাপোলেশন প্রয়োগ করার আগে, আমার সংঘর্ষ পুরোপুরি কার্যকর হয়েছিল। যাইহোক, আমার স্প্রাইটের চলাচলে (জিনিসগুলি মসৃণ করতে) এক্সট্রাপোলেশন প্রয়োগ করার পরে, সংঘর্ষটি আর কাজ করে না।

এক্সট্রা পোপুলেশনের আগে জিনিসগুলি এভাবে কাজ করেছিল:

এখানে চিত্র বর্ণনা লিখুন

যাইহোক, আমি আমার এক্সট্রাপোলেশনটি প্রয়োগ করার পরে, সংঘর্ষের রুটিনটি ভেঙে যায়। আমি ধরে নিচ্ছি কারণ এটি এক্সট্রাপোলেশন রুটিন দ্বারা উত্পাদিত নতুন স্থানাঙ্কের (যা আমার রেন্ডার কলটিতে অবস্থিত) কাজ করছে upon

আমি আমার এক্সট্রাপোলেশন প্রয়োগ করার পরে

এখানে চিত্র বর্ণনা লিখুন

এই আচরণটি কীভাবে সংশোধন করবেন?

আমি এক্সট্রাপোলেশনের ঠিক পরে অতিরিক্ত সংঘর্ষের চেক লাগানোর চেষ্টা করেছি - এটি অনেক সমস্যার সমাধান করবে বলে মনে হচ্ছে তবে আমি এটিকে বাতিল করে দিয়েছি কারণ আমার রেন্ডারিংয়ে যুক্তি যুক্ত করা প্রশ্নের বাইরে নয়।

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

আমি এখানে বেশ কয়েকটি অনুরূপ প্রশ্ন পেয়েছি কিন্তু উত্তরগুলি আমাকে সাহায্য করেনি।

এটি আমার এক্সট্রা পোলেশন কোড:

public void onDrawFrame(GL10 gl) {


        //Set/Re-set loop back to 0 to start counting again
        loops=0;

        while(System.currentTimeMillis() > nextGameTick && loops < maxFrameskip){

        SceneManager.getInstance().getCurrentScene().updateLogic();
        nextGameTick+=skipTicks;
        timeCorrection += (1000d/ticksPerSecond) % 1;
        nextGameTick+=timeCorrection;
        timeCorrection %=1;
        loops++;
        tics++;

     }

        extrapolation = (float)(System.currentTimeMillis() + skipTicks - nextGameTick) / (float)skipTicks; 

        render(extrapolation);
}

এক্সট্রাপোলেশন প্রয়োগ করা

            render(float extrapolation){

            //This example shows extrapolation for X axis only.  Y position (spriteScreenY is assumed to be valid)
            extrapolatedPosX = spriteGridX+(SpriteXVelocity*dt)*extrapolation;
            spriteScreenPosX = extrapolationPosX * screenWidth;

            drawSprite(spriteScreenX, spriteScreenY);           


        }

সম্পাদন করা

আমি উপরে উল্লিখিত হিসাবে, আমি স্প্রাইটের স্থানাঙ্কগুলির একটি অনুলিপিটি বিশেষভাবে আঁকার জন্য তৈরি করার চেষ্টা করেছি .... এটির নিজস্ব সমস্যা রয়েছে।

প্রথমত, অনুলিপিটি নির্বিশেষে, স্প্রাইটটি যখন চলমান হয়, তখন এটি খুব মসৃণ হয়, যখন এটি থামে, এটি সামান্য বাম / ডানদিকে ঘুরপাক খাচ্ছে - কারণ এটি এখনও সময়ের ভিত্তিতে নিজের অবস্থানকে বহির্মুখী করে তুলছে। এটি কি স্বাভাবিক আচরণ এবং স্প্রাইট বন্ধ হয়ে গেলে আমরা কি 'এটি বন্ধ' করতে পারি?

আমি বাম / ডানদিকের জন্য পতাকা রাখার চেষ্টা করেছি এবং যদি এর মধ্যে দুটি সক্ষম হয় তবে কেবল এক্সট্রাপোলেটিং। আমি কোনও পার্থক্য আছে কিনা তা দেখার জন্য আমি সর্বশেষ এবং বর্তমান অবস্থানগুলি অনুলিপি করার চেষ্টা করেছি। তবে সংঘর্ষ যতদূর যায় এগুলি সাহায্য করে না help

যদি ব্যবহারকারীটি টিপতে থাকে, ডান বোতামটি এবং স্প্রাইটটি ডানদিকে চলে যাচ্ছে, যখন এটি কোনও দেয়ালের সাথে আঘাত করে, ব্যবহারকারী যদি ডান বোতামটি ধরে রাখেন, স্প্রাইটটি ডানদিকে অ্যানিমেটিং চালিয়ে যাবে, যখন প্রাচীর দ্বারা থামানো হবে ( তবে প্রকৃতপক্ষে চলমান নয়) তবে ডান পতাকা এখনও সেট করা আছে এবং সংঘর্ষের রুটিনটি ক্রমাগত দেওয়াল থেকে স্প্রিটকে সরিয়ে নিয়ে যাওয়ার কারণে এটি স্প্রাইডটি এখনও চলছে বলে কোডটিতে প্রদর্শিত হয় (প্লেয়ার নয়) এবং তাই এক্সট্রাপোলেশন অবিরত। সুতরাং খেলোয়াড়টি যা দেখতে পাবে তা হ'ল স্প্রাইট 'স্ট্যাটিক' (হ্যাঁ, এটি অ্যানিমেট করা হচ্ছে, তবে এটি আসলে পর্দা জুড়ে চলছে না), এবং প্রতিবার এবং পরে এটি হস্তান্তরিতভাবে কাঁপতে থাকে যেহেতু এক্সট্রাপোলেশন এটি করার চেষ্টা করে ..... .. এই সাহায্য আশা করি


1
পুরোপুরি বুঝতে এটি কিছুটা হজম করবে ('ইন্টারপোলেশন' আপাতদৃষ্টিতে এক ডজন পৃথক অর্থ রয়েছে এবং এটি এখানে আপনি কী বোঝাতে চাইছেন তা প্রথম নজরে সম্পূর্ণ পরিষ্কার নয়) তবে আমার প্রথম প্রবৃত্তিটি 'আপনার প্রভাবিত করার জন্য আপনাকে কিছু করা উচিত নয় আপনার রেন্ডারিং রুটিনে অবজেক্টের অবস্থান '। আপনার রেন্ডারারের উচিত আপনার অবজেক্টের অবজেক্টের দেওয়া অবস্থানটি আঁকতে হবে এবং সেই বস্তুকে ম্যানিপুলেট করা সমস্যার জন্য একটি রেসিপি রয়েছে, কারণ এটি অন্তর্নিহিতভাবে গেমের পদার্থবিজ্ঞানে রেন্ডারকে দম্পতি করে। একটি আদর্শ বিশ্বে, আপনার রেন্ডারারের গেম অবজেক্টগুলিতে কনস্ট পয়েন্টার নিতে সক্ষম হওয়া উচিত।
স্টিভেন স্টাডনিকি

হাই, স্টিভেনস্ট্যাডনিকি, আপনার মন্তব্যের জন্য অনেক ধন্যবাদ, এমন একটি প্রচুর উদাহরণ রয়েছে যা রেন্ডারারের কাছে একটি অন্তরঙ্গকরণের মানকে দেখানো হচ্ছে, দয়া করে এটি দেখুন: mysecretroom.com/www/programming-and-software/… যা এখান থেকে আমার রূপান্তরিত হয়েছে আমার কোড। আমার সীমিত বোঝাপড়াটি হ'ল এটি সর্বশেষ এবং পরবর্তী আপডেটগুলির মধ্যে অবস্থানটিকে গত আপডেটের পরে নেওয়া সময়ের পরিমাণের ভিত্তিতে বিভক্ত করে তোলে - আমি সম্মতি জানাই এটি একেবারে দুঃস্বপ্নের মত! আমি আপনাকে কৃতজ্ঞ
জানব

6
ঠিক আছে, আমি বলব 'কেবল কারণ আপনি কোনও কিছুর কোড খুঁজে পেতে পারেন এটি সেরা অনুশীলন করে না'। :-) এই ক্ষেত্রে, যদিও আমি সন্দেহ করি যে পৃষ্ঠাগুলির সাথে আপনি লিঙ্ক করেছেন তার পৃষ্ঠাগুলি কোথায় এটির অবজেক্টগুলি প্রদর্শন করতে পারে তা নির্ধারণের জন্য ব্যবহার করে তবে এটি তাদের সাথে বস্তুর অবস্থানগুলি আপডেট করে না; আপনি প্রতিটি ফ্রেম গণনা করে এমন একটি ড্র-নির্দিষ্ট অবস্থান রেখে, তবে সেই অবস্থানটি বস্তুর আসল 'শারীরিক' অবস্থান থেকে পৃথক রেখে আপনি এটিও করতে পারেন ।
স্টিভেন স্টাডনিকি 21'14

হাই @ স্টিভেনস্ট্যাডনিকি, আমার প্রশ্নে বর্ণিত হিসাবে (অনুচ্ছেদটি "আমি একটি অনুলিপি তৈরির চেষ্টাও করেছি") শুরু করে দিয়েছি, আমি ইতিমধ্যে 'কেবলমাত্র ড্র' অবস্থানটি ব্যবহার করার চেষ্টা করেছি :-) আপনি যেখানে দ্বিখণ্ডনের কোনও পদ্ধতির প্রস্তাব দিতে পারবেন? রেন্ডার রুটিনের মধ্যে স্প্রাইটের অবস্থানের সাথে সামঞ্জস্য করার দরকার নেই? ধন্যবাদ!
BungleBonce

আপনার কোডটি দেখে মনে হচ্ছে আপনি ইন্টারপোলেশনের পরিবর্তে এক্সট্রাপোলেশন করছেন।
দুর্জা 6007

উত্তর:


1

আমি এখনও কোনও মন্তব্য পোস্ট করতে পারি না, তাই আমি উত্তর হিসাবে এটি পোস্ট করব।

যদি আমি সমস্যাটি সঠিকভাবে বুঝতে পারি তবে এটি এরকম কিছু হয়:

  1. প্রথম আপনার একটি সংঘর্ষ আছে
  2. তারপরে অবজেক্টের অবস্থান সংশোধন করা হয়েছে (সম্ভবত সংঘর্ষ সনাক্তকরণের রুটিন দ্বারা)
  3. অবজেক্টের আপডেট হওয়া অবস্থানটি রেন্ডার ফাংশনে প্রেরণ করা হয়
  4. রেন্ডার ফাংশন তারপরে এক্সট্রাপোলেশন ব্যবহার করে অবজেক্টের অবস্থান আপডেট করে
  5. এক্সট্রাপোল্টেড অবজেক্টের অবস্থান এখন সংঘর্ষ সনাক্তকরণের রুটিনটিকে ভেঙে দেয়

আমি 3 টি সম্ভাব্য সমাধান সম্পর্কে ভাবতে পারি। আমি তাদের সেই ক্রমে তালিকাবদ্ধ করব যা ন্যূনতম আইএমএইচওর পক্ষে সর্বাধিক কাম্য।

  1. এক্সট্রাপোলেশনটি রেন্ডার ফাংশন থেকে সরিয়ে নিন। বস্তুর অবস্থান এক্সট্রপোলেট করুন এবং তারপরে সংঘর্ষের জন্য পরীক্ষা করুন।
  2. অথবা আপনি যদি রেন্ডার ফাংশনে এক্সট্রাপোলেশনটি রাখতে চান তবে সংঘর্ষের ঘটনাটি চিহ্নিত করার জন্য একটি পতাকা সেট করুন। সংঘর্ষ শনাক্তকরণটি ইতিমধ্যে যেমনটি করেছে ঠিক তেমন বস্তুটির অবস্থানটি সঠিক করে তুলুন, তবে আপনি এক্সট্রাপোলেশন মান গণনা করার আগে প্রথমে সংঘর্ষের পতাকাটি পরীক্ষা করুন। যেহেতু বস্তুটি যেখানেই এটি হওয়া দরকার সেখানে এটি স্থানান্তরিত করার দরকার নেই।
  3. শেষ সম্ভাবনা, যা আমার কাছে কাজের চেয়ে বেশি যা সংশোধন করার সাথে সংঘর্ষ শনাক্তকরণের সাথে অতিরিক্ত পরিবেশন করা হবে। সংঘর্ষের পরে অবজেক্টটি প্রাচীর থেকে দূরে সরিয়ে ফেলুন, যাতে এক্সট্রাপোলশনের পরে অবজেক্টটি প্রাচীরের দিকে ফিরে আসে।

# 2 এর জন্য উদাহরণ কোড।

if (collisionHasOccured)
    extrpolation = 0.0f;
else
    extrapolation = (float)(System.currentTimeMillis() + skipTicks - nextGameTick) / (float)skipTicks;

আমি মনে করি যে # 2 সম্ভবত রান করা খুব দ্রুত এবং সহজতর হবে যদিও # 1 আরও যুক্তিযুক্তভাবে সঠিক সমাধান বলে মনে হচ্ছে। আপনি কীভাবে আপনার ডেল্টার সময় সমাধান # 1 পরিচালনা করছেন তার উপর নির্ভর করে বৃহত্তর ব-দ্বীপ দ্বারা একইভাবে ভেঙে যেতে পারে, সেক্ষেত্রে আপনাকে # 1 এবং # 2 উভয়ই একসাথে ব্যবহার করতে হতে পারে।

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

বলা হচ্ছে, একমাত্র সমস্যা হ'ল বস্তুটি সংঘর্ষের পরে চলেছে। যদি কোনও সংঘর্ষ হয় তবে অবজেক্টটি সেই দিকে অগ্রসর হওয়া উচিত। সুতরাং, যদি কোনও সংঘর্ষ হয়, তবে তার গতি 0 তে সেট করুন This এটি বস্তুটিকে আরও কোনওভাবে সরানো থেকে রেন্ডার ফাংশনটি থামিয়ে দেওয়া উচিত।


হাই @ অহলিও আমি অপশন 2 টি ব্যবহার করে দেখেছি এবং এটি কাজ করে তবে কিছু ভুলের কারণ হতে পারে আমি ভুলটি করেছি, আমি এটি আবার ঘুরে দেখব। তবে আমি বিকল্প 1-তে খুব আগ্রহী যদিও এটি কীভাবে করা যায় তার কোনও তথ্য আমি পাই না। আমি কীভাবে আমার যুক্তিযুক্ত রুটিনে এক্সট্রোপোলেট করতে পারি? বিটিডব্লিউ আমার ডেল্টা ঠিক করা হয়েছে তাই 1/60 বা 0.01667 হয় (বরং এটি আমার এই চিত্রটি সংহত করতে ব্যবহার করে যদিও আমার গেমের প্রতিটি পুনরাবৃত্তি যে সময় নেয় তাতে স্পষ্টতই যা চলছে তার উপর নির্ভর করে তবে 0.0167 এর বেশি কখনই নেওয়া উচিত নয়) ) সুতরাং যে কোনও সহায়তা মহান ধন্যবাদ হবে।
বাংলোবোনস

আপনি কী করছেন তা সম্ভবত আমি পুরোপুরি বুঝতে পারি না। আমার কাছে কিছুটা অদ্ভুত বলে মনে হচ্ছে এমন কিছু হ'ল আপনি কেবল আপনার ড্র অনুষ্ঠানের ক্ষেত্রে অবস্থানের গতিবিধি করছেন না; আপনি সময় গণনা করছেন। এটি কি প্রতিটি বস্তুর জন্য করা হয়? সঠিক ক্রমটি হওয়া উচিত: গেম লুপ কোডে সময় গণনা। গেম লুপ একটি আপডেট (ডিটি) ফাংশনে ডেল্টাটি পাস করে। আপডেট (ডিটি) সমস্ত গেমের অবজেক্ট আপডেট করবে। এটি কোনও চলন, এক্সট্রোপোলেশন এবং সংঘর্ষ সনাক্তকরণ পরিচালনা করতে হবে। আপডেট () গেম লুপটিতে ফিরে আসার পরে এটি একটি রেন্ডার () ফাংশনটি কল করে যা সমস্ত নতুনভাবে আপডেট হওয়া গেমের অবজেক্টগুলিকে আঁকবে।
আহোলিও

হুমমমম বর্তমানে আমার আপডেট ফাংশনটি সবকিছু করে। চলাচল (আন্দোলনের দ্বারা আমি স্প্রাইটের নতুন অবস্থান গণনা করে - এটি আমার ব-দ্বীপের সময় থেকে গণনা করা হয়) Does আমি আমার রেন্ডার ফাংশনে কেবলমাত্র কাজটি করছি (আসলে অঙ্কন ছাড়াও) 'নতুন' অবস্থানকে অতিরিক্ত করে তোলা হচ্ছে, তবে অবশ্যই এটি সময় ব্যবহার করে কারণ এটি রেন্ডার কলটির শেষ যুক্তি আপডেট থেকে সময় গ্রহণ করতে হবে। এটি আমার বোঝাপড়া যাইহোক :-) আপনি এটি কীভাবে করবেন? আমি বুঝতে পারি না কীভাবে কেবল যুক্তি আপডেটের মধ্যে এক্সট্রাপোলেশন ব্যবহার করা যায়। ধন্যবাদ!
বাংলোবোনস

আমার উত্তর আপডেট। আশা করি এটি সহায়তা করে
আহোলিও

ধন্যবাদ, আমার আসল প্রশ্নে দেখুন "যখন এটি থামবে, তখন এটি সামান্য বাম / ডানদিকে ঘুরপাক খাচ্ছে" - সুতরাং আমি আমার স্প্রিটটি থামিয়ে দিলেও, এক্সট্রাপোলেশনটি স্প্রিটকে এখনও 'চলমান' (ঘোরাফেরা) করে রাখে - এটি ঘটে কারণ আমি ব্যবহার করি না আমার এক্সট্রা প্লেশনটি কাজ করার জন্য স্প্রাইটের পুরাতন এবং বর্তমান অবস্থানগুলি, সুতরাং স্প্রাইট স্থির থাকলেও, এটি এখনও 'এক্সট্রোপোলেশন' মানের উপর ভিত্তি করে এই ঝাঁকুনির প্রভাব রাখে যা প্রতিটি ফ্রেমের পুনরাবৃত্তির কাজ করে। এমনকি আমি বলার চেষ্টা করেছি 'যদি পুরানো এবং বর্তমানের পোস্টগুলি একই হয় তবে এক্সট্রোপোলেটেড করবেন না' তবে এটি এখনও কাজ করে বলে মনে হচ্ছে না, আমি ফিরে গিয়ে অন্য চেহারা নেব!
বাংলোবোনস

0

দেখে মনে হচ্ছে আপনার সম্পূর্ণ পদার্থবিজ্ঞানের রেন্ডারিং এবং আপডেট করার প্রয়োজন separate সাধারণত অন্তর্নিহিত সিমুলেশন বিচ্ছিন্ন সময়-পদক্ষেপে চলবে, এবং ফ্রিকোয়েন্সি কখনই পরিবর্তন হবে না। উদাহরণস্বরূপ, আপনি প্রতি 1 সেকেন্ডের 60/60 তম আপনার বলের চলাচল অনুকরণ করতে পারেন, এবং এটিই।

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

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

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

নিবন্ধ থেকে এখানে গুরুত্বপূর্ণ psuedo কোড:

const float fps = 100
const float dt = 1 / fps
float accumulator = 0

// In units seconds
float frameStart = GetCurrentTime( )

// main loop
while(true)
  const float currentTime = GetCurrentTime( )

  // Store the time elapsed since the last frame began
  accumulator += currentTime - frameStart( )

  // Record the starting of this frame
  frameStart = currentTime

  // Avoid spiral of death and clamp dt, thus clamping
  // how many times the UpdatePhysics can be called in
  // a single game loop.
  if(accumulator > 0.2f)
    accumulator = 0.2f

  while(accumulator > dt)
    UpdatePhysics( dt )
    accumulator -= dt

  const float alpha = accumulator / dt;

  RenderGame( alpha )

void RenderGame( float alpha )
  for shape in game do
    // calculate an interpolated transform for rendering
    Transform i = shape.previous * alpha + shape.current * (1.0f - alpha)
    shape.previous = shape.current
    shape.Render( i )

RenderGameফাংশন সবচেয়ে আগ্রহের বিষয়। ধারণাটি হ'ল আলাদা সিমুলেশন পজিশনের মধ্যে আন্তঃবিবাহ ব্যবহার করা। রেন্ডারিং কোডটি সিমুলেশন কেবল পঠনযোগ্য ডেটাগুলির নিজস্ব অনুলিপি তৈরি করতে পারে এবং রেন্ডার করতে একটি অস্থায়ী ইন্টারপোল্টেড মান ব্যবহার করে। এটি আপনাকে যা মনে হচ্ছে এমন কোনও নির্বোধ সমস্যা ছাড়াই খুব মসৃণ চলাচল করবে!

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