HTML5 গেমের জন্য সহজ সম্পদ ব্যবস্থাপনা

ভূমিকা

HTML5 ব্রাউজারে আধুনিক, প্রতিক্রিয়াশীল এবং শক্তিশালী ওয়েব অ্যাপ্লিকেশন তৈরির জন্য অনেক দরকারী API প্রদান করেছে। এটি দুর্দান্ত, তবে আপনি সত্যিই গেম তৈরি করতে এবং খেলতে চান! সৌভাগ্যবশত, HTML5 গেম ডেভেলপমেন্টের একটি নতুন যুগের সূচনা করেছে যেটি ক্যানভাসের মতো API এবং শক্তিশালী জাভাস্ক্রিপ্ট ইঞ্জিন ব্যবহার করে সরাসরি আপনার ব্রাউজারে গেমিং সরবরাহ করার জন্য প্লাগইনগুলির প্রয়োজন ছাড়াই।

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

সমস্যাটি

HTML5 গেমগুলি অনুমান করতে পারে না যে তাদের সম্পত্তি যেমন ছবি বা অডিও প্লেয়ারের স্থানীয় মেশিনে থাকবে, কারণ HTML5 গেমগুলি HTTP-এর মাধ্যমে ডাউনলোড করা সম্পদগুলির সাথে একটি ওয়েব ব্রাউজারে খেলা বোঝায়। নেটওয়ার্ক জড়িত থাকার কারণে, ব্রাউজারটি নিশ্চিত নয় যে কখন গেমটির সম্পদগুলি ডাউনলোড করা হবে এবং উপলব্ধ হবে৷

একটি ওয়েব ব্রাউজারে একটি ইমেজ প্রোগ্রাম্যাটিকভাবে লোড করার প্রাথমিক উপায় হল নিম্নলিখিত কোড:

var image = new Image();
image.addEventListener("success", function(e) {
  // do stuff with the image
});
image.src = "/some/image.png";

এখন কল্পনা করুন যে গেমটি শুরু হলে লোড এবং প্রদর্শন করা প্রয়োজন এমন একশটি চিত্র রয়েছে। 100টি ছবি প্রস্তুত হলে আপনি কিভাবে জানবেন? তারা সব সফলভাবে লোড হয়েছে? খেলা আসলে কখন শুরু করা উচিত?

সমাধান

একজন সম্পদ ব্যবস্থাপককে সম্পদের সারিবদ্ধতা পরিচালনা করতে দিন এবং সবকিছু প্রস্তুত হয়ে গেলে গেমে ফিরে রিপোর্ট করুন। একজন সম্পদ ব্যবস্থাপক নেটওয়ার্কে সম্পদ লোড করার জন্য যুক্তিকে সাধারণীকরণ করে এবং এটি স্ট্যাটাস চেক করার একটি সহজ উপায় প্রদান করে।

আমাদের সাধারণ সম্পদ ব্যবস্থাপকের নিম্নলিখিত প্রয়োজনীয়তা রয়েছে:

  • ডাউনলোড সারিবদ্ধ
  • ডাউনলোড শুরু করুন
  • সাফল্য এবং ব্যর্থতা ট্র্যাক করুন
  • সবকিছু সম্পন্ন হলে সংকেত
  • সম্পদের সহজ পুনরুদ্ধার

সারিবদ্ধ

প্রথম প্রয়োজন ডাউনলোড সারিবদ্ধ করা হয়. এই নকশাটি আপনাকে প্রকৃতপক্ষে ডাউনলোড না করেই আপনার প্রয়োজনীয় সম্পদ ঘোষণা করতে দেয়৷ এটি কার্যকর হতে পারে যদি, উদাহরণস্বরূপ, আপনি একটি কনফিগারেশন ফাইলে একটি গেম স্তরের জন্য সমস্ত সম্পদ ঘোষণা করতে চান৷

কন্সট্রাকটর এবং সারিবদ্ধ করার কোডটি দেখতে এরকম দেখাচ্ছে:

function AssetManager() {
  this.downloadQueue = [];
}

AssetManager.prototype.queueDownload = function(path) {
    this.downloadQueue.push(path);
}

