MVC telah dibahas di banyak tempat sehingga tidak ada banyak yang harus diulang lagi di sini. Pada dasarnya Anda ingin grafik objek, helper, dan logika Anda terkandung dalam tier model. Tampilan akan menjadi layar yang terdorong keluar untuk mengisi bagian dinamis halaman (dan mungkin mengandung sedikit logika dan bantuan). Dan controller, yang menjadi implementasi ringan untuk melayani layar berdasarkan apa yang tersedia dari objek grafik, helper, dan logika.
Model
Ini harus berada di tempat daging aplikasi duduk. Itu dapat dibagi menjadi lapisan layanan, lapisan logika, dan lapisan entitas. Apa artinya ini untuk contoh Anda?
Lapisan entitas
Ini harus menampung definisi model dan perilaku internal gim Anda. Misalnya, jika Anda memiliki permainan untuk kapal penyapu ranjau, ini akan menjadi tempat definisi papan dan kuadrat bersama dengan bagaimana mereka mengubah keadaan internal mereka.
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;
};
Jadi MineTile akan mengetahui keadaan internalnya, seperti apakah itu menunjukkan atau diperiksa ( this.pristine
), apakah itu salah satu ubin yang memiliki tambang ( this.hasMine
) tetapi tidak akan menentukan apakah itu seharusnya memiliki tambang. Itu akan sampai ke lapisan logika. (Untuk melangkah lebih jauh ke OOP, MineTile dapat mewarisi dari Tile generik).
Lapisan logika
Ini harus menampung cara-cara rumit yang akan digunakan aplikasi untuk berinteraksi dengan perubahan mode, menjaga status, dll. Jadi ini akan menjadi tempat pola mediator akan diterapkan untuk mempertahankan status permainan saat ini. Ini akan menjadi tempat di mana logika permainan berada untuk menentukan apa yang terjadi selama pertandingan berakhir misalnya, atau untuk mengatur MineTiles mana yang akan memiliki tambang. Itu akan membuat panggilan ke lapisan Entity untuk mendapatkan tingkat instantiated berdasarkan parameter yang ditentukan secara logis.
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];
}
};
Lapisan layanan
Ini akan menjadi tempat di mana controller memiliki akses. Ini akan memiliki akses ke lapisan logika untuk membangun game. Panggilan tingkat tinggi dapat dilakukan ke dalam lapisan layanan untuk mengambil game yang sepenuhnya instantiated atau keadaan game yang dimodifikasi.
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();
}
Pengendali
Kontroler harus ringan, pada dasarnya inilah yang terpapar sebagai klien untuk model. Akan ada banyak pengendali, jadi penataan mereka akan menjadi penting. Panggilan fungsi pengontrol akan menjadi apa yang disebut panggilan javascript berdasarkan peristiwa UI. Ini harus memperlihatkan perilaku yang tersedia di lapisan layanan dan kemudian mengisi atau dalam hal ini memodifikasi tampilan untuk klien.
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());
};
Melihat
Pandangan harus diatur relatif terhadap perilaku pengontrol. Mereka mungkin akan menjadi bagian paling intensif dari aplikasi Anda karena berurusan dengan kanvas.
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();
}
Jadi sekarang Anda memiliki seluruh pengaturan MVC untuk game yang satu ini. Atau setidaknya, contoh sederhana, menulis seluruh permainan akan berlebihan.
Setelah ini selesai, perlu ada ruang lingkup global untuk suatu aplikasi. Ini akan menahan masa pakai pengontrol Anda saat ini, yang merupakan pintu gerbang ke semua tumpukan MVC dalam skenario ini.
var currentGame;
var context = document.getElementById("masterCanvas").getContext('2d');
startMineSweeper.click = function(){
currentGame = new MineSweeperController(context);
currentGame.Start(25,25,"expert");
};
Menggunakan pola MVC sangat kuat, tetapi jangan terlalu khawatir tentang mengikuti setiap nuansa mereka. Pada akhirnya, pengalaman bermainlah yang akan menentukan apakah aplikasi ini berhasil :)
Untuk pertimbangan: Jangan Biarkan Astronot Arsitektur Menakutkan Anda oleh Joel Spolsky