আমি কি এ থেকে বি তে লাফ দিতে পারি?


10

আমি আমার পার্শ্ব-স্ক্রোলারের জন্য কিছু প্রাথমিক এআই তৈরি করছি এবং এআই ইউনিট কেবল একটি লাফিয়ে পয়েন্ট এ থেকে পয়েন্ট বিতে পৌঁছতে পারে কিনা তা আমার জানতে হবে।

আমার চরিত্রগুলির উড়ানের ট্রাজেক্টোরিটি কিছুটা অযৌক্তিক কারণ তারা মধ্য বায়ুতে যেমন বল প্রয়োগ করতে পারে (উদাহরণস্বরূপ জাজ জ্যাক্রাবিট ২-তে), সুতরাং প্রক্ষেপণটির ক্লাসিক ট্র্যাজেক্টোরির বিপরীতে যা ...

একটি নিক্ষিপ্ত বা প্রবর্তিত অভিক্ষিপ্ত পথটি (...) চালক ছাড়াই গ্রহণ করবে।

... আমি মনে করি যে আমার সমস্যাটি প্রপালশন (যেমন রকেট) সহ একটি প্রক্ষিপ্ত সম্পর্কে বেশি ।

এটি চিত্রিত করার জন্য, ফ্লাইটের বক্ররেখাটি আমার চরিত্রের মতো দেখতে যদি আমি ঝাঁপিয়ে পড়ে এবং ক্রমাগত "বাম বোতাম" টিপতে পারি (এটি বাম প্রান্তে অন্যরকম দেখাচ্ছে, এটিই আমি মাঝ বায়ুতে কিছু কৌশল তৈরি করছিলাম): এখানে চিত্র বর্ণনা লিখুন

ফ্লাইট চলাকালীন প্রয়োগ করা বাহিনীটি সর্বদা এক্স অক্ষের সমান্তরাল হয়, সুতরাং যদি আমি "বাম" ধরে রাখি তবে এটি F = (-f, 0) এবং যদি আমি "ডান" ধরে থাকি তবে এটি F = (f, 0) হয়

তিনি স্কি জাম্পারের মতো খুব চলাচল করতে পারেন:

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

সুতরাং এটি ক্লাসিক ট্র্যাজেক্টোরির থেকে অনেকটাই পৃথক, যা কেবল একটি প্যারোবোলার (উত্স: উইকিপিডিয়া ):

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

এটিকে আরও কঠিন করার জন্য, আমি সাধারণ বায়ু প্রতিরোধের অনুকরণ করছি যাতে আমার অক্ষরগুলি কেবল কিছু সর্বাধিক গতির মান পর্যন্ত ত্বরণ করতে পারে।

ভ্রমণের বিপরীত দিকে একটি ছোট শক্তি প্রয়োগ করে এটি করা হয় :

b2Vec2 vel = body->GetLinearVelocity();
float speed = vel.Normalize(); //normalizes vector and returns length
body->ApplyForce( AIR_RESISTANCE_MULT * speed * speed * -vel, body->GetWorldCenter() );

এআইআরআরএসআইএসএনটিএনসিসিএমএলটিটি একটি ধ্রুবক যা আমার ক্ষেত্রে 0.1 এর সমান।

আসুন ধরে নেওয়া যাক আমার চরিত্রটি অসীম একটি ছোট পয়েন্ট।

এবং আমি বাধাগুলি বিবেচনায় নিচ্ছি না , তাই আমার প্রশ্নটি এরকম হয় ...

