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;
};
ดังนั้น MineTile จะรู้สถานะภายในของมันเช่นถ้ามันกำลังแสดงหรือถูกตรวจสอบ ( this.pristine
) ถ้ามันเป็นหนึ่งในแผ่นกระเบื้องที่มีเหมือง ( this.hasMine
) แต่จะไม่ตัดสินว่าควรจะมีเหมืองหรือไม่ นั่นจะขึ้นอยู่กับชั้นตรรกะ (ในการก้าวต่อไปสู่ OOP ยิ่งขึ้น MineTile สามารถสืบทอดจากไทล์ทั่วไปได้)
ชั้นตรรกะ
นี่ควรเป็นวิธีที่ซับซ้อนที่แอปพลิเคชันจะโต้ตอบกับโหมดการเปลี่ยนแปลงการรักษาสถานะ ฯลฯ ดังนั้นนี่จะเป็นที่ซึ่งรูปแบบของผู้ไกล่เกลี่ยจะถูกนำมาใช้เพื่อรักษาสถานะของเกมปัจจุบัน นี่จะเป็นที่ที่ตรรกะของเกมอาศัยอยู่เพื่อกำหนดสิ่งที่เกิดขึ้นในระหว่างการเล่นเกมหรือสำหรับการตั้งค่าว่า MineTiles ใดจะมีระเบิด มันจะทำการเรียกเข้าไปยังเลเยอร์เอ็นติตี้เพื่อรับระดับอินสแตนซ์ตามพารามิเตอร์ที่กำหนดตามหลักเหตุผล
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 ทั้งหมดสำหรับเกมนี้ หรืออย่างน้อยตัวอย่างกระดูกเปลือยการเขียนเกมออกมาก็คงจะมากเกินไป
เมื่อดำเนินการเสร็จสิ้นจะต้องมีขอบเขตทั่วโลกสำหรับแอปพลิเคชันที่ใดที่หนึ่ง สิ่งนี้จะเก็บอายุการใช้งานของคอนโทรลเลอร์ปัจจุบันของคุณซึ่งเป็นเกตเวย์ของสแต็ก MVC ทั้งหมดในสถานการณ์นี้
var currentGame;
var context = document.getElementById("masterCanvas").getContext('2d');
startMineSweeper.click = function(){
currentGame = new MineSweeperController(context);
currentGame.Start(25,25,"expert");
};
การใช้รูปแบบ MVC นั้นทรงพลังมาก แต่ไม่ต้องกังวลมากเกินไปเกี่ยวกับการยึดติดกับทุกความแตกต่างของพวกเขา ในที่สุดมันเป็นประสบการณ์เกมที่จะตัดสินว่าแอปพลิเคชันนั้นประสบความสำเร็จหรือไม่ :)
เพื่อการพิจารณา: อย่าปล่อยให้นักบินอวกาศสถาปัตย์ตกใจกับ Joel Spolsky