2 ডি আইসোমেট্রিক: স্ক্রিন টালি স্থানাঙ্ক


9

আমি একটি আইসোমেট্রিক 2 ডি গেম লিখছি এবং কার্সারটি কোন টাইলের উপর নির্ভর করে তা নির্ধারণ করতে আমার অসুবিধা হচ্ছে। এখানে একটি অঙ্কন:

যেখানে x এবং ys হ'ল স্ক্রিন স্থানাঙ্ক (পিক্সেল), xt এবং yt হ'ল টাইল স্থানাঙ্ক, ডাব্লু এবং এইচ হ'ল টাইলের প্রস্থ এবং টাইলের উচ্চতা যথাক্রমে ix স্থানাঙ্কগুলির জন্য আমার স্বরলিপিটি হ'ল (y, x) যা বিভ্রান্তিকর হতে পারে, এটির জন্য দুঃখিত।

আমি এখন অবধি সবচেয়ে ভাল খুঁজে পেতে পারি এটি হ'ল:

int xtemp = xs / (W / 2);
int ytemp = ys / (H / 2);
int xt = (xs - ys) / 2;
int yt = ytemp + xt;

এটি প্রায় সঠিক বলে মনে হচ্ছে তবে নির্দিষ্ট টাইলস নির্বাচন করা কঠিন করে তোলে বা কখনও কখনও এটি ক্লিক করার চেষ্টা করছি তার পাশে একটি টাইল নির্বাচন করে me আমি বুঝতে পারি না কেন এবং আমি চাই যদি কেউ এর পিছনে যুক্তি বুঝতে আমাকে সহায়তা করতে পারে।

ধন্যবাদ!

উত্তর:


2

সঠিক পরিমাপের জন্য, আমরা নিম্নলিখিতগুলি বিবেচনা করতে পারি:

প্রথমে আইসোমেট্রিক স্পেস থেকে স্থানাঙ্ককে কীভাবে আই ও জে ভেক্টর দ্বারা নির্ধারিত করা হয় (আইসোমেট্রিকম্যাপ [i, j] হিসাবে) বা স্ক্রিনের এক্স এবং ওয়াই দ্বারা নির্ধারিত স্ক্রিনে yt এবং axt রূপে কীভাবে রূপান্তর করা যায় তা বিবেচনা করা যাক। আসুন ধরে নেওয়া যাক আপনার পর্দার স্থানটি সরলতার স্বার্থে আইসোমেট্রিক স্পেসের সাথে উত্স অনুসারে সংযুক্ত করা হয়েছে।

রূপান্তরটি করার একটি উপায় হ'ল প্রথমে ঘোরানো, তারপরে y বা x- অক্ষটি স্কেল করুন scale আপনার yt এবং xxt এর সাথে মেলে প্রয়োজনীয় মানগুলি পাওয়ার জন্য আমি এখানে স্পটটিতে বেশিরভাগই আসতে পারি না। আপনি এটি করতে বা না করার জন্য একটি ম্যাট্রিক্স তৈরি করতে পারেন এবং তারপরে বিপরীত ম্যাট্রিক্স ব্যবহার করতে পারেন, তবে বিপরীত ক্রিয়াকলাপটি মূলত আপনি যা চান তা তাই।

বিপরীতে মানটি স্কেল করুন এবং তারপরে মানগুলি পেতে এবং নীচের দিকে গোল করে পিছনের দিকে ঘোরান।

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


আহা। আমি এই পোস্টটি বহুবার সংশোধন করেছি এবং আমি মনে করি যে আমি যাই হোক আমার পছন্দ মতো সুন্দরভাবে আমার বক্তব্যটি পেতে পারি না। আমার ঘুম দরকার.
টনি

1
ধন্যবাদ, ম্যাট্রিকগুলি অবশ্যই এখানে সেরা সমাধান। আমার এখন প্রায় কাজ করছে!
আসিক

4

আমি যে গেমটি লিখছিলাম তার জন্য আমার একই সমস্যা ছিল। আমি ধারণা করি যে আপনি ঠিক কীভাবে আইসোমেট্রিক সিস্টেম প্রয়োগ করেছেন তার উপর ভিত্তি করে এই সমস্যাটি আলাদা হবে, তবে আমি কীভাবে সমস্যার সমাধান করেছি তা ব্যাখ্যা করব।

আমি প্রথম আমার টাইল_ টু_স্ক্রিন ফাংশন দিয়ে শুরু করেছি। (আমি ধরে নিলাম যে আপনি প্রথম স্থানে টাইলসটি ঠিক জায়গায় রাখছেন)) এই ফাংশনে স্ক্রিন_এক্স এবং স্ক্রিন_ই গণনা করার একটি সমীকরণ রয়েছে। আমার দেখতে দেখতে (অজগর):

def map_to_screen(self, point):
    x = (SCREEN_WIDTH + (point.y - point.x) * TILE_WIDTH) / 2
    y = (SCREEN_HEIGHT + (point.y + point.x) * TILE_HEIGHT) / 2
    return (x, y)

আমি এই দুটি সমীকরণ নিয়েছি এবং এগুলিকে রৈখিক সমীকরণের ব্যবস্থায় পরিণত করেছি। আপনি যে কোনও পদ্ধতিতে এই সমীকরণের সিস্টেমটি সমাধান করুন। (আমি একটি rref পদ্ধতি ব্যবহার করেছি। এছাড়াও, কিছু গ্রাফিং ক্যালকুলেটরগুলি এই সমস্যাটি সমাধান করতে পারে))

