অন্যের অফসেটের উপর ভিত্তি করে আমি কোনও বস্তুকে কীভাবে ঘোরান?


25

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

নিম্নলিখিত চিত্রটি আমার সমস্যার চিত্র তুলে ধরে:এখানে চিত্র বর্ণনা লিখুন

আমার কাছে যদি বুড়িটি "লুকআউট ()" লক্ষ্য থাকে, তোপ থেকে উত্পন্ন একটি লেজারটি লক্ষ্যযুক্ত লক্ষ্যটিকে পুরোপুরি মিস করবে।

যদি এটি পুরোপুরি শীর্ষ-ডাউন দর্শন হয়, এবং কামানটি পুরো বার্জটির সমান্তরাল ছিল, তবে আমার যুক্তিটি আমাকে বলে যে জাল লক্ষ্যটি এমন অবস্থানে অবস্থিত হওয়া উচিত যা আসল টার্গেটের সমান এবং একটি অফসেট যা এর মধ্যে সমান হয় বুড়ি এবং কামান। তবে, আমার আসল দৃশ্যে, আমার ক্যামেরাটি 60º কোণে রয়েছে এবং কামানের সামান্য ঘূর্ণন রয়েছে।

নিম্নলিখিত চিত্রটি চিত্রটির বর্ণনা দেয়: ইলাস্টেটিভ সিনারিও

আমি ঠিক ঠিক কেন তা নিশ্চিত নই, তবে আমি যদি একই অফসেটটি প্রয়োগ করি তবে এটি কেবল বুধ থেকে কিছু দূরত্ব নির্ধারণের সময় কাজ করছে বলে মনে হচ্ছে।

আমার যুক্তি ত্রুটিযুক্ত? আমি কি এখানে মৌলিক কিছু মিস করছি?

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


অস্ত্রের নকশার দৃষ্টিকোণ থেকে, আপনি কেবল আপনার বন্দুক ঠিক করতে পারেন ;)
ওয়েইন ওয়ার্নার

@ ওয়াইনওয়ার্নার এটি আমার ক্ষেত্রে কোনও বিকল্প নয়। এটি আঁকাবাঁকা, তবে কার্যকরী হওয়ার জন্য এটি একটি নকশা পছন্দ।
ফ্রান্সসটাইন

1
আমি আমার উত্তরে একটি কাজের উদাহরণ যুক্ত করেছি ।
ইত্যাদি

উত্তরগুলি নিখুঁত বলে মনে হচ্ছে ... আপনি ঠিক কী কী বিবরণ প্রয়োজন তা উল্লেখ করতে পারেন?
সৈয়দ মুর্তেজা কমালি

উত্তর:


31

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

পদক্ষেপ 1 - বদ্ধ লাইন (ভি) এবং বন্দুকের লাইন (ডাব্লু) এর মধ্যে দূরত্ব পান যা ওয়াই (এটি ধ্রুবক তবে গণনায় আঘাত দেয় না)। টারেট থেকে লক্ষ্য পর্যন্ত দূরত্ব পান (যা এক্স)।

পদক্ষেপ 2 - এক্স দ্বারা Y কে ভাগ করুন এবং তারপরে মানটির হাইপারবোলিক সাইন পান

double turnRadians = Mathf.Asin(Y/X);
double angle = Mathf.Rad2Deg * turnRadians;

//where B is the red dot, A is a point on the X line and C is a point on the Z line.

পদক্ষেপ 3 - আরও অনেক বেশি বারটিকে ঘুরিয়ে দিন (অক্ষের চারপাশে এটি শীর্ষ থেকে নীচে চলে যায়, সম্ভবত অক্ষটি আপ হয় তবে কেবল আপনি সেই অংশটি জানতে পারবেন)।

gameObject.transform.Rotate(Vector3.up, turnAngle);

অবশ্যই এক্ষেত্রে আপনার এটিকে ঘড়ির কাঁটার বিপরীতে ঘুরিয়ে দেওয়ার প্রয়োজন হয় যাতে আপনি সেখানে যেমন বাঁকটি আঙ্গুলের সামনে একটি বিয়োগ যোগ করতে পারেন -turnAngle

