जावास्क्रिप्ट MVC आवेदन डिजाइन (कैनवास)


9

मैं जावास्क्रिप्ट में एक एमवीसी की तरह एक कैनवास एप्लिकेशन को संरचना / आर्किटेक्ट करने के तरीके को समझने में कठिनाई महसूस कर रहा हूं। यूआई काफी तरल और एनिमेटेड होगा, खेल काफी सरल है, लेकिन ट्विनिंग और एनीमेशन पर भारी जोर दिया जाएगा। मुझे लगता है कि MVC सिद्धांत रूप में कैसे काम करता है लेकिन व्यवहार में नहीं। मैं इस से दूर हो गया है, मैं एक बहुत पढ़ें, और जब मैं शुरू कर दिया था के रूप में उलझन में हूँ।

आवेदन क्षेत्र के बारे में कुछ विवरण:

  • मल्टी स्क्रीन गेम फ्रेमवर्क - इस फ्रेमवर्क में कई गेम बैठेंगे आम यूआई "स्क्रीन" में शामिल हैं: सेटिंग्स, सूचना, कठिनाई चुनें, मुख्य मेनू आदि।
  • कई इनपुट तरीके
  • कुछ स्क्रीन पर शीर्ष मेनू बार जैसे सामान्य UI तत्व
  • विभिन्न रेंडरिंग विधियों (कैनवास / DOM / webGL) के उपयोग की संभावना

फिलहाल मेरे पास AppModel, AppController और AppView है। यहाँ से मैं प्रत्येक "स्क्रीन" को जोड़ने और इसे AppView में संलग्न करने की योजना बना रहा था। लेकिन टॉप मेनू बार जैसी चीजों के बारे में क्या, उन्हें एक और MVC ट्रायड होना चाहिए? कसकर युग्मन घटकों के बिना मैं इसे कहां और कैसे संलग्न करूंगा?

क्या एक स्वीकृत MVC ट्रायड दूसरे के भीतर होना एक स्वीकृत अभ्यास है? यानी मैं AppView में प्रत्येक "स्क्रीन" जोड़ सकता हूं? "त्रय" भी एक स्वीकृत MVC शब्द है ?!

मेरा दिमाग विकल्पों के तहत पिघल रहा है ... मुझे ऐसा लगता है कि मैं यहां कुछ मौलिक याद कर रहा हूं। मुझे पहले से ही एक समाधान मिल रहा है और एमवीसी दृष्टिकोण का उपयोग किए बिना चल रहा है, लेकिन कसकर युग्मित सूप के साथ समाप्त हो गया है - तर्क और विचार और वर्तमान में संयुक्त। यह विचार इसे खोलने और विचारों के आसान परिवर्तन की अनुमति देने के लिए था (उदाहरण के लिए एक कैनवास दृश्य को डोम आधारित दृश्य के साथ स्वैप करना)।

वर्तमान पुस्तकालयों का उपयोग किया जाता है: requ.js, createJS, अंडरस्कोर, जीएसएपी, हाथ से रोल किए गए एमवीसी कार्यान्वयन

किसी भी संकेत, उदाहरण आदि, विशेष रूप से चीज़ के वास्तविक डिज़ाइन के संबंध में और "स्क्रीन" को उचित M, V या C में विभाजित करने की सराहना की जाएगी।

... या MVC के अलावा एक और अधिक उपयुक्त विधि

[एनबी, अगर आपने यह प्रश्न पहले देखा है क्योंकि मैंने इसे 2 अन्य गलत स्टैकएक्सचेंज समुदायों में पूछा है ... मेरे मस्तिष्क ने काम करना बंद कर दिया है]


1
लगता है कि आपने आखिरकार सही साइट ढूंढ ली। Gamedev अपना सवाल नहीं चाहता था?
रॉबर्ट हार्वे

@RobertHarvey ने सोचा कि यह संभवतः यहाँ अधिक प्रासंगिक था ... कम से कम मुझे आशा है कि!
विग्लाइवॉर्म

जवाबों:


3

