ফ্রেম স্বাধীন আন্দোলন


11

আমি এখানে চলাচলে আরও দুটি থ্রেড পড়েছি: সময় ভিত্তিক আন্দোলন বনাম ফ্রেমের হার ভিত্তিক আন্দোলন? , এবং কখন আমার একটি স্থির বা পরিবর্তনশীল সময়ের পদক্ষেপ ব্যবহার করা উচিত?

তবে আমার মনে হয় আমি ফ্রেম স্বতন্ত্র আন্দোলনের একটি প্রাথমিক বোঝার অভাব বোধ করছি কারণ এই থ্রেডগুলির মধ্যে কোনওটি কী বলছে তা আমি বুঝতে পারি না।

আমি অলসফির এসডিএল টিউটোরিয়ালগুলি অনুসরণ করছি এবং ফ্রেমের স্বাধীন পাঠের উপরে এসেছি। http://lazyfoo.net/SDL_tutorials/lesson32/index.php

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

এটা কি সঠিক? পাঠ বলেছেন:

"সেকেন্ডে শেষ ফ্রেম থেকে পিক্সেল প্রতি সেকেন্ডে * সময় * বেগ। সুতরাং যদি প্রোগ্রামটি প্রতি সেকেন্ডে 200 ফ্রেমে চলে: 200 পিপিএস * 1/200 সেকেন্ড = 1 পিক্সেল"

তবে ... আমি ভেবেছিলাম যে আমরা 200 পিপিএস এক সেকেন্ডের 1/1000 ম দ্বারা গুন করছি। প্রতি সেকেন্ডে ফ্রেম নিয়ে এই ব্যবসাটি কী?

ফ্রেম স্বাধীন আন্দোলন কীভাবে কাজ করে সে সম্পর্কে যদি কেউ আমাকে আরও কিছুটা বিশদ ব্যাখ্যা দিতে পারে তবে আমি প্রশংসা করব।

ধন্যবাদ.

সংযোজন:

SDL_Rect posRect;
posRect.x = 0;
posRect.y = 0;

float y, yVel;
y = 0;
yVel = 0;

Uint32 startTicks = SDL_GetTicks();

bool quit = false;
SDL_Event gEvent;

while ( quit == false )
{
    while ( SDL_PollEvent( &gEvent ) )
    {
        if ( gEvent.type == SDL_QUIT )
            quit = true;
    }

    if ( y <= 580 )
    {
        yVel += DOT_VEL;
        y += (yVel * (SDL_GetTicks() - startTicks)/1000.f);
        posRect.y = (int)y;
    }

    startTicks = SDL_GetTicks();
    SDL_BlitSurface( bg, NULL, screen, NULL );
    SDL_BlitSurface( dot, NULL, screen, &posRect );
    SDL_Flip( screen );
}

এই কোডটি স্ক্রিনের নীচে একটি বিন্দু সরিয়ে দেয়। আমি মনে করি আমার এখন পর্যন্ত সবকিছু ঠিক আছে। এটি পর্দার নীচে সরানো হয় কিন্তু একটি বিচিত্র জিনিসটি ঘটে যা ঘটে যা আমি ব্যাখ্যা করতে পারি না। বিন্দুটি যখন y- মানের থেকে বেশি হয় তখন y = 580 এ থাকার কথা। যাইহোক, আমি যখনই প্রোগ্রামটি চালাচ্ছি, বিন্দুটি অন্য কোনও স্থানে শেষ হবে, যার অর্থ সামান্য কিছুটা 580 এরও বেশি হবে, সুতরাং বিন্দুটি অর্ধেক বা পর্দার বাইরে অর্ধেকেরও বেশি (বিন্দুটি 20 পিক্সেল, পর্দা মাত্রা 800x600)। আমি যদি প্রোগ্রামটির শিরোনাম-বারটি ক্লিক করে ধরে রাখার মতো কিছু করি এবং তারপরে ছেড়ে দিই, ডটটি স্ক্রিন থেকে অদৃশ্য হয়ে যাবে। এটি প্রতিবার কীভাবে পরিবর্তনশীল? শিরোনামবার সমস্যা হিসাবে আমার মনে হয় কারণ এটি যখন আমি শিরোনামবারে ধরে থাকি তখন টাইমারটি এখনও চলমান থাকে এবং সময় অতিবাহিত হয় আরও বড় হয়ে যায়, ফলে পরবর্তী ফ্রেমে বিন্দুটি আরও বেশি দূরত্বে চলে যায়। এটা কি সঠিক?


