ঘোস্ট রিপ্লে - স্টোরেজ এবং সময়


11

আমি একটি গাড়ী রেস গেমের সাথে কাজ করছি এবং অতীত দৌড়গুলির পুনরায় খেলানোর জন্য একটি ভুত স্প্রিট প্রয়োগ করেছি। আমি একটি পদার্থবিজ্ঞানের ইঞ্জিন ব্যবহার করেছি এবং অনেকগুলি পড়ার পরে আমি এই সিদ্ধান্তে পৌঁছেছি যে রিপ্লেয়ের জন্য ভূতের ডেটা সংরক্ষণ করার সর্বোত্তম উপায়টি নির্দিষ্ট সময়সীমার উপর গাড়ীটির অবস্থান এবং ঘূর্ণন রেকর্ড করা, যেমন এখানে বর্ণিত: https: // গেমদেব। stackexchange.com/a/8380/26261

তবে রিপ্লে চলাকালীন সেই টাইমপয়েন্টগুলি খুঁজে পাওয়ার ভাল উপায় কী হবে? একটি উদাহরণ এই ডেটা সহ একটি রেকর্ড হতে পারে:

time: +3.19932 (seconds since race start)
position:  180,40 (position at that time)
rotation: 30.4 (rotation at that time)

তবে এতে আমার বেশ কয়েকটি সমস্যা রয়েছে:

  1. আমি যখন পুনরায় খেলি, তখন আমি আবার যথাক্রমে ৩.১৯ 32 at২-তে পৌঁছানোর সম্ভাবনা কম - সম্ভবত, আমার সময়সীমার ৩.১-এর কাছাকাছি থাকতে হবে এবং সবচেয়ে কাছের মিলের রেকর্ডটি খুঁজে পেতে হবে। ইন্টারপোলটিং করার সময় এমনকি উপরে এবং নীচের নিকটতম মিলও। এটি খুব অদক্ষ এবং সময় সাশ্রয়ী মনে হচ্ছে?

  2. কোন তালিকা কাঠামোতে আমি এই পুনর্বিবেচনার জন্য এই রেকর্ডগুলি সঞ্চয় করতে পারি? একটি অ্যারের? তার মানে কি এই নয় যে একটি নির্দিষ্ট সময়ের সাথে মিলে যাওয়া রেকর্ডগুলির জন্য অনুসন্ধানের সময়টি আরও দীর্ঘতর হবে?

  3. টাইমপয়েন্টগুলির জন্য আমার কোন ফ্রিকোয়েন্সি ব্যবহার করা উচিত? প্রতিটি ফ্রেম -আমি অনুমান-ওভারকিল হবে, বরং আমার অর্থাত্ প্রতিটি নবম ফ্রেম সংরক্ষণ করা উচিত এবং এর মধ্যে ফাঁক দেওয়া উচিত, যা স্টোরেজ প্রশ্নগুলিকে ২. আরও জটিল করে তোলে।

তাহলে এই ধারণাটি কি সঠিক পদ্ধতির? যদি হ্যাঁ, আমি কীভাবে দক্ষতার সাথে ডেটা সঞ্চয় এবং পুনরুদ্ধার করতে পারি? দয়া করে নোট করুন যে আমি সাধারণত উপরের ডেটা স্ট্রাকচারটি ব্যবহার করে যেতে চাই, ডিস্ট্রিমেন্টিক গেমস্টেটগুলি এবং রেকর্ডিং ব্যবহারকারী ইনপুট ইত্যাদি নয় etc.

কোন সাহায্যের জন্য ধন্যবাদ!

সম্পাদনা: আমি বুঝতে পারি যে আমি যে পরিবেশটি ব্যবহার করছি তা বর্ণনা করা উচিত: আইফোনের জন্য কোকোস 2 ডি। একটি পদ্ধতি আছে update:(ccTime)delta। আদর্শভাবে, এই পদ্ধতিটি প্রতি 1/60 সেকেন্ডে কল করা হবে, তবে এর কোনও গ্যারান্টি নেই - deltaশেষ গেমটিকের পরে আসল সময়টি কি 1/1 এর চেয়ে অনেক বেশি বা কম হতে পারে। এটি এই পদ্ধতিতে যেখানে আমি বর্তমান গেমস্টেটটি সঞ্চয় করতে চাই।


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

উত্তর:


8

তার মানে কি এই নয় যে একটি নির্দিষ্ট সময়ের সাথে মিলে যাওয়া রেকর্ডগুলির জন্য অনুসন্ধানের সময়টি আরও দীর্ঘতর হবে?

নাহ :)

বলুন আপনি এটিকে অ্যারে হিসাবে সঞ্চয় করেছেন (স্নাপশটগুলি কালানুক্রমিক ক্রমে রয়েছে তবে সমানভাবে ব্যবধানযুক্ত নয়):