MVC को कई स्थानों पर कवर किया गया है, इसलिए यहाँ पुन: पुनरावृति के लिए बहुत कुछ नहीं होना चाहिए। अनिवार्य रूप से आप अपने ऑब्जेक्ट ग्राफ, हेल्पर्स और लॉजिक को मॉडल टियर में शामिल करना चाहते हैं। दृश्य वे स्क्रीन होंगे जो पृष्ठ के गतिशील भाग को भरने के लिए बाहर धकेले जाते हैं (और इनमें तर्क और सहायकों की हल्की मात्रा हो सकती है)। और नियंत्रक, जो ऑब्जेक्ट ग्राफ़, हेल्पर्स और लॉजिक से उपलब्ध स्क्रीन के आधार पर स्क्रीन को परोसने के लिए एक हल्का कार्यान्वयन है।

नमूना

यह वह जगह होनी चाहिए जहां आवेदन का मांस बैठता है। इसे एक सर्विस लेयर, एक लॉजिक लेयर और एक एंटिटी लेयर में बांधा जा सकता है। आपके उदाहरण के लिए इसका क्या मतलब है?

इकाई परत

यह आपके खेल के मॉडल और आंतरिक व्यवहार की परिभाषाओं को घर में रखना चाहिए। उदाहरण के लिए, यदि आपके पास खानों के लिए एक खेल है, तो यह वह जगह होगी जहां बोर्ड और वर्ग परिभाषाएं थीं कि वे अपनी आंतरिक स्थिति को कैसे बदलते हैं।

function Location(x,y){
 this.x = x;
 this.y = y;
}
function MineTile(x,y){
 this.flagged = false;
 this.hasMine = false;
 this.pristine = true;
 this.location = new Location(x,y);
}
MineTile.prototype.expose = function(){
 if( this.hasMine ) return false;
 this.pristine = false;
 return this.location;
};

तो माइनटाइल को इसकी आंतरिक स्थिति का पता चल जाएगा, जैसे कि यह दिखा रहा है या जांच की गई है ( this.pristine), अगर यह उन खानों में से एक है जिसमें एक खदान है ( this.hasMine) है, लेकिन यह निर्धारित नहीं करेगा कि यह खदान होना चाहिए था या नहीं। यह तर्क परत तक होगा। (OOP में और भी आगे जाने के लिए, MineTile एक जेनेरिक टाइल से विरासत में मिली)।

तर्क परत

यह उन जटिल तरीकों को शामिल करता है जो एप्लिकेशन को बदलते मोड, राज्य को ध्यान में रखते हुए, आदि के साथ बातचीत करेगा, इसलिए यह वह जगह होगी जहां वर्तमान खेल की स्थिति को बनाए रखने के लिए एक मध्यस्थ पैटर्न लागू किया जाएगा। यह वह जगह होगी जहां गेम लॉजिक यह निर्धारित करने के लिए रहता है कि गेम के दौरान क्या होता है, उदाहरण के लिए या माइनटाइल्स की स्थापना के लिए मेरा क्या होगा। यह तार्किक रूप से निर्धारित मापदंडों के आधार पर त्वरित स्तर प्राप्त करने के लिए इकाई परत में कॉल करेगा।

var MineSweeperLogic = {
 construct: function(x,y,difficulty){
  var mineSet = [];
  var bombs = 7;
  if( difficulty === "expert" ) bombs = 15;
  for( var i = 0; i < x; i++ ){
   for( var j = 0; i j < y; j++ ){
    var mineTile = new MineTile(i,j);
    mineTile.hasMine = bombs-- > 0;
    mineSet.push(mineTile);
   }
  }
  return mineSet;
 },
 mineAt: function(x,y,mineSet){
  for( var i = 0; i < mineSet.length; i++ )
   if( mineSet[i].x === x && mineSet[i].y === y ) return mineSet[i];
 }
};

सेवा परत

यह वह जगह होगी जहां नियंत्रक की पहुंच है। इसमें खेलों के निर्माण के लिए तर्क परत तक पहुंच होगी। एक उच्च स्तर की कॉल सेवा परत में हो सकती है ताकि पूरी तरह से त्वरित खेल या एक संशोधित खेल स्थिति को पुनः प्राप्त किया जा सके।