ডাউনলোড শুরু করুন

আপনি ডাউনলোড করার জন্য সমস্ত সম্পদ সারিবদ্ধ করার পরে, আপনি সম্পদ ব্যবস্থাপককে সবকিছু ডাউনলোড করা শুরু করতে বলতে পারেন।

ওয়েব ব্রাউজার ডাউনলোডগুলিকে সমান্তরাল করতে পারে, ভাগ্যক্রমে—সাধারণত প্রতি হোস্টে 4টি সংযোগ পর্যন্ত। সম্পদ ডাউনলোডের গতি বাড়ানোর একটি উপায় হল সম্পদ হোস্টিংয়ের জন্য বিভিন্ন ডোমেন নাম ব্যবহার করা। উদাহরণস্বরূপ, assets.example.com থেকে সবকিছু পরিবেশন করার পরিবর্তে, assets1.example.com, assets2.example.com, assets3.example.com ইত্যাদি ব্যবহার করার চেষ্টা করুন। এমনকি যদি এই ডোমেন নামগুলির প্রতিটি একই ওয়েব সার্ভারের জন্য একটি CNAME হয়, ওয়েব ব্রাউজার তাদের আলাদা সার্ভার হিসাবে দেখে এবং সম্পদ ডাউনলোড করার জন্য ব্যবহৃত সংযোগের সংখ্যা বাড়ায়। আপনার ওয়েব সাইটের গতি বাড়াতে সর্বোত্তম অনুশীলনে ডোমেন জুড়ে বিভক্ত উপাদানগুলি থেকে এই কৌশলটি সম্পর্কে আরও জানুন।

ডাউনলোড শুরু করার জন্য আমাদের পদ্ধতিকে বলা হয় downloadAll() । আমরা সময়ের সাথে সাথে এটি তৈরি করব। আপাতত, ডাউনলোড শুরু করার প্রথম যুক্তি এখানে।

AssetManager.prototype.downloadAll = function() {
    for (var i = 0; i < this.downloadQueue.length; i++) {
        var path = this.downloadQueue[i];
        var img = new Image();
        var that = this;
        img.addEventListener("load", function() {
            // coming soon
        }, false);
        img.src = path;
    }
}

আপনি উপরের কোডে দেখতে পাচ্ছেন, downloadAll() সহজভাবে ডাউনলোড সারি দিয়ে পুনরাবৃত্তি করে এবং একটি নতুন চিত্র অবজেক্ট তৈরি করে। লোড ইভেন্টের জন্য একটি ইভেন্ট শ্রোতা যোগ করা হয় এবং ছবির src সেট করা হয়, যা প্রকৃত ডাউনলোডকে ট্রিগার করে।

এই পদ্ধতিতে আপনি ডাউনলোড শুরু করতে পারেন।

সাফল্য এবং ব্যর্থতা ট্র্যাকিং

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

AssetManager.prototype.downloadAll = function(downloadCallback) {
  for (var i = 0; i < this.downloadQueue.length; i++) {
    var path = this.downloadQueue[i];
    var img = new Image();
    var that = this;
    img.addEventListener("load", function() {
        // coming soon
    }, false);
    img.addEventListener("error", function() {
        // coming soon
    }, false);
    img.src = path;
  }
}

আমাদের অ্যাসেট ম্যানেজারকে জানতে হবে যে আমরা কতগুলি সাফল্য এবং ব্যর্থতার সম্মুখীন হয়েছি, বা কখন গেমটি শুরু হতে পারে তা কখনই জানা যাবে না।

প্রথমে, আমরা কনস্ট্রাক্টরের অবজেক্টে কাউন্টার যোগ করব, যা এখন এইরকম দেখাচ্ছে:

function AssetManager() {
<span class="highlight">    this.successCount = 0;
    this.errorCount = 0;</span>
    this.downloadQueue = [];
}

এর পরে, ইভেন্ট শ্রোতাদের মধ্যে কাউন্টারগুলি বৃদ্ধি করুন, যা এখন এইরকম দেখাচ্ছে:

img.addEventListener("load", function() {
    <span class="highlight">that.successCount += 1;</span>
}, false);
img.addEventListener("error", function() {
    <span class="highlight">that.errorCount += 1;</span>
}, false);