কীভাবে নির্ধারণ করতে হবে (কমপক্ষে নির্ভরযোগ্যভাবে অনুমান), প্রাথমিক বেগ V দেওয়া হয়েছে, একটি প্রেরণ জে = (0, -j) যা আমি লাফের উপরে চরিত্রের জন্য প্রয়োগ করি, মাধ্যাকর্ষণ জি = (0, জি) , জোর করে F = (+ -f) , 0) ক্রমাগত ফ্লাইটের সময় প্রয়োগ করা হয় এবং এআইআরএআরএসআইএসটিএনএসএমএমএলটি যদি আমরা সত্যিকার অর্থে বায়ু প্রতিরোধের বিষয়টি বিবেচনায় নেওয়ার সিদ্ধান্ত নিই (এটি alচ্ছিক ) , আমার চরিত্রটি যে পথটি আঁকবে তার আঁকানো নীচের কোন বিন্দুটি কিনা?

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

সম্পাদনা: জেসনের পরামর্শ অনুসারে আমি সিমুলেশনটি ব্যবহার করে এটি সমাধান করার সিদ্ধান্ত নিয়েছি, তবে কীভাবে এই ধরনের কেস পরিচালনা করবেন? এখানে চিত্র বর্ণনা লিখুন

আমার কি সি থেকে ডি তে একটি বিভাগ অঙ্কন করা উচিত এবং পছন্দসই পয়েন্টটি এই বিভাগের নীচে রয়েছে কিনা তা পরীক্ষা করা উচিত?

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


আমি মনে করি যে মামলার বায়ু প্রতিরোধের বিষয়টি আমরা বিবেচনা করি না এমন মামলার একটি সমাধান আমি পেয়েছি: গেমদেব.স্ট্যাকেক্সেঞ্জার
প্রশ্নস /

উত্তর:


4

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

সম্পাদনা: তুলনা সম্পর্কে আরও কিছু বিশদ। আপনি জানেন যে টাইমস্টেপ ধরে (যা গেমের ফ্রেমে অনেকগুলি হতে পারে), প্লেয়ার লক্ষ্যটি অতিক্রম করে <targetx,targety>। তাদের পথটি অবস্থান দ্বারা বর্ণিত <ax*t^2 + bx*t + cx, ay*t^2 + by*t + cy>যেখানে:

ax = 1/2 * accel.x
bx = velocity.x
cx = position.x

tটাইমস্টেপ ( 0 <= t <= dt) এর মাধ্যমে সময় এবং একইভাবে y। সুতরাং t=0চরিত্রটি যখন পূর্বের অবস্থানে থাকে এবং কখন t=dt, তারা পরবর্তী অবস্থানে থাকে। নোট করুন যে এটি মূলত ইউলারের আপডেট এর dtপরিবর্তে রয়েছে tযাতে আমরা ট্রাজেক্টোরির পাশাপাশি যে কোনও জায়গায় গণনা করতে পারি। এখন আমরা জানি যে এক্স-পজিশনটি একটি চতুষ্কোণ ফাংশন, তাই চরিত্রটি সরাসরি লক্ষ্যের উপরে বা নীচে যে ধাপে আমরা সেই পদক্ষেপের সময় দু'বার সমাধান করতে ax*t^2 + bx*t + cx = targetxএবং (পেতে) পেতে পারি । তারপরে আমরা এমন কোনও সমাধান বের করি যা সীমাতে নেই [0,dt], কারণ এটি বর্তমান টাইমস্টেপটিতে নেই। (দৃ rob়তার জন্য, ব্যাপ্তির শেষ প্রান্তে একটি ছোট ধ্রুবক যুক্ত করুন যাতে আপনার কোনও সমস্যা না হয়)। এখন আমাদের কোনও সমাধান (ফিল্টারিংয়ের পরে) থাকতে পারে না, সেক্ষেত্রে আমরা এই টাইমস্টেপটিকে লক্ষ্যবস্তুতে আঘাত করি না। অন্যথায়, আমরা ay*t^2 + by*t + cyসমাধানগুলি মূল্যায়ন করি এবং এই y এর সাথে তুলনা করি targety। নোট করুন যে আপনি আপনার ট্র্যাজেক্টোরির এক পর্যায়ে লক্ষ্যের ওপরে হতে পারেন এবং এর নিচে পরে (বা তদ্বিপরীত)। আপনি যা করতে চান সেই অনুসারে আপনাকে এ জাতীয় পরিস্থিতিতে ব্যাখ্যা করতে হবে।

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

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