function MineSweeper(x,y,difficulty){
 this.x = x;
 thix.y = y;
 this.difficulty = difficulty;
 this.mineSet = MineSweeperLogic.construct(x,y,difficulty);
}
MineSweeper.prototype.expose = function(x,y){
 return MineSweeperLogic.mineAt(x,y,this.mineSet).expose();
}

नियंत्रक

नियंत्रकों को हल्का वजन होना चाहिए, अनिवार्य रूप से यही वह है जो मॉडल के ग्राहक के रूप में उजागर होता है। कई नियंत्रक होंगे, इसलिए उन्हें संरचित करना महत्वपूर्ण हो जाएगा। नियंत्रक फ़ंक्शन कॉल वह होगा जो UI ईवेंट के आधार पर जावास्क्रिप्ट कॉल हिट करता है। इन्हें सर्विस लेयर में उपलब्ध व्यवहार को उजागर करना चाहिए और फिर पॉप्युलेट करना चाहिए या इस मामले में क्लाइंट के लिए विचारों को संशोधित करना चाहिए।

function MineSweeperController(ctx){
 var this.context = ctx;
}
MineSweeperController.prototype.Start = function(x,y,difficulty){
 this.game = new MineSweeper(x,y,difficulty);
 this.view = new MineSweeperGameView(this.context,this.game.x,this.game.y,this.game.mineSet);
 this.view.Update();
};
MineSweeperController.prototype.Select = function(x,y){
 var result = this.game.expose(x,y);
 if( result === false ) this.GameOver();
 this.view.Select(result);
};
MineSweeperController.prototype.GameOver = function(){
 this.view.Summary(this.game.FinalScore());
};

राय

विचारों को नियंत्रक के व्यवहारों के सापेक्ष व्यवस्थित किया जाना चाहिए। संभवतः यह आपके आवेदन का सबसे गहन हिस्सा होगा क्योंकि यह कैनवासिंग से संबंधित है।

function MineSweeperGameView(ctx,x,y,mineSet){
 this.x = x;
 this.y = y;
 this.mineSet = mineSet;
 this.context = ctx;
}
MineSweeperGameView.prototype.Update = function(){
 //todo: heavy canvas modification
 for(var mine in this.mineSet){}
 this.context.fill();
}

तो अब आपके पास इस एक गेम के लिए आपका पूरा MVC सेटअप है। या कम से कम, एक नंगे हड्डियों का उदाहरण, पूरे खेल को लिखना अत्यधिक होता।

एक बार यह सब हो जाने के बाद, कहीं न कहीं आवेदन के लिए एक वैश्विक गुंजाइश की आवश्यकता होगी। यह आपके वर्तमान नियंत्रक के जीवनकाल को धारण करेगा, जो इस परिदृश्य में एमवीसी स्टैक के सभी के लिए प्रवेश द्वार है।

var currentGame;
var context = document.getElementById("masterCanvas").getContext('2d');
startMineSweeper.click = function(){
 currentGame = new MineSweeperController(context);
 currentGame.Start(25,25,"expert");
};

MVC पैटर्न का उपयोग करना बहुत शक्तिशाली है, लेकिन उनमें से प्रत्येक की बारीकियों का पालन करने के बारे में बहुत ज्यादा चिंता न करें। अंत में, यह खेल का अनुभव है जो निर्धारित करेगा कि क्या आवेदन एक सफलता है :)

विचार के लिए: जोएल स्पोल्स्की द्वारा आर्किटेक्चर एस्ट्रोनॉट्स डराओ मत


धन्यवाद @TravisJ - मैं एमवीसी की एक अच्छी व्याख्या के रूप में खेल से संबंधित है। अभी भी कुछ बिंदुओं के बारे में स्पष्ट नहीं है, मुझे लगता है, जैसा कि आप कहते हैं, मैं पैटर्न की बारीकियों में फंस रहा हूं और यह मुझे आगे बढ़ने से रोक रहा है। एक चीज जो मैंने देखी वह थी नियंत्रक में this.view.Select () का उपयोग - क्या इस प्रकार की चुस्त युग्मन आवश्यक है या आगे डिकोडिंग का एक तरीका है?
विगलेवॉर्म

