প্ল্যাটফর্মার তৈরি করা - কোনও খেলোয়াড়কে লাফানোর অনুমতি দেওয়া হয় কীভাবে তা নির্ধারণ করবেন?


16

আমি একটি সাধারণ প্লাটফর্মার ঝাঁপ এন 'রান স্টাইল গেমটি তৈরি করছি। আমি টাইল ব্যবহার করি না - পরিবর্তে আমি আমার স্তরের সত্তার জন্য জ্যামিতিক আকার নিয়েছি (এবং প্লেয়ারটিও এক)। আমি আমার সংঘর্ষ সনাক্তকরণ কোডটি শেষ করেছি এবং এখন পর্যন্ত সবকিছু ঠিকঠাক কাজ করে।

এর পরে, আমি জাম্পিং বাস্তবায়ন করতে চেয়েছিলাম। প্লেয়ারটি উপযুক্ত কীটি হিট করে এবং কিছু উপরে wardsর্ধ্বগতি যুক্ত করেছে কিনা তা খতিয়ে দেখছি। ঠিকভাবে কাজ করে. খেলোয়াড়টি বাতাসে থাকলেও এটি কাজ করে, যা আমি চাই তা নয়। ;-)

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

ধন্যবাদ!

উত্তর:


14

দুটি বিকল্প মনে মনে বসন্ত:

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

সাধারণ চেকটি আমার কাছে দুর্দান্ত ধারণা বলে মনে হয়। পোস্ট করার জন্য ধন্যবাদ।
ক্রিস্টোফার হরেেনস্টাইন

সাধারণ পরীক্ষার জন্য +1। এটি নিশ্চিত করে যে কোনও তল কোনও সমস্যা ছাড়াই একটি প্রাচীরের মধ্যে নির্বিঘ্নে রূপান্তরিত করতে পারে।
সোভিয়েট

1
+1 অবশ্যই সংঘর্ষ-স্বাভাবিক পরীক্ষা করুন। বিভিন্ন ধরণের বিশ্ব-জ্যামিতি থাকা ভাল এবং এটি আরও নমনীয় স্তরের ডিজাইনের অনুমতি দেয় তবে এটি আপনাকে প্রাথমিক সমস্যার সমাধান করে না। কোনও "প্রাচীর" এছাড়াও "স্থল" টাইপের হতে পারে, যদি আপনি এটিতে দৌড়ে থাকেন বা তার উপর দাঁড়িয়ে থাকেন তবে depending সেখানেই সংঘর্ষ-স্বাভাবিক সাহায্য করবে।
বাম্মজ্যাক

আমি সাধারণ সমাধানটি খুব সুন্দর খুঁজে পাই এবং আমার সমস্যাটি সমাধান করব। এমনকি অন্যান্য উচ্চ-রেটিং উত্তরগুলিও চমৎকার এবং এরকম - তবে এটি আমার প্রশ্নের উত্তর আরও ভাল করে দেয়। আপনার ওয়ার্কার্সকে ধন্যবাদ!
মালাক্স

8

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

এই ধারণাটি এখানে: প্রতিটি "বিভাগে" গণনার একটি পতাকা রয়েছে। উদাহরণ স্বরূপ:

namespace Collisions
{
    enum Type
    {
        None   = 0,
        Floor  = 1 << 0,
        Ladder = 1 << 1,
        Enemy  = 1 << 2,
        ... // And whatever else you need.

        // Then, you can construct named groups of flags.
        Player = Floor | Ladder | Enemy
    };
}

এই পদ্ধতির সাহায্যে আপনি পরীক্ষা করতে সক্ষম হবেন যদি প্লেয়ারটি আপনার পরিচালনা করা উচিত এমন কোনও কিছুকে ধাক্কা খায়, যাতে আপনার ইঞ্জিন সত্তার কোনও "ধর্ষক" পদ্ধতিতে কল করতে পারে:

void Player::Collided( Collisions::Type group )
{
   if ( group & Collisions::Ladder )
   {
      // Manage Ladder Collision
   }
   if ( group & Collisions::Floor )
   {
      // Manage Floor Collision
   }
   if ( group & Collisions::Enemy )
   {
      // Manage Enemy Collision
   }
}

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

void PhysicEngine::OnCollision(...)
{
    mPhysics.AddContact( body1, body1.GetFilter(), body2, body2.GetFilter() );
}

এনামের পরিবর্তে কনস্টেন্ট ইনট ব্যবহার করার কোনও কারণ আছে কি? একটি একক পতাকা বা নামযুক্ত গোষ্ঠীর অধঃপতনের ক্ষেত্রে গণনা করা প্রকারটি আরও বেশি পঠনযোগ্য এবং আপনি বেশিরভাগ সংকলকগুলিতে অতিরিক্ত টাইপ-চেকিং ক্ষমতা পান।

হ্যাঁ, এনামগুলি নতুন কাস্টম গোষ্ঠী তৈরি করতে বাইনারি অপারেটরগুলি (আমার মনে হয়) ব্যবহার করতে পারে না। যে কারণে আমি থিস কনস তৈরি করেছি তা হ'ল আমি কনফিগার প্যারামিটারগুলির সুরক্ষা রেখে পঠনযোগ্যতার কারণে পাবলিক স্ট্যাটিক সদস্যদের সাথে একটি কনফিগার ক্লাস ব্যবহার করি।
ফ্রেডেরিক ইম্বিয়াউল্ট

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

একটি গণিত টাইপ ব্যবহার করতে আমি আপনার কোডের উদাহরণগুলি আপডেট করেছি।

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

1

যদি আপনি একটি নির্দিষ্ট দূরত্বে আপনার চরিত্রের পা সর্বদা চরিত্রের নীচে বিবেচনা করেন এবং আপনি যদি পৃষ্ঠ থেকে সরে না যান তবে আপনার চরিত্রটি মাটিতে রয়েছে।

মোটামুটি ছদ্ম কোডে:

bool isOnGround(Character& chr)
{
   // down vector is opposite from your characters current up vector.
   // if you want to support wall jumps, animate the vecToFoot as appropriate.
   vec vecToFoot = -chr.up * chr.footDistanceFromCentre;

// if feet are moving away from any surface, can't be on the ground if (dot(chr.velocity, down) < 0.0f) return false;

// generate line from character centre to the foot position vec linePos0 = chr.position; vec linePos1 = chr.position + vecToFoot;

// test line against world. If it returns a hit surface, we're on the ground if (testLineAgainstWorld(line0, line1, &surface) return true;

return false; }


আপনি যদি মনে করেন যে ডাবল জাম্প, বা প্রাচীরের জাম্পের মতো বৈশিষ্ট্যগুলি যুক্ত করতে চান তবে এটি কাজ করবে না?
ফ্রেডেরিক ইম্বিয়েল্ট

আমি বিশ্বাস করি না যে ওপি ডাবল লাফ বা ওয়াল জাম্পের কথা উল্লেখ করেছে, সে কি?
jpaver

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

এটি সাধারণত সংঘর্ষের চেক করার একটি কম নমনীয় উপায়। (কম নমনীয় কারণ আপনি সাধারণের দিকটি যাচাই করে সিলিং জাম্প থেকে একটি তল জাম্প থেকে তুচ্ছভাবে পৃথক করতে পারেন))

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