চরিত্রটি তাদের লাফ দিয়ে পার্টওয়ে বাড়াতে বন্ধ করে দেয় বা অন্যভাবে উত্সাহ দেওয়া শুরু করলে কী ঘটে তা আপনি অনুকরণ করতে পারেন। উপরের কৌশলটির সাথে জটিলতাটি হ'ল ((লগ টি) ^ 2), যা খুব খারাপ নয়।


+1, দুর্দান্ত উত্তর! আমি কীভাবে আসল সিমুলেশনটি বিবেচনা করতে পারি না। আপনি কি দয়া করে "প্যারাবোলিক আনুমানিকতা" (আমি যথেষ্ট বুঝতে পারছি না) এর বিস্তারিত বর্ণনা করতে পারেন? আপনি কি কেবল গতিবেগকে সংহত করার পদ্ধতিটি বোঝাতে চাইছেন, যেমন যেমন আরকে 4 এবং ইউলার? যদি তা হয় তবে আপনি কী এটি ব্যাখ্যা করতে পারেন বা এটি সম্পাদন করার জন্য কিছু তথ্যের লিঙ্ক দিতে পারেন?
প্যাট্রিক সিজাচুরস্কি

1
সাধারণত আপনি করেন x'= x + v*dt। পরিবর্তে ব্যবহার x' = x + v*dt + 1/2*a*dt*dt। যখন dtছোট হয়, dt^2ছোট হয়, তাই সাধারণত এটি গেমগুলির মধ্যে traditionalতিহ্যবাহী অয়লার একীকরণে বাদ যায়। এখানে dtছোট নয়, সুতরাং আপনার ত্বরণের শব্দটি প্রয়োজন। যেহেতু dtদ্বিতীয় শক্তিতে উত্থাপিত হয়, এটি চতুর্ভুজীয় একীকরণ এবং পথটি একটি পরকীয়া, সুতরাং প্যারাবোলিক আনুমানিক। আর কে 4 মূলত উচ্চতর ডেরাইভেটিভগুলি গণনা করে এবং তাই কিউবিক, কোয়ার্টিক, কুইন্টিক ইত্যাদি আনুমানিক রূপ দিতে পারে। আর কে 4 এটির জন্য ওভারকিল, সম্ভবত স্থিতিশীলতা গুরুত্বপূর্ণ নয়।

এবং আমি মনে করি গতিবেগটি কি traditionalতিহ্যবাহী ইউলারের মতো সংহত করা উচিত? v' = v + a*dt
প্যাট্রিক সিজাচুরস্কি

1
হাঁ। আপনার কোনও জট নেই, আপনি এটি শূন্য বলে ধরে নিচ্ছেন।

সম্পাদনাটি একবার দেখুন।
প্যাট্রিক জাজাচুরস্কি

4

হ্যাঁ! আমি এটা করেছি!

আমি সাধারণ সিমুলেশন ব্যবহার করছি যা লক্ষ্য পয়েন্টের উল্লম্ব অক্ষের পিছনে প্রথম অবস্থান নেয় - সেখান থেকে আমি পূর্ববর্তী সিমুলেটেড অবস্থান নিয়ে একটি বিভাগ তৈরি করি। এখন আমি লক্ষ্য করি যে লক্ষ্য বিন্দুটি এই বিভাগের নীচে রয়েছে কিনা। যদি তা হয় - তবে আমরা সেখানে লাফিয়ে উঠতে পারি।

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

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

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