আপনার সংযোজন আসলে অন্য একটি প্রশ্ন। আপনার বিদ্যমান প্রশ্নটিতে এটি যুক্ত করার পরিবর্তে আপনার এটি দ্বিতীয় প্রশ্ন করা উচিত। এটি সহজে উত্তর দেওয়া যায় যদিও: কেবল y- আন্দোলন গণনা করুন, উদাহরণস্বরূপ। yMovement = (yVel * (SDL_GetTicks() - startTicks)/1000.f);তারপরে করুন:if(y + yMovement <= 580){ y += yMovement; } else { y = 580; }
বম্মজ্যাক

উত্তর:


10

দ্রষ্টব্য: সমস্ত ভগ্নাংশটি ভাসমান বোঝানো।

ফ্রেম স্বতন্ত্র আন্দোলন সময়ের বাইরে আন্দোলনের ভিত্তিতে কাজ করে। আপনি শেষ ফ্রেমের পর থেকে যে পরিমাণ সময় ব্যয় করেছেন তা পাবেন (সুতরাং যদি এক সেকেন্ডে 60০ ফ্রেম থাকে তবে প্রতিটি ফ্রেম যদি একই ফ্রেম সময় নিয়ে থাকে তবে প্রতিটি ফ্রেম ১.০ / 60০.০ সেকেন্ড সময় নেয়) এবং এটি কতটা চলাচল করে তা আবিষ্কার করুন অনুবাদ।

যদি আপনি চান যে আপনার সত্তা নির্দিষ্ট সময়ের জন্য নির্দিষ্ট পরিমাণের স্থানটি সরিয়ে ফেলতে চান (আমরা প্রতি সেকেন্ডের জন্য 100 পিক্সেল বলব) তবে প্রতি ফ্রেমের পরিমাণকে কয়েক গুণ করে আপনার ফ্রেমে কত পিক্সেল স্থানান্তরিত করতে হবে তা জানতে পারবেন per বর্তমান ফ্রেমে কতটা চলাচল করা উচিত তা নির্ধারণ করার জন্য সেকেন্ডে (1.0 / 60.0) সময় পেরিয়ে দ্বিতীয় (100 পিক্সেল)।

সময় কেটে যাওয়ার পরিমাণ এবং একটি গতি যা সময়ের একক (সেকেন্ড বা মিলিসেকেন্ডের চেয়ে বেশি পছন্দসই) সংজ্ঞায়িত হয় তা ব্যবহার করে আপনার ফ্রেমে প্রতি কতটা আন্দোলন করা উচিত তা নির্ধারণ করে এটি কাজ করে। সুতরাং আপনার গণনাটি দেখতে পারে:movementPerSecond * (timeElapsedInMilliseconds / 1000.0)

আমি আশা করি যে এটি আপনাকে একরকম উপলব্ধি করেছে।

আমি আমার লোককে 200 পিক্সেল প্রতি সেকেন্ডে ডানদিকে নিয়ে যেতে চাই। পূর্ববর্তী ফ্রেমের পরে যদি বর্তমান ফ্রেমটি 50 মিলি সেকেন্ডে চালিত হয়, তবে আমার লোকটিকে পূর্ব নির্ধারিত গতির একটি ভগ্নাংশ (যা 200 পিক্সেল ছিল) সরানো উচিত। আমার তাকে দূরত্বের 50/1000 তম স্থানান্তরিত করা উচিত কারণ কেবলমাত্র 1/20 তম (50/1000 = 1/20) সময় কেটে গেছে। সুতরাং কেবলমাত্র তাকে 10 পিক্সেল স্থানান্তরিত করার অর্থ হবে (যদি আরও 19 ফ্রেম ঘটে থাকে, একে অপরকে থেকে 50 মিলিসেকেন্ড আলাদা করে রাখে, তবে দ্বিতীয় সেকেন্ডে চলাফেরার পরিমাণটি 200 পিক্সেল হবে, আমরা যে পরিমাণ চেয়েছিলাম)।

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

প্রতি সেকেন্ড ফ্রেম: এটি প্রতি সেকেন্ডে সংঘটিত ফ্রেমের পরিমাণ। সাধারণত একটি ফ্রেমের হার হ'ল হয় গেমটি কতবার আঁকিয়ে নেওয়া / সেকেন্ডে রেন্ডার করা হয় বা গেম লুপটি সেকেন্ডে কতবার পূর্ণ হয়।

স্থির শ্লোকের পরিবর্তনশীল সময়ের ধাপ: এটি ফ্রেমের মধ্যে সময়ের পরিমাণকে বোঝায়। সাধারণত, ফ্রেমের মধ্যে সময় স্থির থাকবে না। পদার্থবিজ্ঞানের মতো কিছু সিস্টেম / কোরের কিছু অনুকরণ / চালনার জন্য কিছু একক সময় প্রয়োজন। সাধারণত, পদক্ষেপের সময় স্থির করা হলে পদার্থবিজ্ঞান সিস্টেমগুলি আরও স্থিতিশীল / স্কেলেবল হয়। স্থির / পরিবর্তনশীল সময়ের ধাপগুলির মধ্যে পার্থক্য নামগুলি। স্থির সময়ের পদক্ষেপগুলি যা তাদের শোনাচ্ছে তা হ'ল: সময় নির্ধারিত সময় যা একটি নির্দিষ্ট হারে ঘটে। পরিবর্তিত সময়ের পদক্ষেপগুলি সময়ের ব্যবস্থাগুলি যা বিভিন্ন সময় / ভিন্ন হারে ঘটে।


