ভূমিকা
পয়েন্টার লক API একটি ব্রাউজার গেমে প্রথম-ব্যক্তি শ্যুটার নিয়ন্ত্রণগুলি সঠিকভাবে প্রয়োগ করতে সহায়তা করে৷ আপেক্ষিক মাউস নড়াচড়া ছাড়া প্লেয়ারের কার্সার, উদাহরণস্বরূপ, স্ক্রিনের ডান প্রান্তে আঘাত করতে পারে এবং ডানদিকে আরও কোনো নড়াচড়া ছাড় দেওয়া হবে - ভিউটি ডানদিকে প্যান করা অব্যাহত থাকবে না এবং প্লেয়ার খারাপটি অনুসরণ করতে সক্ষম হবে না। বলছি এবং তার মেশিনগান দিয়ে তাদের strafe. প্লেয়ার ফ্র্যাগড পেতে এবং হতাশ হয়ে যাচ্ছে. পয়েন্টার লক দিয়ে এই সাবঅপ্টিমাল আচরণ ঘটতে পারে না।
পয়েন্টার লক এপিআই আপনার অ্যাপ্লিকেশানকে নিম্নলিখিতগুলি করতে দেয়:
- আপেক্ষিক মাউস আন্দোলন সহ কাঁচা মাউস ডেটা অ্যাক্সেস পান
- সমস্ত মাউস ইভেন্টকে একটি নির্দিষ্ট উপাদানে রুট করুন
পয়েন্টার লক সক্রিয় করার একটি পার্শ্ব প্রতিক্রিয়া হিসাবে, মাউস কার্সারটি লুকিয়ে আছে যাতে আপনি চাইলে একটি অ্যাপ্লিকেশন-নির্দিষ্ট পয়েন্টার আঁকতে বেছে নিতে পারেন বা মাউস পয়েন্টারটি লুকিয়ে রাখতে পারেন যাতে ব্যবহারকারী মাউস দিয়ে ফ্রেমটি সরাতে পারে। আপেক্ষিক মাউস মুভমেন্ট হল পরম অবস্থান নির্বিশেষে পূর্ববর্তী ফ্রেম থেকে মাউস পয়েন্টার অবস্থানের ডেল্টা। উদাহরণস্বরূপ, যদি মাউস পয়েন্টারটি (640, 480) থেকে (520, 490) এ সরানো হয় তবে আপেক্ষিক আন্দোলন ছিল (-120, 10)। কাঁচা মাউস অবস্থান ডেল্টা দেখানো একটি ইন্টারেক্টিভ উদাহরণের জন্য নীচে দেখুন।
এই টিউটোরিয়াল দুটি বিষয় কভার করে: পয়েন্টার লক ইভেন্ট সক্রিয় এবং প্রক্রিয়াকরণের নাট এবং বোল্ট, এবং প্রথম-ব্যক্তি শ্যুটার নিয়ন্ত্রণ প্রকল্প বাস্তবায়ন। এটা ঠিক, আপনি যখন এই নিবন্ধটি পড়া শেষ করবেন তখন আপনি জানতে পারবেন কিভাবে পয়েন্টার লক ব্যবহার করতে হয় এবং আপনার নিজস্ব ব্রাউজার গেমের জন্য কোয়েক-স্টাইল নিয়ন্ত্রণগুলি প্রয়োগ করতে হয়!
ব্রাউজার সামঞ্জস্য
পয়েন্টার লক মেকানিক্স
বৈশিষ্ট্য সনাক্তকরণ
ব্যবহারকারীর ব্রাউজার পয়েন্টার লক সমর্থন করে কিনা তা নির্ধারণ করতে আপনাকে নথি বস্তুতে pointerLockElement
বা একটি বিক্রেতা-প্রিফিক্সড সংস্করণ পরীক্ষা করতে হবে। কোডে:
var havePointerLock = 'pointerLockElement' in document ||
'mozPointerLockElement' in document ||
'webkitPointerLockElement' in document;
বর্তমানে পয়েন্টার লক শুধুমাত্র Firefox এবং Chrome এ উপলব্ধ। Opera এবং IE এখনও এটি সমর্থন করে না।
সক্রিয় করা হচ্ছে
পয়েন্টার লক সক্রিয় করা একটি দুই ধাপ প্রক্রিয়া। প্রথমে আপনার অ্যাপ্লিকেশনটি একটি নির্দিষ্ট উপাদানের জন্য পয়েন্টার লক সক্ষম করার অনুরোধ করে এবং ব্যবহারকারীর অনুমতি দেওয়ার সাথে সাথেই একটি pointerlockchange
ইভেন্ট চালু হয়। এস্কেপ কী টিপে ব্যবহারকারী যেকোনো সময় পয়েন্টার লক বাতিল করতে পারেন। আপনার অ্যাপ্লিকেশন প্রোগ্রাম্যাটিকভাবে পয়েন্টার লক থেকে প্রস্থান করতে পারে। পয়েন্টার লক বাতিল হলে একটি pointerlockchange
ইভেন্ট ফায়ার হয়।
element.requestPointerLock = element.requestPointerLock ||
element.mozRequestPointerLock ||
element.webkitRequestPointerLock;
// Ask the browser to lock the pointer
element.requestPointerLock();
// Ask the browser to release the pointer
document.exitPointerLock = document.exitPointerLock ||
document.mozExitPointerLock ||
document.webkitExitPointerLock;
document.exitPointerLock();
উপরের কোড সব এটা লাগে. যখন ব্রাউজার পয়েন্টারটিকে লক করে তখন একটি বুদবুদ পপআপ করে ব্যবহারকারীকে জানিয়ে দেবে যে আপনার অ্যাপ্লিকেশন পয়েন্টারটিকে লক করেছে এবং তাদের নির্দেশ দেবে যে তারা 'Esc' কী টিপে এটি বাতিল করতে পারে।
ইভেন্ট হ্যান্ডলিং
আপনার অ্যাপ্লিকেশনের জন্য শ্রোতাদের যোগ করতে হবে এমন দুটি ইভেন্ট রয়েছে। প্রথমটি হল pointerlockchange
, যেটি যখনই পয়েন্টার লক অবস্থায় পরিবর্তন হয় তখনই আগুন জ্বলে। দ্বিতীয়টি হল mousemove
যা যখনই মাউস সরে যায় তখনই আগুন লাগে।
// Hook pointer lock state change events
document.addEventListener('pointerlockchange', changeCallback, false);
document.addEventListener('mozpointerlockchange', changeCallback, false);
document.addEventListener('webkitpointerlockchange', changeCallback, false);
// Hook mouse move events
document.addEventListener("mousemove", this.moveCallback, false);
আপনার pointerlockchange
কলব্যাকের ভিতরে আপনাকে অবশ্যই পয়েন্টারটি লক বা আনলক করা হয়েছে কিনা তা অবশ্যই পরীক্ষা করতে হবে। পয়েন্টার লক সক্রিয় করা হয়েছে কিনা তা নির্ধারণ করা সহজ: document.pointerLockElement যে উপাদানটির জন্য পয়েন্টার লক অনুরোধ করা হয়েছিল তার সমান কিনা তা পরীক্ষা করুন৷ যদি তা হয়, আপনার অ্যাপ্লিকেশন সফলভাবে পয়েন্টারটিকে লক করেছে এবং যদি তা না হয়, তাহলে ব্যবহারকারী বা আপনার নিজের কোড দ্বারা পয়েন্টারটি আনলক করা হয়েছে৷
if (document.pointerLockElement === requestedElement ||
document.mozPointerLockElement === requestedElement ||
document.webkitPointerLockElement === requestedElement) {
// Pointer was just locked
// Enable the mousemove listener
document.addEventListener("mousemove", this.moveCallback, false);
} else {
// Pointer was just unlocked
// Disable the mousemove listener
document.removeEventListener("mousemove", this.moveCallback, false);
this.unlockHook(this.element);
}
পয়েন্টার লক সক্রিয় করা হলে clientX
, clientY
, screenX
এবং screenY
স্থির থাকে। movementX
এবং movementY
শেষ ইভেন্টটি ডেলিভার করার পর থেকে পয়েন্টারটি সরানো পিক্সেলের সংখ্যার সাথে আপডেট করা হয়েছে। ছদ্ম কোডে:
event.movementX = currentCursorPositionX - previousCursorPositionX;
event.movementY = currentCursorPositionY - previousCursorPositionY;
mousemove
কলব্যাকের ভিতরে ইভেন্টের movementX
এবং movementY
ক্ষেত্রগুলি থেকে আপেক্ষিক মাউস মোশন ডেটা বের করা যেতে পারে।
function moveCallback(e) {
var movementX = e.movementX ||
e.mozMovementX ||
e.webkitMovementX ||
0,
movementY = e.movementY ||
e.mozMovementY ||
e.webkitMovementY ||
0;
}
ধরা ত্রুটি
পয়েন্টার লক প্রবেশ বা প্রস্থান করার মাধ্যমে একটি ত্রুটি উত্থাপিত হলে pointerlockerror
ইভেন্ট ফায়ার হয়। এই ইভেন্টের সাথে সংযুক্ত কোন তথ্য নেই.
document.addEventListener('pointerlockerror', errorCallback, false);
document.addEventListener('mozpointerlockerror', errorCallback, false);
document.addEventListener('webkitpointerlockerror', errorCallback, false);
পূর্ণ-স্ক্রীন প্রয়োজন?
মূলত পয়েন্টার লক ফুলস্ক্রিন API এর সাথে আবদ্ধ ছিল। এর অর্থ হল যে একটি উপাদান অবশ্যই পূর্ণস্ক্রীন মোডে থাকতে হবে আগে এটিতে পয়েন্টার লক করা যায়। এটি আর সত্য নয় এবং পয়েন্টার লক আপনার অ্যাপ্লিকেশন পূর্ণ-স্ক্রীনের যেকোনো উপাদানের জন্য ব্যবহার করা যেতে পারে বা না।
ফার্স্ট-পারসন শুটার কন্ট্রোল উদাহরণ
এখন যেহেতু আমরা পয়েন্টার লক সক্ষম করেছি এবং ইভেন্টগুলি গ্রহণ করছি, এটি একটি বাস্তব উদাহরণের সময়। আপনি কি কখনও জানতে চেয়েছেন কিভাবে কোয়েকের নিয়ন্ত্রণ কাজ করে? স্ট্র্যাপ ইন কারণ আমি তাদের কোড দিয়ে ব্যাখ্যা করতে যাচ্ছি!
প্রথম-ব্যক্তি শ্যুটার নিয়ন্ত্রণগুলি চারটি মূল মেকানিক্সকে ঘিরে তৈরি করা হয়েছে:
- বর্তমান চেহারা ভেক্টর বরাবর এগিয়ে এবং পিছনে সরানো
- বর্তমান strafe ভেক্টর বরাবর বাম এবং ডান সরানো
- ভিউ ইয়াও ঘোরানো (বাম এবং ডান)
- ভিউ পিচ ঘোরানো (উপর এবং নিচে)
এই কন্ট্রোল স্কিমটি বাস্তবায়নকারী একটি গেমের জন্য শুধুমাত্র তিনটি টুকরো ডেটা প্রয়োজন: ক্যামেরা অবস্থান, ক্যামেরা লুক ভেক্টর এবং একটি ধ্রুবক আপ ভেক্টর। আপ ভেক্টর সবসময় (0, 1, 0)। উপরের চারটি মেকানিক্স শুধু ক্যামেরার অবস্থান এবং ক্যামেরা লুক ভেক্টরকে বিভিন্ন উপায়ে ম্যানিপুলেট করে।
আন্দোলন
ডেকে প্রথমে আন্দোলন হয়। নীচের ডেমোতে আন্দোলন স্ট্যান্ডার্ড W, A, S, এবং D কীগুলির সাথে ম্যাপ করা হয়েছে। W এবং S কীগুলি ক্যামেরাকে সামনের দিকে এবং পিছনে নিয়ে যায়। যখন A এবং D কী ক্যামেরাটিকে বাম এবং ডানদিকে চালায়। ক্যামেরা সামনে এবং পিছনে সরানো সহজ:
// Forward direction
var forwardDirection = vec3.create(cameraLookVector);
// Speed
var forwardSpeed = dt * cameraSpeed;
// Forward or backward depending on keys held
var forwardScale = 0.0;
forwardScale += keyState.W ? 1.0 : 0.0;
forwardScale -= keyState.S ? 1.0 : 0.0;
// Scale movement
vec3.scale(forwardDirection, forwardScale * forwardSpeed);
// Add scaled movement to camera position
vec3.add(cameraPosition, forwardDirection);
বাম এবং ডান স্ট্র্যাফিং একটি strafe দিক প্রয়োজন. ক্রস পণ্য ব্যবহার করে স্ট্র্যাফের দিক গণনা করা যেতে পারে:
// Strafe direction
var strafeDirection = vec3.create();
vec3.cross(cameraLookVector, cameraUpVector, strafeDirection);
একবার আপনার কাছে স্ট্র্যাফের দিকনির্দেশ হয়ে গেলে, স্ট্র্যাফ আন্দোলন বাস্তবায়ন করা এগিয়ে বা পিছিয়ে যাওয়ার সমান।
পরবর্তী আপ ভিউ ঘোরানো হয়.
ইয়াও
ইয়াও বা ক্যামেরা ভিউয়ের অনুভূমিক ঘূর্ণন হল ধ্রুবক আপ ভেক্টরের চারপাশে একটি ঘূর্ণন। নীচে একটি নির্বিচারে অক্ষের চারপাশে ক্যামেরা লুক ভেক্টর ঘোরানোর জন্য সাধারণ কোড রয়েছে। এটি axis
চারপাশে deltaAngle
রেডিয়ানগুলির ঘূর্ণনকে প্রতিনিধিত্ব করে একটি কোয়াটারনিয়ন তৈরি করে কাজ করে এবং তারপর ক্যামেরা লুক ভেক্টর ঘোরানোর জন্য কোয়াটারনিয়ন ব্যবহার করে:
// Extract camera look vector
var frontDirection = vec3.create();
vec3.subtract(this.lookAtPoint, this.eyePoint, frontDirection);
vec3.normalize(frontDirection);
var q = quat4.create();
// Construct quaternion
quat4.fromAngleAxis(deltaAngle, axis, q);
// Rotate camera look vector
quat4.multiplyVec3(q, frontDirection);
// Update camera look vector
this.lookAtPoint = vec3.create(this.eyePoint);
vec3.add(this.lookAtPoint, frontDirection);
পিচ
বাস্তবায়িত পিচ বা ক্যামেরা ভিউয়ের উল্লম্ব ঘূর্ণন একই রকম তবে আপ ভেক্টরের চারপাশে ঘূর্ণনের পরিবর্তে আপনি স্ট্র্যাফ ভেক্টরের চারপাশে একটি ঘূর্ণন প্রয়োগ করেন। প্রথম ধাপ হল স্ট্র্যাফ ভেক্টর গণনা করা এবং তারপর সেই অক্ষের চারপাশে ক্যামেরা লুক ভেক্টরটি ঘোরানো।
সারাংশ
পয়েন্টার লক API আপনাকে মাউস কার্সার নিয়ন্ত্রণ করতে দেয়। আপনি যদি ওয়েব গেম তৈরি করেন তবে আপনার খেলোয়াড়রা এটি পছন্দ করবে যখন তারা ফ্র্যাগ হওয়া বন্ধ করবে কারণ তারা উত্তেজিতভাবে মাউসকে উইন্ডো থেকে সরিয়ে দিয়েছে এবং আপনার গেম মাউস আপডেট পাওয়া বন্ধ করে দিয়েছে। ব্যবহার সহজ:
- পয়েন্টার লকের অবস্থা ট্র্যাক করতে
pointerlockchange
ইভেন্ট লিসেনার যোগ করুন - একটি নির্দিষ্ট উপাদানের জন্য পয়েন্টার লক অনুরোধ করুন
- আপডেট পেতে
mousemove
ইভেন্ট লিসেনার যোগ করুন