मैं एक गेम इंजन बना रहा हूँ!
इस महान साहसिक कार्य का परिचय
अब कुछ हफ्तों से मैं नियमित रूप से एक प्रोजेक्ट पर काम कर रहा हूं जिसके बारे में बात करना मेरे हिसाब से दिलचस्प हो सकता है, कैनवास पर आधारित जावास्क्रिप्ट और HTML5 में मेरे वीडियो गेम इंजन का निर्माण।
आप शायद सोच रहे होंगे कि आपने वीडियो गेम बनाने के लिए HTML5 और जावास्क्रिप्ट को क्यों चुना? उत्तर प्रश्न की तुलना में कम अच्छा है, यह मेरे स्कूल (ज़ोन01 नॉर्मंडी) के लिए आवश्यक परियोजनाओं की प्रतिस्पर्धा है और यह तथ्य कि भाषाओं में इस परियोजना को पूरा करने के लिए आवश्यक सभी चीजें हैं, जिसने मुझे इन प्रौद्योगिकियों को चुनने के लिए प्रेरित किया।
लेकिन वास्तव में ये वे भाषाएं नहीं हैं जिन्हें मैंने आधार के रूप में चुना होगा और मैं निश्चित रूप से इसे अंतिम रूप देने के बाद विभिन्न भाषाओं के साथ इस प्रकार के अन्य साहसिक कार्यों को शुरू करूंगा।
वास्तुकला
इसलिए मैंने अपने वीडियो गेम इंजन को डिजाइन करने के लिए काम करना शुरू कर दिया, यह कम से कम दो मुख्य सहित कई वर्गों से बना होगा: गेम क्लास जो पूरे गेम क्षेत्र का प्रबंधन करेगा और गेमऑब्जेक्ट क्लास आपको ऑब्जेक्ट उत्पन्न करने की अनुमति देता है हमारे खेलों में और उन्हें एक-दूसरे के साथ बातचीत करने दें।
इन कक्षाओं में मैं CollideBox क्लास जोड़ूंगा जो मुझे सभी वस्तुओं के टकराव बक्से को प्रबंधित करने की अनुमति देगा।
गेम क्लास में एक गेमलूप विधि है जिसे गेम के प्रत्येक फ्रेम (छवि) पर निष्पादित किया जाएगा, एक ड्रा विधि जिसे प्रत्येक गेम लूप के दौरान बुलाया जाएगा।
गेमऑब्जेक्ट क्लास के लिए, इसमें एक स्टेप विधि और एक ड्रा विधि है।
पहला गेम लूप के प्रत्येक राउंड को निष्पादित करता है और दूसरा हर बार गेमलूप क्लास की ड्रा विधि को कॉल करता है।
यह आपको किसी प्रोजेक्ट में इंजन मॉड्यूल आयात करके सैद्धांतिक रूप से गेम बनाने की अनुमति देता है।
स्प्राइट्स को प्रदर्शित करने के लिए मैंने कैनवा एपीआई का उपयोग करना चुना जो HTML5 में अंतर्निहित है (अंतर्निहित का अर्थ है कि यह डिफ़ॉल्ट रूप से इसके साथ आता है)
यह मुझे सभी स्प्राइट प्रदर्शित करने और एनिमेशन बनाने के लिए छवियों को दोबारा काटने की अनुमति देगा जो मेरे लिए बेहद उपयोगी होगा!
कई दिनों के बाद मैं एक निश्चित गति से एनिमेशन प्रदर्शित करने और अपने CollideBoxes के माध्यम से टकराव का पता लगाने में सक्षम हूं।
और बहुत सी अन्य अच्छी चीज़ें जो मैं आपको नीचे देखने दूँगा:
गेमऑब्जेक्ट क्लास
क्लास गेमऑब्जेक्ट{
कंस्ट्रक्टर (गेम) {// गेमऑब्जेक्ट को इनिशियलाइज़ करें
यह.x = 0
यह.y = 0
this.sprite_img = {फ़ाइल: अपरिभाषित, कॉलम: 1, पंक्ति: 1, fw: 1, fh: 1, चरण: 0, anim_speed: 0, स्केल: 1}
यह.लोडेड = गलत
यह.खेल = खेल
यह.मार = झूठ
यह.टकराव = नया CollideBox()
गेम.gObjects.push(यह)
};
सेटस्प्राइट(img_path, पंक्ति=1, col=1, गति=12, स्केल=1) {
var img = नई छवि();
img.onload = () => {
कंसोल.लॉग ("छवि लोड की गई")
this.sprite_img = {फ़ाइल: img, col: col, पंक्ति: पंक्ति, fw: img.width/col, fh: img.height/row, चरण: 0, anim_speed: गति, स्केल: स्केल}
this.onSpriteLoaded()
};
img.src = img_path
}
ऑनस्प्राइटलोडेड() {}
ड्रा (संदर्भ, फ़्रेम) {// गेम ऑब्जेक्ट का फ़ंक्शन ड्रा करें
यदि (this.sprite_img.file != अपरिभाषित) {
लेट कॉलम = this.sprite_img.step % this.sprite_img.col;
पंक्ति = Math.floor(this.sprite_img.step / this.sprite_img.col);
// context.clearRect(this.x, this.y, this.sprite_img.fw, this.sprite_img.fh);
context.drawImage(
this.sprite_img.file,
this.sprite_img.fw * कॉलम,
this.sprite_img.fh * पंक्ति,
this.sprite_img.fw,
this.sprite_img.fh,
यह.x,
यह.y,
this.sprite_img.fw * this.sprite_img.scale,
this.sprite_img.fh * this.sprite_img.scale
);
यदि (फ़्रेम % Math.floor(60 / this.sprite_img.anim_speed) === 0) {
// चरण अद्यतन केवल 12 एफपीएस पर
यदि (this.sprite_img.step बॉक्स.x &&
this.collision.y बॉक्स.y
)
}
ऑनस्टेप() {};
}
class GameObject{
constructor(game) { // Initialize the GameObject
this.x = 0
this.y = 0
this.sprite_img = {file: undefined, col: 1, row: 1, fw: 1, fh: 1, step: 0, anim_speed: 0, scale: 1}
this.loaded = false
this.game = game
this.kill = false
this.collision = new CollideBox()
game.gObjects.push(this)
};
setSprite(img_path, row=1, col=1, speed=12, scale=1) {
var img = new Image();
img.onload = () => {
console.log("image loaded")
this.sprite_img = {file: img, col: col, row: row, fw: img.width / col, fh: img.height / row, step: 0, anim_speed: speed, scale: scale}
this.onSpriteLoaded()
};
img.src = img_path
}
onSpriteLoaded() {}
draw(context, frame) { // Draw function of game object
if (this.sprite_img.file != undefined) {
let column = this.sprite_img.step % this.sprite_img.col;
let row = Math.floor(this.sprite_img.step / this.sprite_img.col);
// context.clearRect(this.x, this.y, this.sprite_img.fw, this.sprite_img.fh);
context.drawImage(
this.sprite_img.file,
this.sprite_img.fw * column,
this.sprite_img.fh * row,
this.sprite_img.fw,
this.sprite_img.fh,
this.x,
this.y,
this.sprite_img.fw * this.sprite_img.scale,
this.sprite_img.fh * this.sprite_img.scale
);
if (frame % Math.floor(60 / this.sprite_img.anim_speed) === 0) {
// Mise à jour de step seulement à 12 fps
if (this.sprite_img.step box.x &&
this.collision.y box.y
)
}
onStep() {};
}
गेम क्लास
क्लास गेम {
कंस्ट्रक्टर (चौड़ाई = 1400, ऊंचाई = 700) {
this.gObjects = [];
this.toLoad = [];
यह.टाइमर = [];
यह.परतें = [];
this.canvas = document.getElementsByTagName("कैनवास")[0]
यह.कैनवास.चौड़ाई = चौड़ाई
यह.कैनवास.ऊंचाई = ऊंचाई
this.context = this.canvas.getContext("2d")
this.context.globalCompositeOperation = 'स्रोत-ओवर';
यह.इनपुट = {};
यह.माउस = {x:0,y:0}
document.addEventListener('keydown', (e) => {
this.inputs[e.key] = true;
}, असत्य);
document.addEventListener('keyup', (e) => {
this.inputs[e.key] = false;
}, असत्य);
document.addEventListener('mousemove', (e) => {
this.mouse.x = e.x;
this.mouse.y = e.y;
})
document.addEventListener('mouseevent', (e) => {
स्विच (ई.बटन) {
}
})
}
ड्रा(फ़्रेम) {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
कंसोल.लॉग(यह.कैनवास.चौड़ाई, यह.कैनवास.ऊंचाई)
for(आइए i = 0; i {
घड़ी = 1
for(आइए i = 0; i class GameObject{
constructor(game) { // Initialize the GameObject
this.x = 0
this.y = 0
this.sprite_img = {file: undefined, col: 1, row: 1, fw: 1, fh: 1, step: 0, anim_speed: 0, scale: 1}
this.loaded = false
this.game = game
this.kill = false
this.collision = new CollideBox()
game.gObjects.push(this)
};
setSprite(img_path, row=1, col=1, speed=12, scale=1) {
var img = new Image();
img.onload = () => {
console.log("image loaded")
this.sprite_img = {file: img, col: col, row: row, fw: img.width / col, fh: img.height / row, step: 0, anim_speed: speed, scale: scale}
this.onSpriteLoaded()
};
img.src = img_path
}
onSpriteLoaded() {}
draw(context, frame) { // Draw function of game object
if (this.sprite_img.file != undefined) {
let column = this.sprite_img.step % this.sprite_img.col;
let row = Math.floor(this.sprite_img.step / this.sprite_img.col);
// context.clearRect(this.x, this.y, this.sprite_img.fw, this.sprite_img.fh);
context.drawImage(
this.sprite_img.file,
this.sprite_img.fw * column,
this.sprite_img.fh * row,
this.sprite_img.fw,
this.sprite_img.fh,
this.x,
this.y,
this.sprite_img.fw * this.sprite_img.scale,
this.sprite_img.fh * this.sprite_img.scale
);
if (frame % Math.floor(60 / this.sprite_img.anim_speed) === 0) {
// Mise à jour de step seulement à 12 fps
if (this.sprite_img.step box.x &&
this.collision.y box.y
)
}
onStep() {};
}
निश्चित रूप से बहुत सारे अनुकूलन या अन्य त्रुटियां हैं लेकिन सब कुछ कार्यात्मक है,
"उत्तम!" क्या आप मुझे बताएंगे?
यह बहुत आसान होगा।
चिंताएँ
इसे पूरा करने और इस इंजन के साथ एक गेम बनाने के लिए संभावनाओं का परीक्षण शुरू करने के बाद, मुझे एक सहकर्मी के साथ बातचीत के दौरान कुछ भयानक समाचार पता चला।
मुझे लगता है कि आपको याद होगा कि प्रौद्योगिकी के जो विकल्प चुने गए थे वे मेरे जोन01 स्कूल की आवश्यकताओं के अनुरूप थे…
वास्तव में चुनी गई भाषाएँ अच्छी थीं लेकिन मुझे ऐसे निर्देश के बारे में जानकारी नहीं थी जो परियोजना को गंभीर रूप से बाधित करेगा...
हमें कैनवा लाइब्रेरी का उपयोग करने से प्रतिबंधित कर दिया गया था!
एक अनुस्मारक के रूप में, यह वह लाइब्रेरी है जिसका उपयोग हम अपनी छवियों को प्रदर्शित करने के लिए करते हैं।
आगे क्या होगा?
जैसा कि मैं यह पाठ लिख रहा हूं, मैं कैनवा के उपयोग के बिना, इस गेम इंजन को पूरी तरह से नया स्वरूप देना शुरू कर रहा हूं।
यह डेवलॉग समाप्त हो गया है और इस कहानी का शेष भाग जल्द ही आपके पास होगा, चिंता न करें।
अगले डेवलॉग के लिए मैं निश्चित रूप से एक नया प्रारूप आज़माऊंगा।
उम्मीद है कि इस सामग्री ने आपकी मदद की है, आपका मनोरंजन किया है या कम से कम आपको कुछ विषयों पर शिक्षित किया है। मैं आपके दिन के अच्छे अंत और अच्छी कोडिंग की कामना करता हूं।
DevLogs 1.1: इंजन समाप्त हो गया है, यह कैसे काम करता है?
इससे पहले
कुछ महीने पहले मैंने अपना वीडियो गेम इंजन बनाना शुरू किया था, मैंने इसे पूरा कर लिया... काफी समय पहले, और जोन01 के कई सहयोगियों की मदद से हम सुपर मारियो ब्रदर्स से प्रेरित एक गेम बनाने में भी सफल रहे जो मेरे पास उपलब्ध है Itch.io पेज.
इस डेवलॉग के लिए आवेदन करने का प्रारूप तय करने में बहुत समय लगा, और मैं मानता हूं कि मैंने इसे लिखने की समय सीमा को थोड़ा विलंबित या यहां तक कि पूरी तरह से पीछे धकेल दिया।
इस विषय पर काम न करने के लिए अपने अनिर्णय का धैर्यपूर्वक बहाना लेते हुए, अब मैं खुद को रूएन बस स्टेशन के बाकी क्षेत्र में नियोजित रिलीज की तारीख लिखने के दो महीने बाद पाता हूं जबकि मेरी रद्द की गई ट्रेन मुझे एक अतिरिक्त घंटे इंतजार करने के लिए मजबूर करती है।
तो आइए वास्तुकला के सभी विवरणों को कवर करें, मेरे डेवलॉग के पहले भाग के बाद से इसमें बहुत कम बदलाव हुआ है (कैनवास के उपयोग से बचकर अनुकूलन के अलावा)।
इसलिए हम किए गए प्रोजेक्ट के बारे में बात करेंगे, जिस तरह से हमने एक टीम के रूप में काम किया और हमें जिन समस्याओं का सामना करना पड़ा।
इसे इस परियोजना पर प्रतिक्रिया के रूप में देखें, और मुझे आशा है कि आप इस लेखन से कुछ सबक सीख सकेंगे जो आपकी किसी परियोजना में मदद करेंगे।
परियोजना
प्रोजेक्ट जावास्क्रिप्ट में सुपर मारियो ब्रदर्स को फिर से बनाना था और शुरुआत से शुरू करना था, कम से कम कोड के संदर्भ में।
विनिर्देश सरल थे, हमें कई स्तरों वाला एक मारियो गेम बनाना था, नए स्तर बनाने का एक तरीका।
इसके अलावा हमें विकल्पों को समायोजित करने के लिए एक स्कोरबोर्ड और एक मेनू भी बनाना पड़ा।
इस परियोजना की कठिनाइयाँ थीं:
स्क्रीन पर तत्वों की क्षैतिज स्क्रॉलिंग-
स्क्रीन पर मौजूद नहीं होने वाले तत्वों का अनुकूलन-
स्क्रॉल करना क्योंकि इसमें खिलाड़ी की स्थिति के सापेक्ष सभी तत्वों को पृष्ठभूमि में स्क्रॉल करना आवश्यक है।
और स्क्रीन पर प्रदर्शित नहीं होने वाले तत्वों को अनुकूलित करने से प्रदर्शन के नुकसान के बिना गेम चलाने के लिए आवश्यक संसाधन कम हो जाते हैं।
इन कठिनाइयों को हल करने के बाद हमने इस गेम को मेरे itch.io पेज पर प्रकाशित किया है, जहां आप जाकर इसका परीक्षण भी कर सकते हैं।
इस तरह यह डेवलॉग समाप्त होता है, अब मैं अन्य परियोजनाओं और/या अन्य विषयों के बारे में लिख सकूंगा।
यदि मैं आपको जो बता रहा हूं उसमें आपकी थोड़ी भी रुचि है, तो आप जीथब पर मेरे विभिन्न प्रोजेक्ट (इस देवलॉग सहित) देख सकते हैं।
आपका शेष दिन मंगलमय हो!