উদাহরণস্বরূপ, আপনি 50 মিলিসেকেন্ড প্রতিটি ফ্রেমের জন্য সময়, সঠিক? এবং এটি 1000 / FPS দ্বারা গণনা করা হয়েছিল? এবং সুতরাং আপনার প্রতিটি ফ্রেমটি তৈরি করতে হবে যে আন্দোলনটি প্রতি সেকেন্ডে * 50/1000 পিক্সেল?
শ্রিম্পক্র্যাকার্স

এইচএম, আমি বুঝতে পেরেছি যে প্রতিটি সময় ফ্রেমের জন্য মিলিসেকেন্ডগুলি সম্ভবত পরিবর্তনশীল হবে, তাই না? গেটটিক্সের মতো কিছু -) স্টার্টটিক্স সর্বদা আলাদা এবং ধ্রুবক নয় not
শ্রিম্প ক্র্যাকার্স

@ ওমনিয়ন: আপনি যদি "সেকেন্ডে প্রতি পিক্সেল" এর মধ্যে দূরত্ব নির্দিষ্ট করে থাকেন তবে আপনি মিলিসেকেন্ড ব্যবহার করতে পারবেন না ... এটি 1.0 / 60.0 নয় 1000/60 হওয়া উচিত যার ফলে সম্পূর্ণ ভিন্ন কিছু ঘটতে পারে।
bummzack

@ শ্রিম্পক্র্যাকার্স হ্যাঁ, সময় অতিবাহিত হয়েছে। একটি পুরানো পিসি কল্পনা করুন যা 60 fps রেন্ডার করতে সক্ষম নয়। আপনি এখনও চান যে গেমটি একই গতিতে চালিত হয় (তবে একই এফপিএস নয়) such
bummzack

সুতরাং, অলস টিউটোরিয়ালে, ডেল্ট্যাটিক্স / 1000.f এর অর্থ 1000 কী? FPS যে? 1000 মিলিসেকেন্ড? আমি এখনই কিছুটা বিভ্রান্ত। দেখে মনে হয় যে প্রতিটি ফ্রেমের জন্য প্রয়োজনীয় সময় নির্ধারণের জন্য এফপিএস প্রয়োজনীয়, তবে এটি আসলে আন্দোলনের মধ্যে গণনা করে না।
শ্রিম্প ক্র্যাকার্স

7

ফ্রেম ডায়নামিক্সে কোনও সত্তা সরিয়ে রাখার জন্য আপনার কোড (উদাহরণস্বরূপ) এর মতো দেখতে পাবেন:

x = x + speedPerFrame

আপনি যদি ফ্রেম-স্বতন্ত্র হতে চান তবে এটি দেখতে এরকম হতে পারে:

x = x + speedPerSecond * secondsElapsedSinceLastFrame

ধন্যবাদ, এটা বোঝা যায়। উপরে আমার আরও একটি প্রশ্ন আছে।
শ্রিম্পক্র্যাকার্স

1

অতিরিক্ত প্রশ্ন সম্পর্কে।

আপনার পয়েন্টটি প্রতিবার বিভিন্ন স্থানে থামে কারণ আপনি যখন সরিয়ে নিয়েছেন তখন আপনি সীমানা (y> 580) পরীক্ষা করেন না। আপনি কেবল অতীতের 580 এর পরে আরও আপডেট করা বন্ধ করুন।

শেষ ফ্রেমে আপনি 580 অতিক্রম করার আগে আপনি 579 থেকে শুরু হতে পারেন বা আপনি 570 এ হতে পারেন বা আপনি 100 এ হতে পারেন You শেষ ফ্রেমটি কার্যকর হতে কত সময় লেগেছে তার উপর নির্ভর করে আপনি 1 পিক্সেল সামনের বা 1000 করেও এগিয়ে যেতে পারেন।

আপনার আইএফ শর্তটিকে এই জাতীয় কিছুতে পরিবর্তন করুন এবং আপনার ভাল হওয়া উচিত।

if ( y <= 580 )
{
    yVel += DOT_VEL;
    y += (yVel * (SDL_GetTicks() - startTicks)/1000.f);
    if( y > 580 )
    {
        y = 580;
    }
    posRect.y = (int)y;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.