@wigglyworm - वहाँ हमेशा अधिक decoupling हो सकता है! : डी लेकिन वास्तव में, नियंत्रक वह होना चाहिए जो मॉडल से संवाद करता है और फिर दृश्य को अपडेट करता है ताकि संभवतः वह जगह हो जहां अधिकांश युग्मन MVC में होता है।
ट्रैविस जे

2

यहां वह है जो आपने पहले ही गलत किया है - आपने भ्रम की स्थिति में एमवीसी को हाथ से लुढ़का दिया है, और बिना किसी एमवीसी को अपनी बेल्ट के तहत।

PureMVC पर एक नज़र डालें, यह भाषा अज्ञेय है और वास्तव में MVC के साथ अपने पैरों को गीला करने के लिए एक अच्छा मंच हो सकता है।

इसका कोड छोटा और बोधगम्य है, और इससे आप अपनी प्रगति के लिए इसे अपनी आवश्यकताओं के अनुरूप बना पाएंगे।

इसके साथ एक छोटा सा सरल खेल लिखना शुरू करें, माइंसवेपर अच्छा होगा। ट्रैविस जे ने जो कहा वह बहुत अच्छा है, खासकर मॉडल के बारे में। मैं केवल यह जोड़ना चाहूंगा कि आपको यह याद रखने की आवश्यकता है कि नियंत्रक (कम से कम PureMvc में) स्टेटलेस हैं, वे अस्तित्व में आते हैं, अपना BRIEF काम करते हैं और चले जाते हैं। वे ज्ञानी हैं। वे कार्यों की तरह हैं। "ग्रिड भरें, मॉडल बदल गया है", "मॉडल को अपडेट करें, एक बटन धक्का दिया गया था"

दृश्य (प्योरएमवीसी में मध्यस्थ) सबसे विनम्र हैं, और मॉडल केवल थोड़ा चालाक है। दोनों अमल को अमल में लाते हैं, इसलिए आप (नियंत्रकों) कभी भी यूआई या डीबी को सीधे नहीं छूते हैं।

आपके UI के प्रत्येक तत्व (उदाहरण के लिए एक winforms ऐप में) में एक दृश्य (मध्यस्थ है - आप देखते हैं कि यह अब एक बेहतर शब्द क्यों है?), लेकिन "नियंत्रण रंग" या "फोकस" जैसे मेटा-चिंताओं के लिए मध्यस्थ भी बनाया जा सकता है। प्रबंधक "जो UI तत्वों में काम करता है। यहाँ परतों में सोचो।

UI और DB ईवेंट्स स्वचालित रूप से नियंत्रकों (यदि आप एक स्मार्ट नामकरण योजना का उपयोग करते हैं) को आमंत्रित कर सकते हैं, और कुछ नियंत्रकों को चरणबद्ध किया जा सकता है - एक मध्यस्थ को सीधे मॉडल डेटा परिवर्तन घटना को सुनने और उसके डेटा पैकेज को वितरित करने के लिए बनाया जा सकता है।

हालाँकि यह एक तरह का धोखा है और इसके लिए माडल की आवश्यकता होती है कि बाहर क्या है, और मध्यस्थ को यह समझने के लिए कि डेटा पैकेज का क्या करना है, लेकिन यह आपको कई मामलों में सांसारिक नियंत्रकों के साथ घुलमिलने से बचाएगा।

मॉडल: गूंगा लेकिन पुन: प्रयोज्य; नियंत्रकों: स्मार्ट लेकिन कम पुन: प्रयोज्य (वे एप्लिकेशन हैं); मध्यस्थ: गूंगा लेकिन पुन: प्रयोज्य। इस मामले में पुन: प्रयोज्यता का अर्थ है दूसरे ऐप के लिए पोर्टेबल।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.