snapshots = [
    {time: 0.0, position: {x,y,z}},
    {time: 0.41,    position: {x,y,z}},
    {time: 0.57,    position: {x,y,z}},
    {time: 1.10,    position: {x,y,z}},
    {time: 1.67,    position: {x,y,z}},
    {time: 2.05,    position: {x,y,z}},
    {time: 3.24,    position: {x,y,z}},
    {time: 3.86,    position: {x,y,z}},
    {time: 3.91,    position: {x,y,z}},
    {time: 5.42,    position: {x,y,z}},
    ...]

তারপরে, যখন রিপ্লে / গেম শুরু হবে, আপনি অ্যারে থেকে প্রথম এবং দ্বিতীয় উপাদানটি পাবেন:

nextIdx = 1
previousSnapshot = snapshots[nextIdx-1]
nextSnapshot = snapshots[nextIdx]

তারপরে প্রতিটি ফ্রেমে ( currentTimeএই নতুন গেমের বর্তমান সময়):

if currentTime > nextSnapshot.time
    nextIdx++
    previousSnapshot = snapshots[nextIdx-1]
    nextSnapshot = snapshots[nextIdx]

# Do your magic here, e.g.:
snapshotPairGap = nextSnapshot.time - previousSnapshot.time
ratio = (currentTime - previousSnapshot.time) / snapshotPairGap
ghostPosition = {
    x: previousSnapshot.position.x + ratio*(nextSnapshot.position.x - previousSnapshot.position.x)
    y: previousSnapshot.position.y + ratio*(nextSnapshot.position.y - previousSnapshot.position.y)
    z: previousSnapshot.position.z + ratio*(nextSnapshot.position.z - previousSnapshot.position.z)
}

অবশ্যই এটি গণনার কয়েকটি ক্যাশে করে অনুকূলিত করা যেতে পারে। অ্যারের মাধ্যমে কোনও অনুসন্ধান নেই, কেবল নির্দিষ্ট সূচকগুলি সন্ধান করছি।


হ্যাঁ! আমাকে এটি পরে চেষ্টা করে দেখতে হবে, তবে এটি যা খুঁজছিলাম তা মনে হয়। ধন্যবাদ !!
মারিম্বা

15

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

N | Time | Position | Rotation
1 | 0.05 | 1, 1, 1  | 0
2 | 0.15 | 1, 2, 1  | 0
3 | 0.25 | 1, 3, 2  | 30

এখন কল্পনা করুন আপনি 0.10 সময় অবস্থান এবং আবর্তন পেতে চান। যেহেতু 0.10 পয়েন্ট '1' (যার অর্থ 0.05 সময়) এবং '2' (অর্থ 0.15 সময়) এর মধ্যে রয়েছে, আপনাকে এগুলি বিভক্ত করতে হবে।

timestamp = 0.10
factor = (timestamp - Time[1]) / (Time[2] - Time[1])
position = Lerp(Position[1], Position[2], factor)
rotation = Lerp(Rotation[1], Rotation[2], factor)

Lerpকেবল লিনিয়ার ইন্টারপোলেশন

সুতরাং আসুন শূন্যস্থানগুলি কয়েকটি উদাহরণ (*) দিয়ে পূরণ করুন।

N | Time  | Position    | Rotation
1 | 0.05  | 1, 1,    1  | 0
* | 0.075 | 1, 1.25, 1  | 0
* | 0.10  | 1, 1.5,  1  | 0
2 | 0.15  | 1, 2,    1  | 0
* | 0.20  | 1, 2.5,  2  | 15
3 | 0.25  | 1, 3,    2  | 30

আছে HTH।


5
+1 টি। অন্তরঙ্গকরণ এখানে সহজ এবং কার্যকর উত্তর। এটি সত্য হতে পারে যে ঘন ঘূর্ণন যখন গাড়িটি ঘুরছে তখন কিছুটা ভাল ফলাফল দিতে পারে তবে অন্তরগুলি পর্যাপ্ত পরিমাণে কম থাকলে লিনিয়ার ভালভাবে কাজ করবে।
কাইলোটান

কিভাবে বিভক্ত করতে দেখানোর জন্য ধন্যবাদ! এটি আমার গেমের জন্য খুব কার্যকর হবে। তবে আসুন আমরা অ্যারের অভ্যন্তরে 41.15 সময়ে পুনরুদ্ধার করতে চাই। আপনি কোনও রেকর্ড> 41.15 না পাওয়া পর্যন্ত পুরো অ্যারেটি অনুসন্ধান শুরু করবেন?
মারিম্বা

1
একটি সরল রৈখিক অনুসন্ধান আপনার জন্য কাজ পারে, কিন্তু বাইনারি অনুসন্ধান, উত্তম আপনি একটি সাজানো অ্যারে আছে যখন: en.wikipedia.org/wiki/Binary_search_algorithm
মার্সিন Seredynski
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.