আসল সমস্যাটি সমাধান করার জন্য লুয়ায় সম্পূর্ণ কোডটি এখানে রয়েছে (কোডটি ধরে নিয়েছে যে আপনার নিজের "ডিবাগ_ড্রইউ" রুটিন এবং আপনার নিজস্ব ভেক্টর শ্রেণি যেমন "দৈর্ঘ্য_এসকিউ" (দৈর্ঘ্যের স্কোয়ার্ড), "স্বাভাবিককরণ" বা অপারেটর +, * :

function simple_integration(p, dt)
    local new_p = {}

    new_p.acc = p.acc
    new_p.vel = p.vel + p.acc * dt 
    new_p.pos = p.pos + new_p.vel * dt
    -- uncomment this if you want to use quadratic integration
    -- but with small timesteps even this is an overkill since Box2D itself uses traditional Euler
    -- and I found that for calculations to be accurate I either way must keep the timesteps very low at the beginning of the jump
     --+ p.acc * dt * dt * 0.5

    return new_p
end

function point_below_segment(a, b, p)
    -- make sure a is to the left
    if a.x > b.x then a,b = b,a end

    return ((b.x - a.x)*(p.y - a.y) - (b.y - a.y)*(p.x - a.x)) < 0
end

-- returns true or false
function can_point_be_reached_by_jump
(
gravity, -- vector (meters per seconds^2)
movement_force, -- vector (meters per seconds^2)
air_resistance_mult, -- scalar
queried_point, -- vector (meters)
starting_position, -- vector (meters)
starting_velocity, -- vector (meters per seconds)
jump_impulse, -- vector (meters per seconds)
mass -- scalar (kilogrammes)
)

    local my_point = {
        pos = starting_position,
        vel = starting_velocity + jump_impulse/mass
    }

    local direction_left = movement_force.x < 0
    local step = 1/60

    while true do           
        -- calculate resultant force
        my_point.acc = 
        -- air resistance (multiplier * squared length of the velocity * opposite normalized velocity)
        (vec2(my_point.vel):normalize() * -1 * air_resistance_mult * my_point.vel:length_sq()) / mass
        -- remaining forces
        + gravity + movement_force/mass

        -- I discard any timestep optimizations at the moment as they are very context specific
        local new_p = simple_integration(my_point, step)

        debug_draw(my_point.pos, new_p.pos, 255, 0, 255, 255)
        debug_draw(new_p.pos, new_p.pos+vec2(0, -1), 255, 255, 0, 255)

        if (direction_left and new_p.pos.x < queried_point.x) or (not direction_left and new_p.pos.x > queried_point.x) then
            if point_below_segment(new_p.pos, my_point.pos, queried_point) then
                debug_draw(new_p.pos, my_point.pos, 255, 0, 0, 255)
                return true
            else
                debug_draw(new_p.pos, my_point.pos, 255, 255, 255, 255)
                return false
            end
        else 
            my_point = new_p
        end
    end

    return false
end

আমাকে সঠিক দিকটিতে স্থাপনের জন্য জেসনকে গ্রহণ করুন! ধন্যবাদ!


2

আপনি উত্তরটি "কেবল গণনা" করতে চাইতে পারেন তবে আমি নিশ্চিত যে আপনার "ফ্রি ফ্যাল" পদার্থবিজ্ঞানের অত্যন্ত ইন্টারেক্টিভ প্রকৃতির কারণে আপনি এটিটি একবার অপর্যাপ্ত পেয়ে যাবেন।

একটি ভিন্ন পদ্ধতির ব্যবহার বিবেচনা করুন: অনুসন্ধান করা। এটি সুপার মারিও এআই এর জন্য কীভাবে সম্পন্ন হয়েছে তা এখানে রয়েছে: http://aigamedev.com/open/interview/mario-ai/

এ থেকে বি তে যাওয়ার সম্ভাব্য প্যাচগুলি অনুসন্ধানের মাধ্যমে মিড-এয়ারে সীমাহীন ইন্টারঅ্যাক্টিভিটির অনুমতি পাওয়া যায় যদিও এখনও কম্পিউটেশনাল দক্ষ।


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