সম্পদ ব্যবস্থাপক এখন সফলভাবে লোড হওয়া এবং ব্যর্থ সম্পদ উভয়ই ট্র্যাক করছে।

সিগন্যালিং যখন সম্পন্ন

গেমটি ডাউনলোডের জন্য তার সম্পদগুলি সারিবদ্ধ করার পরে এবং সম্পদ ব্যবস্থাপককে সমস্ত সম্পদ ডাউনলোড করতে বলে, সমস্ত সম্পদ ডাউনলোড হয়ে গেলে গেমটিকে বলা দরকার৷ সম্পদগুলি ডাউনলোড করা হলে গেমটি বারবার জিজ্ঞাসা করার পরিবর্তে, সম্পদ ব্যবস্থাপক গেমটিতে ফিরে আসার সংকেত দিতে পারেন।

সম্পদ ব্যবস্থাপক প্রথমে জানতে হবে যখন প্রতিটি সম্পদ শেষ হয়। আমরা এখন একটি isDone পদ্ধতি যোগ করব:

AssetManager.prototype.isDone = function() {
    return (this.downloadQueue.length == this.successCount + this.errorCount);
}

SuccessCount + errorCount-কে ডাউনলোড কিউয়ের আকারের সাথে তুলনা করে, অ্যাসেট ম্যানেজার জানেন যে প্রতিটি অ্যাসেট সফলভাবে শেষ হয়েছে কিনা বা কোনো ধরনের ত্রুটি আছে কিনা।

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

img.addEventListener("load", function() {
    console.log(this.src + ' is loaded');
    that.successCount += 1;
    if (that.isDone()) {
        // ???
    }
}, false);
img.addEventListener("error", function() {
    that.errorCount += 1;
if (that.isDone()) {
        // ???
    }
}, false);

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

সম্পদ ব্যবস্থাপক সমস্ত সম্পদ ডাউনলোড করা সম্পন্ন হলে, আমরা অবশ্যই একটি কলব্যাক পদ্ধতি কল করব! আসুন downloadAll() পরিবর্তন করি এবং কলব্যাকের জন্য একটি প্যারামিটার যোগ করি:

AssetManager.prototype.downloadAll = function(downloadCallback) {
    ...

আমরা আমাদের ইভেন্ট শ্রোতাদের মধ্যে ডাউনলোড কলব্যাক পদ্ধতিতে কল করব:

img.addEventListener("load", function() {
    that.successCount += 1;
    if (that.isDone()) {
        downloadCallback();
    }
}, false);
img.addEventListener("error", function() {
    that.errorCount += 1;
    if (that.isDone()) {
        downloadCallback();
    }
}, false);

সম্পদ ব্যবস্থাপক অবশেষে শেষ প্রয়োজনের জন্য প্রস্তুত।

সম্পদের সহজ পুনরুদ্ধার

একবার গেমটি শুরু হতে পারে বলে সংকেত দেওয়া হলে, গেমটি চিত্রগুলি রেন্ডার করা শুরু করবে। সম্পদ ব্যবস্থাপক শুধুমাত্র সম্পদগুলি ডাউনলোড এবং ট্র্যাক করার জন্যই দায়ী নয়, তবে সেগুলিকে গেমে সরবরাহ করার জন্যও দায়ী৷

আমাদের চূড়ান্ত প্রয়োজনীয়তা কিছু ধরণের getAsset পদ্ধতি বোঝায়, তাই আমরা এখন এটি যোগ করব:

AssetManager.prototype.getAsset = function(path) {
    return this.cache[path];
}

এই ক্যাশে অবজেক্টটি কনস্ট্রাক্টরে আরম্ভ করা হয়েছে, যা এখন এইরকম দেখাচ্ছে:

function AssetManager() {
    this.successCount = 0;
    this.errorCount = 0;
    this.cache = {};
    this.downloadQueue = [];
}

নিচে দেখানো হিসাবে, downloadAll() এর শেষে ক্যাশে পপুলেট করা হয়েছে:

AssetManager.prototype.downloadAll = function(downloadCallback) {
  ...
      img.addEventListener("error", function() {
          that.errorCount += 1;
          if (that.isDone()) {
              downloadCallback();
          }
      }, false);
      img.src = path;
      <span class="highlight">this.cache[path] = img;</span>
  }
}