চূড়ান্ত সমীকরণগুলি এর মতো দেখায়:

# constants for quick calculating (only process once)
DOUBLED_TILE_AREA = 2 * TILE_HEIGHT * TILE_WIDTH
S2M_CONST_X = -SCREEN_HEIGHT * TILE_WIDTH + SCREEN_WIDTH * TILE_HEIGHT
S2M_CONST_Y = -SCREEN_HEIGHT * TILE_WIDTH - SCREEN_WIDTH * TILE_HEIGHT

def screen_to_map(self, point):
    # the "+ TILE_HEIGHT/2" adjusts for the render offset since I
    # anchor my sprites from the center of the tile
    point = (point.x * TILE_HEIGHT, (point.y + TILE_HEIGHT/2) * TILE_WIDTH)
    x = (2 * (point.y - point.x) + self.S2M_CONST_X) / self.DOUBLED_TILE_AREA
    y = (2 * (point.x + point.y) + self.S2M_CONST_Y) / self.DOUBLED_TILE_AREA
    return (x, y)

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

হালনাগাদ

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

# constants for quickly calculating screen_to_iso
TILE_AREA = TILE_HEIGHT * TILE_WIDTH
S2I_CONST_X = -SCREEN_CENTER.y * TILE_WIDTH + SCREEN_CENTER.x * TILE_HEIGHT
S2I_CONST_Y = -SCREEN_CENTER.y * TILE_WIDTH - SCREEN_CENTER.x * TILE_HEIGHT

def screen_to_iso(p):
    ''' Converts a screen point (px) into a level point (tile) '''
    # the "y + TILE_HEIGHT/2" is because we anchor tiles by center, not bottom
    p = Point(p.x * TILE_HEIGHT, (p.y + TILE_HEIGHT/2) * TILE_WIDTH)
    return Point(int((p.y - p.x + S2I_CONST_X) / TILE_AREA),
                 int((p.y + p.x + S2I_CONST_Y) / TILE_AREA))

def iso_to_screen(p):
    ''' Converts a level point (tile) into a screen point (px) '''
    return SCREEN_CENTER + Point((p.y - p.x) * TILE_WIDTH / 2,
                                 (p.y + p.x) * TILE_HEIGHT / 2)

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

2

আপনি একটি ভাল সমন্বয় ব্যবস্থা ব্যবহার করছেন। আপনি স্তম্ভিত কলামগুলি ব্যবহার করেন তবে জিনিসগুলি আরও জটিল হয়ে উঠবে।

এই সমস্যাটি সম্পর্কে ভাবার একটি উপায় হ'ল আপনার (xt, yt) (xs, ys) তে পরিণত করার একটি ফাংশন রয়েছে। আমি থানির উত্তর অনুসরণ করব এবং এটি কল করব map_to_screen

আপনি এই ফাংশনটির বিপরীতমুখী চান । আমরা এটি কল করতে পারেন screen_to_map। ফাংশন বিপরীতে এই বৈশিষ্ট্যগুলি রয়েছে:

map_to_screen(screen_to_map(xs, ys)) == (xs, ys)
screen_to_map(map_to_screen(xt, yt)) == (xt, yt)

আপনার দুটি ফাংশন লেখা হয়ে গেলে সেই দুটি ইউনিট পরীক্ষার জন্য ভাল জিনিস। বিপরীতটি কীভাবে লিখবেন? সমস্ত ফাংশন বিপরীত না কিন্তু এই ক্ষেত্রে:

  1. যদি আপনি এটিকে কোনও রোটেশন পরে কোনও অনুবাদ অনুসরণ করে লিখে থাকেন তবে বিপরীতটি হ'ল বিপরীত অনুবাদ (নেতিবাচক ডেক্স, ডাই) এর পরে বিপরীত রোটেশন (নেতিবাচক কোণ)।
  2. আপনি যদি এটি ম্যাট্রিক্স গুণিত হিসাবে লিখে থাকেন তবে বিপরীতটি হল ম্যাট্রিক্স বিপরীতমুখী গুণ।
  3. যদি আপনি এটিকে (xxt, yt) পদে (xs, ys) সংজ্ঞায়িত বীজগণিত সমীকরণ হিসাবে লিখেন, তবে প্রদত্ত (xs, ys) এর জন্য সমীকরণগুলি সমাধান করে বিপরীতটি পাওয়া যায়।

নিশ্চিত হয়ে নিন যে বিপরীত + মূল ফাংশনটি আপনি যে উত্তর দিয়ে শুরু করেছিলেন তা ফিরে দেয়। থানার উভয় পরীক্ষা পাস করে, যদি আপনি + TILE_HEIGHT/2অফারটি অফার করেন। আমি যখন বীজগণিত সমাধান করলাম তখন আমি এনেছি:

x = (2*xs - SCREEN_WIDTH) / TILE_WIDTH
y = (2*ys - SCREEN_HEIGHT) / TILE_HEIGHT
yt =  (y + x) / 2
xt =  (y - x) / 2

যা আমি বিশ্বাস করি থানার মতোই screen_to_map

ফাংশন মাউস স্থানাঙ্ককে ফ্লোটে পরিণত করবে; floorতাদের পূর্ণসংখ্যা টাইল স্থানাঙ্কে রূপান্তর করতে ব্যবহার করুন।


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