কিছু অংশ সম্পাদনা করেছেন। দূরত্বের পার্থক্যটি নির্দেশ করার জন্য @ জেনসকে ধন্যবাদ।

ওপি জানিয়েছে যে তার বন্দুকটির একটি কোণ রয়েছে তাই আমরা এখানে যাই, চিত্রটি আগে, পরে ব্যাখ্যা: এখানে চিত্র বর্ণনা লিখুন

আমরা আগের গণনা থেকে ইতিমধ্যে জানি যেখানে নীল রেখা অনুযায়ী লাল রেখাকে লক্ষ্য করা যায়। তাই প্রথমে নীল রেখার লক্ষ্যে:

float turnAngle = angleBetweenTurretAndTarget - angleBetweenTurretAndGun;
turret.transform.Rotate(Vector3.up, turnAngle);

এখানে কেবলমাত্র গণনাটি পৃথক হয়েছে, "এক্স প্রাইম" (এক্স ') এর গণনা কারণ বন্দুক এবং বুড়ি (কোণ "ক") এর মধ্যবর্তী কোণটি রেখার মধ্যবর্তী দূরত্বকে পরিবর্তন করেছিল।

//(this part had a mistake of using previous code inside new variable names, YPrime and Y are shown as X' and X in the 2nd picture.
float YPrime = Cos(a)*Y; //this part is what @ens is doing in his answer
double turnRadians = Mathf.Asin(YPrime/X);
double angle = Mathf.Rad2Deg * turnRadians;
turret.transform.Rotate(Vector3.up, angle);

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

"ক" কোণটি আবিষ্কার করার জন্য দুটি পদ্ধতি রয়েছে, একটি হ'ল ট্রান্সফর্ম.আপ পদ্ধতি:

float angleBetween = Vector3.Angle(turret.transform.up, gun.transform.up);

উপরের কৌশলটি 3 ডি তে গণনা করবে, সুতরাং আপনি যদি 2 ডি ফলাফল চান তবে আপনাকে জেড অক্ষ থেকে মুক্তি দিতে হবে (এটি আমি গ্রাভিটি যেখানে ধরে নিয়েছি তা অনুমান করে তবে আপনি যদি কিছুই পরিবর্তন করেন না, ইউনিটিতে এটি Y অক্ষ, যা উপরে বা নীচে রয়েছে, অর্থাত্ মাধ্যাকর্ষণটি Y অক্ষরেখার উপর রয়েছে, সুতরাং আপনাকে জিনিসগুলি পরিবর্তন করতে হতে পারে):

Vector2 turretVector = new Vector2(turret.transform.up.x, turret.transform.up.y);
Vector2 gunVector = new Vector2(gun.transform.up.x, gun.transform.up.y);
float angleBetween = Vector2.Angle(turretVector, gunVector);

দ্বিতীয় উপায় হ'ল ঘূর্ণন পদ্ধতি (আমি এই ক্ষেত্রে 2 ডি তে ভাবছি):

double angleRadians = Mathf.Asin(turret.transform.rotation.z - gun.transform.rotation.z);
double angle = 2 * Mathf.Rad2Deg * angleRadians;

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

আমরা কী করছি তার অতিরিক্ত ব্যাখ্যার জন্য কোডের চূড়ান্ত অবরুদ্ধ:

//turn turret towards target
turretTransform.up = targetTransform.position - turretTransform.position;
//adjust for gun angle
if (weaponTransform.localEulerAngles.z <180) //if the value is over 180 it's actually a negative for us
    turretTransform.Rotate(Vector3.forward, 90 - b - a);
else
    turretTransform.Rotate(Vector3.forward, 90 - b + a);

যদি আপনি সবকিছু ঠিকঠাক করেন তবে আপনার মতো একটি দৃশ্য পাওয়া উচিত ( unityক্যপ্যাকেজের জন্য লিঙ্ক ): এখানে চিত্র বর্ণনা লিখুন আমি সর্বদা ইতিবাচক মানগুলির দ্বারা যা বোঝাতে চাইছি:এখানে চিত্র বর্ণনা লিখুন

জেড পদ্ধতিটি নেতিবাচক মান দিতে পারে:এখানে চিত্র বর্ণনা লিখুন

উদাহরণস্বরূপ দৃশ্যের জন্য, এই লিঙ্কটি থেকে unityক্যপ্যাকেজ পান

আমি দৃশ্যে (টিউটারে) কোডটি ব্যবহার করেছি:

public class TurretAimCorrection : MonoBehaviour
{
    public Transform targetTransform;
    public Transform turretTransform;
    public Transform weaponTransform;

    private float f, d, x, y, h, b, a, weaponAngle, turnAngle;
    private void Start()
    {
        TurnCorrection();
    }

    private void Update()
    {
        TurnCorrection();
    }
    void TurnCorrection()
    {
        //find distances and angles
        d = Vector2.Distance(new Vector2(targetTransform.position.x, targetTransform.position.y), new Vector2(turretTransform.position.x, turretTransform.position.y));
        x = Vector2.Distance(new Vector2(turretTransform.position.x, turretTransform.position.y), new Vector2(weaponTransform.position.x, weaponTransform.position.y));
        weaponAngle = weaponTransform.localEulerAngles.z;
        weaponAngle = weaponAngle * Mathf.Deg2Rad;
        y = Mathf.Abs(Mathf.Cos(weaponAngle) * x);
        b = Mathf.Rad2Deg * Mathf.Acos(y / d);
        a = Mathf.Rad2Deg * Mathf.Acos(y / x);
        //turn turret towards target
        turretTransform.up = targetTransform.position - turretTransform.position;
        //adjust for gun angle
        if (weaponTransform.localEulerAngles.z < 180)
            turretTransform.Rotate(Vector3.forward, 90 - b - a);
        else
            turretTransform.Rotate(Vector3.forward, 90 - b + a);
        //Please leave this comment in the code. This code was made by 
        //http://gamedev.stackexchange.com/users/93538/john-hamilton a.k.a. CrazyIvanTR. 
        //This code is provided as is, with no guarantees. It has worked in local tests on Unity 5.5.0f3.
    }
}

2 ডি প্লেন হিসাবে X এবং Z এর সাথে 3D অভিযোজিত কোড:

public class TurretAimCorrection : MonoBehaviour
{
    public Transform targetTransform; //drag target here
    public Transform turretTransform; //drag turret base or turret top part here
    public Transform weaponTransform; //drag the attached weapon here

    private float d, x, y, b, a, weaponAngle, turnAngle;
    private void Start()
    {
        TurnAdjustment();
    }

    private void Update()
    {
        TurnAdjustment();
    }
    void TurnAdjustment()
    {

        d = Vector2.Distance(new Vector2(targetTransform.position.x, targetTransform.position.z), new Vector2(turretTransform.position.x, turretTransform.position.z));
        x = Vector2.Distance(new Vector2(turretTransform.position.x, turretTransform.position.z), new Vector2(weaponTransform.position.x, weaponTransform.position.z));
        weaponAngle = weaponTransform.localEulerAngles.y;
        weaponAngle = weaponAngle * Mathf.Deg2Rad;
        y = Mathf.Abs(Mathf.Cos(weaponAngle) * x);
        b = Mathf.Rad2Deg * Mathf.Acos(y / d);
        a = Mathf.Rad2Deg * Mathf.Acos(y / x);
        //turn turret towards target
        turretTransform.forward = new Vector3(targetTransform.position.x, 0, targetTransform.position.z) - new Vector3(turretTransform.position.x, 0, turretTransform.position.z);
        //adjust for gun angle
        if (weaponTransform.localEulerAngles.y < 180)
            turretTransform.Rotate(Vector3.up, - a +b-90);
        else
            turretTransform.Rotate(Vector3.up, + a+ b - 90);
        //Please leave this comment in the code. This code was made by 
        //http://gamedev.stackexchange.com/users/93538/john-hamilton a.k.a. CrazyIvanTR. 
        //This code is provided as is, with no guarantees. It has worked in local tests on Unity 5.5.0f3.
    }
}

প্রথম চিত্রটিতে কিছুটা ত্রুটি রয়েছে। জেডটি বাক্সের বুজটির দৈর্ঘ্য। X ঘূর্ণনের পরে বাক্সের বুজটির দৈর্ঘ্য ... x = z। সুতরাং, যদি না y হ'ল অনুমান হয় যা সঠিক ত্রিভুজ নয় এবং পাপ প্রযোজ্য না।
গ্রেট হাঁস

@ দ্য গ্রেটডাক জেডটি ব্রাজিল এবং বাক্সের মধ্যবর্তী দূরত্ব নয় যা ভেক্টর ২ for এর বুড়ির সামনে (এটি কেবল শেষের দিকে তীর না রেখে সীমাবদ্ধ দেখানো হয়েছে)। Z এর দূরত্ব থাকলেও ছবিটির ইউনিট রয়েছে এবং আপনি দেখতে পারেন যে জেড <এক্স এমনকি গণনা ছাড়াই।
জন হ্যামিল্টন

2
@ ফ্র্যাঙ্কসস্টেইন আপনাকে প্রথমে বুড়িটি ঘুরিয়ে দিতে হবে না, তারপরে এগুলি প্রয়োগ করুন। আপনি প্রথমে এগুলি গণনা করতে পারেন, তারপরে এই সমীকরণগুলি থেকে আপনি যে ডিগ্রিটি পাবেন সেই বার্টের টার্ন ডিগ্রীতে যোগ করুন। (সুতরাং বস্তুর দিকে বুড়িটি 20 ডিগ্রি পরিবর্তনের পরিবর্তে, বন্দুকের জন্য সামঞ্জস্য করার পরিবর্তে আপনি বন্দুকের জন্য 20 ডিগ্রি + অ্যাডজাস্টমেন্ট দ্বারা গড়িটি ঘুরিয়ে আনবেন)।
জন হ্যামিল্টন

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

1
@ জনহ্যামিলটন আপনি এটি করেছেন! এটি অবশেষে সমাধান করা হয়েছে, এবং লেজারের মতো নির্ভুলতার সাথেও! ধন্যবাদ! ধন্যবাদ! ধন্যবাদ! আমি এখন আমার পোস্টটি শুরুতে এটি কীভাবে সম্পাদনা করব তা ভবিষ্যতের রেফারেন্সের জন্য আরও সহজে বোঝা যায়! আরও একবার, আপনাকে ধন্যবাদ!
ফ্রান্সসটাইন

3

আপনি আরও সাধারণ পদ্ধতি ব্যবহার করতে পারেন:

আপনার সমস্যার গণিত ইতিমধ্যে স্কেলার প্রোডাক্ট (বা ডট পণ্য) আকারে বিদ্যমান । আপনাকে কেবল আপনার অস্ত্র ফরোয়ার্ড অক্ষের দিকনির্দেশ এবং আপনার অস্ত্র থেকে লক্ষ্য পর্যন্ত দিকনির্দেশ পাওয়া দরকার।

ডাব্লু আপনার অস্ত্রের সামনের ভেক্টর হতে দিন।

ডি আপনার অস্ত্র থেকে আপনার টার্গেটের দিক হতে দিন। (লক্ষ্য.পোস - অস্ত্র.পোস)

আপনি যদি ডট পণ্যের সূত্রটি সমাধান করেন

dot(A,B) = |A|*|B|*cos(alpha) with alpha = the angle between A and B

আলফা জন্য, আপনি পেতে:

              ( dot(W,D) )
alpha = arccos(--------- )
              ( |W|*|D|  )

আপনাকে কেবল রেডিয়ানকে ডিগ্রিতে রূপান্তর করতে হবে এবং আপনার রোবোটটি ঘোরানোর জন্য আপনি কোণ পেয়েছিলেন। (যেমনটি আপনি উল্লেখ করেছেন যে অস্ত্রটি আপনার রোবোটের একটি কোণে রয়েছে, সুতরাং আপনার আলফাতে কোণটি যুক্ত করতে হবে)

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


2

এখনও অবধি পোস্ট করা সমস্ত উত্তর (কম বেশি) ভুল, তাই এখানে একটি দ্রুত সঠিক সমাধান দেওয়া হয়েছে:

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

লক্ষ্যটির দিকে বন্দুকটি লক্ষ্য করতে, টার্গেটের সম্মুখের ভেক্টরটি টার্গেটে ঘোরান এবং কোণ θ যুক্ত করুন θ

সুতরাং আসুন find সন্ধান করুন:

   d / sin(δ) = a / sin(α) # By the Law of Sines
=> α = asin(a * sin(δ) / d)

   β = 180° - α - δ
   θ = 90° - β
=> θ = α + δ - 90°
     = asin(a * sin(δ) / d) + δ - 90°
     = asin(a * cos') / d) - δ' # Where (δ' = 90° - δ) is the angle between 
                                  # the gun and the turret forward vector.

যখন δ' = 0এটি সহজ হয় θ = asin(a / d), যা জন হ্যামিল্টনের উত্তরের প্রথম অংশের সাথে মেলে।

সম্পাদনা:

আমি একটি কাজের উদাহরণ যুক্ত করেছি।

জেএসফিডলে খুলুন বা নীচে এম্বেড করা স্নিপেট ব্যবহার করুন:

var Degree = Math.PI / 180;
var showDebugOverlays = false;

var Turret = {
    gunAngle: -10 * Degree,
    maxGunAngle: 85 * Degree,
    adaptedGunXOffset: null,

    rotateToTarget: function (target) {
        var delta = Vec.subtract(this.position, target.position);
        var dist = Vec.length(delta);
        var angle = Vec.angle(delta);

        theta = Math.asin(this.adaptedGunXOffset / dist) + this.gunAngle;
        this.rotation = -(angle + theta);

        this.updateGunRay(target);
    },

    setGunAngle: function (angle) {
        var angle = this.clampGunAngle(angle);
        this.gunAngle = angle;
        this.gun.rotation = angle;
        // Account for the fact that the origin of the gun also has an y offset
        // relative to the turret origin
        var extraXOffset = this.gun.position.y * Math.tan(angle);
        var gunXOffset = this.gun.position.x + extraXOffset;
        // This equals "a * cos(δ')" in the angle formula
        this.adaptedGunXOffset = gunXOffset * Math.cos(-angle);

        if (showDebugOverlays) {
            // Show x offsets
            this.removeChild(this.xOffsetOverlay);
            this.removeChild(this.extraXOffsetOverlay);
            this.xOffsetOverlay = addRect(this, 0, 0, this.gun.position.x, 1, 0xf6ff00);
            this.extraXOffsetOverlay = addRect(this, this.gun.position.x, 0, extraXOffset, 1, 0xff00ae);
        }
    },

    rotateGun: function (angleDelta) {
        this.setGunAngle(this.gunAngle + angleDelta);
    },

    updateGunRay: function (target) {
        var delta = this.gun.toLocal(target.position);
        var dist = Vec.length(delta);
        this.gun.removeChild(this.gun.ray);
        this.gun.ray = makeLine(0, 0, 0, -dist);
        this.gun.addChildAt(this.gun.ray, 0);
    },

    clampGunAngle: function (angle) {
        if (angle > this.maxGunAngle) {
            return this.maxGunAngle;
        }
        if (angle < -this.maxGunAngle) {
            return -this.maxGunAngle;
        }
        return angle;
    }
}

function makeTurret() {
    var turret = new PIXI.Sprite.fromImage('http://i.imgur.com/gPtlPJh.png');
    var gunPos = new PIXI.Point(25, -25)

    turret.anchor.set(0.5, 0.5);

    var gun = new PIXI.Container();
    var gunImg = new PIXI.Sprite.fromImage('http://i.imgur.com/RE45GEY.png');
    gun.ray = makeLine(0, 0, 0, -250);
    gun.addChild(gun.ray);

    gunImg.anchor.set(0.5, 0.6);
    gun.addChild(gunImg);
    gun.position = gunPos;

    // Turret forward vector
    turret.addChild(makeLine(0, -38, 0, -90, 0x38ce2c));
    turret.addChild(gun);
    turret.gun = gun;

    Object.setPrototypeOf(Turret, Object.getPrototypeOf(turret));
    Object.setPrototypeOf(turret, Turret);

    turret.setGunAngle(turret.gunAngle);

    if (showDebugOverlays) {
        addRect(turret, 0, 0, 1, 1); // Show turret origin
        addRect(gun, -1, 1, 2, 2, 0xff0096); // Show gun origin
    }

    return turret;
}

function makeTarget() {
    var target = new PIXI.Graphics();
    target.beginFill(0xd92f8f);
    target.drawCircle(0, 0, 9);
    target.endFill();
    return target;
}

var CursorKeys = {
    map: { ArrowLeft: -1, ArrowRight: 1 },
    pressedKeyDirection: null,

    onKeyDown: function (keyEvent) {
        var key = this.map[keyEvent.key];
        if (key) {
            this.pressedKeyDirection = key;
        }
    },
    onKeyUp: function (keyEvent) {
        var key = this.map[keyEvent.key];
        if (key) {
            if (this.pressedKeyDirection == key) {
                this.pressedKeyDirection = null;
            }
        }
    }
}

document.body.addEventListener("keydown", CursorKeys.onKeyDown.bind(CursorKeys));
document.body.addEventListener("keyup", CursorKeys.onKeyUp.bind(CursorKeys));

function makeLine(x1, y1, x2, y2, color) {
    if (color == undefined) {
        color = 0x66CCFF;
    }
    var line = new PIXI.Graphics();
    line.lineStyle(1.5, color, 1);
    line.moveTo(x1, y1);
    line.lineTo(x2, y2);
    return line;
}

function addRect(parent, x, y, w, h, color) {
    if (color == undefined) {
        color = 0x66CCFF;
    }
    var rectangle = new PIXI.Graphics();
    rectangle.beginFill(color);
    rectangle.drawRect(x, y, w, h);
    rectangle.endFill();
    parent.addChild(rectangle);
    return rectangle;
}

var Vec = {
    subtract: function (a, b) {
        return { x: a.x - b.x,
                 y: a.y - b.y };
    },
    length: function (v) {
        return Math.sqrt(v.x * v.x + v.y * v.y);
    },
    angle: function (v) {
        return Math.atan2(v.x, v.y)
    }
}

Math.clamp = function(n, min, max) {
    return Math.max(min, Math.min(n, max));
}

var renderer;
var stage;
var turret;
var target;

function run() {
    renderer = PIXI.autoDetectRenderer(600, 300, { antialias: true });
    renderer.backgroundColor = 0x2a2f34;
    document.body.appendChild(renderer.view);
    stage = new PIXI.Container();
    stage.interactive = true;

    target = makeTarget();
    target.position = { x: renderer.width * 0.2, y: renderer.height * 0.3 };

    turret = makeTurret();
    turret.position = { x: renderer.width * 0.65, y: renderer.height * 0.3 };
    turret.rotateToTarget(target);

    stage.addChild(turret);
    stage.addChild(target);

    var message = new PIXI.Text(
        "Controls: Mouse, left/right cursor keys",
        {font: "18px Arial", fill: "#7c7c7c"}
    );
    message.position.set(10, 10);
    stage.addChild(message);

    stage.on('mousemove', function(e) {
        var pos = e.data.global;
        target.position.x = Math.clamp(pos.x, 0, renderer.width);
        target.position.y = Math.clamp(pos.y, 0, renderer.height);
        turret.rotateToTarget(target);
    })

    animate();
}

function animate() {
    requestAnimationFrame(animate);

    if (CursorKeys.pressedKeyDirection) {
        turret.rotateGun(3 * Degree * CursorKeys.pressedKeyDirection);
        turret.rotateToTarget(target);
    }

    renderer.render(stage);
}

run();
body {
    padding: 0;
    margin: 0;
}

#capture_focus {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.2.2/pixi.min.js"></script>
<div id="capture_focus" />


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

যদি অন্য উত্তরগুলি "কম বেশি ভুল হয়", আপনি সেগুলি সঠিকভাবে বুঝতে / বাস্তবায়ন করতে পারবেন না। পছন্দসই আচরণ তৈরি করতে আমি আগে দুটি বিকল্প উত্তর ব্যবহার করেছি। @ ফ্রাঙ্কনস্টেইন, আমি এমনকি কমপক্ষে একটিতে আপনার মন্তব্যগুলি দেখতে দেখতে বলি যে আপনি যাচাই করেছেন যে এটি কাজ করে। আপনি যদি কোনও সমাধানটি যাচাই করেছেন তবে এখনও আপনার কি সমস্যা আছে?
জেনমলক

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

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