বোনাস: বাগ ফিক্স

আপনি বাগ স্পট? উপরে লেখা হিসাবে, isDone পদ্ধতিটি তখনই বলা হয় যখন হয় লোড বা ত্রুটি ইভেন্ট ট্রিগার হয়। কিন্তু যদি সম্পদ ব্যবস্থাপকের কোনো সম্পদ ডাউনলোডের জন্য সারিবদ্ধ না থাকে? isDone পদ্ধতিটি কখনই ট্রিগার হয় না এবং গেমটি কখনই শুরু হয় না।

আপনি downloadAll() এ নিম্নলিখিত কোড যোগ করে এই দৃশ্যকল্পটি মিটমাট করতে পারেন:

AssetManager.prototype.downloadAll = function(downloadCallback) {
    if (this.downloadQueue.length === 0) {
      downloadCallback();
  }
 ...

যদি কোনো সম্পদ সারিবদ্ধ না থাকে, কলব্যাক অবিলম্বে বলা হয়। বাগ সংশোধন করা হয়েছে!

উদাহরণ ব্যবহার

আপনার HTML5 গেমটিতে এই সম্পদ ব্যবস্থাপক ব্যবহার করা বেশ সহজবোধ্য। এখানে লাইব্রেরি ব্যবহার করার সবচেয়ে মৌলিক উপায়:

var ASSET_MANAGER = new AssetManager();

ASSET_MANAGER.queueDownload('img/earth.png');

ASSET_MANAGER.downloadAll(function() {
    var sprite = ASSET_MANAGER.getAsset('img/earth.png');
    ctx.drawImage(sprite, x - sprite.width/2, y - sprite.height/2);
});

উপরের কোডটি ব্যাখ্যা করে:

  1. একটি নতুন সম্পদ ব্যবস্থাপক তৈরি করে
  2. ডাউনলোড করার জন্য সম্পদ সারিবদ্ধ করুন
  3. downloadAll() দিয়ে ডাউনলোড শুরু করুন
  4. কলব্যাক ফাংশন চালু করে সম্পদ প্রস্তুত হলে সংকেত দিন
  5. getAsset() দিয়ে সম্পদ পুনরুদ্ধার করুন

উন্নতির জন্য এলাকাসমূহ

আপনি নিঃসন্দেহে আপনার গেমটি তৈরি করার সাথে সাথে এই সাধারণ সম্পদ ব্যবস্থাপককে ছাড়িয়ে যাবেন, যদিও আমি আশা করি এটি একটি প্রাথমিক সূচনা প্রদান করেছে। ভবিষ্যতের বৈশিষ্ট্যগুলি অন্তর্ভুক্ত করতে পারে:

  • সংকেত কোন সম্পদ একটি ত্রুটি ছিল
  • অগ্রগতি নির্দেশ করতে কলব্যাক
  • ফাইল সিস্টেম API থেকে সম্পদ পুনরুদ্ধার করা হচ্ছে

দয়া করে নিচের মন্তব্যে উন্নতি, কাঁটাচামচ এবং কোডের লিঙ্ক পোস্ট করুন।

সম্পূর্ণ উৎস

এই অ্যাসেট ম্যানেজারের উত্স, এবং যে গেমটি থেকে এটি বিমূর্ত করা হয়েছে, সেটি Apache লাইসেন্সের অধীনে ওপেন সোর্স এবং এটি Bad Aliens GitHub অ্যাকাউন্টে পাওয়া যেতে পারে। ব্যাড এলিয়েন গেমটি আপনার HTML5 সামঞ্জস্যপূর্ণ ব্রাউজারে খেলা যেতে পারে। এই গেমটি সুপার ব্রাউজার 2 টার্বো এইচডি রিমিক্স শিরোনামের আমার Google IO আলোচনার বিষয় ছিল: HTML5 গেম ডেভেলপমেন্টের ভূমিকা ( স্লাইড , ভিডিও )।

সারসংক্ষেপ

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