Javascript MVC uygulama tasarımı (tuval)


9

Javascript MVC benzeri bir yaklaşım kullanarak bir tuval uygulaması yapı / mimar nasıl kavramakta zorlanıyorum. UI oldukça akıcı ve animasyonlu olacak, oyunlar oldukça basit ama ara doldurma ve animasyon ağırlıklı. MVC'nin prensipte nasıl çalıştığını anlıyorum ama pratikte değil. Ben bundan kaçındım, korkunç bir sürü okudum ve şimdi başladığım gibi kafam karıştı.

Uygulama alanı ile ilgili bazı detaylar:

  • çoklu ekran oyun çerçevesi - birden fazla oyun bu çerçeve içinde yer alacak ortak UI "ekranlar" içerir: ayarlar, bilgi, zorluk seçin, ana menü vb.
  • çoklu giriş yöntemleri
  • bazı ekranlarda üst menü çubuğu gibi yaygın kullanıcı arayüzü öğeleri
  • farklı oluşturma yöntemleri kullanma olanağı (canvas / DOM / webGL)

Şu anda bir AppModel, AppController ve AppView var. Buradan her "ekranı" eklemeyi ve AppView'e eklemeyi planlıyordum. Peki ya üst menü çubuğu gibi şeyler, başka bir MVC üçlüsü mü olmalı? Bileşenleri sıkıca bağlamadan nereye ve nasıl bağlayabilirim?

Bir MVC triadının diğerinin içinde olması kabul edilen bir uygulama mı? yani her "ekranı" AppView'a ekleyebilir miyim? "Triad" kabul edilmiş bir MVC terimi bile mi ?!

Aklım seçeneklerin altında eriyor ... Burada temel bir şeyi kaçırmış gibi hissediyorum. Ben zaten bir MVC yaklaşımı kullanmadan çalışan ve çalışan bir çözüm var, ama sıkı bir şekilde birleşti çorba - mantık ve görünümler ile sona erdi ve şu anda kombine. Fikir, açmak ve görünümlerin daha kolay değiştirilmesine izin vermekti (örneğin, bir tuval görünümünü DOM tabanlı bir görünümle değiştirmek için).

Kullanılan mevcut kütüphaneler: requir.js, createJS, alt çizgi, GSAP, elle haddelenmiş MVC uygulaması

Özellikle nesnenin gerçek tasarımı ve "ekranların" uygun M, V veya C'ye bölünmesi ile ilgili herhangi bir işaretçi, örnek vb. Takdir edilecektir.

... veya MVC dışında daha uygun bir yöntem

[NB, bu soruyu daha önce 2 yanlış hatalı yığın değiş tokuş topluluğuna sorduğum için gördüyseniz ... beynim çalışmayı durdurdu]


1
Nihayet doğru siteyi bulduğunuz anlaşılıyor. Gamedev sorunuzu istemedi mi?
Robert Harvey

@RobertHarvey muhtemelen burada daha alakalı olduğunu düşündü ... en azından umarım!
wigglyworm

Yanıtlar:


3

MVC pek çok yerde ele alınmıştır, bu yüzden burada tekrarlamak için fazla bir şey olmamalıdır. Temel olarak nesne grafiğinizin, yardımcılarınızın ve mantığınızın model katmanında yer almasını istiyorsunuz. Görünümler, sayfanın dinamik bölümünü doldurmak için dışarı itilen ekranlardır (ve az miktarda mantık ve yardımcı içerebilir). Ve nesne grafiklerinden, yardımcılardan ve mantığa göre ekranlara hizmet etmek için hafif bir uygulama olan denetleyici.

model

Bu, uygulamanın etinin oturduğu yer olmalıdır. Bir hizmet katmanına, bir mantık katmanına ve bir varlık katmanına sıralanabilir. Örneğiniz için bu ne anlama geliyor?

Varlık katmanı

Bu, oyununuzun modellerinin ve iç davranışlarının tanımlarını içermelidir. Örneğin, mayın tarama gemisi için bir oyununuz olsaydı, yönetim kurulu ve kare tanımlarının dahili durumlarını nasıl değiştirdikleriyle birlikte burası olurdu.

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;
};

Böylece MineTile this.pristine, bir mayın ( this.hasMine) olan fayanslardan biri olup olmadığı, ancak bir mayının olması gerekip gerekmediğini belirlemeyecek gibi, gösteriliyor veya inceleniyorsa ( ) gibi iç durumunu bilecektir . Bu mantık katmanına kadar olacak. (OOP'ye daha da gitmek için, MineTile genel bir Döşemeden miras alabilir).

Mantık katmanı

Bu, uygulamanın değişen modlar, durum tutma, vb. İle etkileşime gireceği karmaşık yolları barındırmalıdır. Oyun mantığı, örneğin bir oyun sırasında neler olacağını belirlemek veya hangi MineTiles'ın bir mayın sahibi olacağını ayarlamak için ikamet ediyordu. Mantıksal olarak belirlenen parametrelere dayalı somutlaştırılmış seviyeler elde etmek için Entity katmanına çağrılar yapar.

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];
 }
};

Hizmet katmanı

Bu, denetleyicinin erişebileceği yer olacaktır. Oyunları oluşturmak için mantık katmanına erişebilecek. Tamamen başlatılmış bir oyunu veya değiştirilmiş bir oyun durumunu almak için hizmet katmanına üst düzey bir çağrı yapılabilir.

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();
}

kontrolör

Kontrolörler hafif olmalıdır, temel olarak modele müşteri olarak maruz kalan şey budur. Birçok denetleyici olacak, bu yüzden bunları yapılandırmak önemli hale gelecek. UI olaylarına dayalı olarak javascript çağrıları denetleyici işlev çağrıları olacaktır. Bunlar, hizmet katmanında kullanılabilen davranışları göstermeli ve ardından istemci için görünümleri doldurmalı veya bu durumda değiştirmelidir.

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());
};

Görünüm

Görünümler kontrolörün davranışlarına göre düzenlenmelidir. Tuval ile uğraştığından, muhtemelen uygulamanızın en yoğun kısmı olacaklardır.

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();
}

Şimdi bu tek oyun için tüm MVC kurulumuna sahipsiniz. Ya da en azından, tüm oyunu yazmak için çıplak bir kemik örneği aşırı olurdu.

Tüm bunlar yapıldıktan sonra, bir yerde uygulama için küresel bir kapsam olması gerekecektir. Bu, bu senaryoda tüm MVC yığını için ağ geçidi olan geçerli denetleyicinizin ömrünü tutacaktır.

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

MVC kalıplarını kullanmak çok güçlüdür, ancak her nüansına uyma konusunda çok fazla endişelenmeyin. Sonunda, uygulamanın başarılı olup olmadığını belirleyecek oyun deneyimi :)

Göz önünde bulundurmak için: Mimari Astronotların Sizi Korkutmasına İzin Verme Joel Spolsky


thanks @TravisJ - Ben oyun ile ilgili olarak MVC güzel bir açıklama olarak upvoted. Hala belirli noktalardan belirsiz, bence, dediğin gibi, desenlerin nüanslarında bataklığa düşüyorum ve ilerlememi durduruyor. Gördüğüm bir şey, denetleyicide this.view.Select () kullanılmasıydı - bu tür sıkı bir bağlantı gerekli mi yoksa daha fazla ayırma yolu var mı?
wigglyworm

@wigglyworm - Her zaman daha fazla ayırma olabilir! : D Ama gerçekten, kontrolör modelle iletişim kuran ve daha sonra görünümü günceller, böylece muhtemelen çoğu kuplaj MVC'de gerçekleşir.
Travis J

2

İşte zaten yanlış yaptığınız şey - karışıklık durumunda ve kemerinizin altında herhangi bir MVC olmadan bir MVC'yi yuvarladınız.

PureMVC'ye bir göz atın, dil agnostiktir ve aslında MVC yaparak ayaklarınızı ıslatmak için iyi bir platform olabilir.

Kodu küçük ve anlaşılır ve bu da ilerledikçe ihtiyaçlarınıza göre ayarlamanıza izin verecektir.

Onunla küçük bir basit oyun yazmaya başlayın, mayın tarama gemisi iyi olurdu. Travis J'nin söylediklerinin çoğu, özellikle Model hakkında iyidir. Sadece Kontrolörlerin (en azından PureMvc'de) vatansız olduğunu, varolduklarını, BRIEF işlerini yaptıkları ve gittiklerini hatırlamanız gerektiğini eklemeliyim. Onlar bilgili olanlar. Onlar işlev gibidirler. "Izgarayı doldurun, çünkü Model değişti", "Modeli güncelleyin, çünkü bir düğmeye basıldı"

Görüşler (PureMVC'deki Arabulucular) en aptal ve Model sadece biraz daha akıllı. Her ikisi de uygulamayı soyutlar, böylece siz (Kontrolörler) asla doğrudan kullanıcı arayüzüne veya DB'ye dokunmazsınız.

Kullanıcı arayüzünüzün her öğesinin (örneğin bir winforms uygulamasında olduğu gibi) bir Görünümü vardır (Arabulucu - bunun neden şimdi daha iyi bir terim olduğunu görüyorsunuz?), Ancak Arabulucular "Kontrol Rengi" veya "Odak gibi meta-endişeler için de yapılabilir. UI öğelerinde çalışan Yönetici ". Burada katmanlar halinde düşünün.

UI ve DB olayları otomatik olarak Kontrolörleri çağırabilir (akıllı bir adlandırma şeması kullanırsanız) ve bazı Kontrolörler aşamalı olarak kaldırılabilir - bir Model Verileri değişiklik olayını doğrudan dinlemek ve veri paketini teslim etmek için bir Arabulucu yapılabilir.

Bu bir tür hile olmasına ve Modelin dışarıda ne olduğu hakkında biraz bilgi sahibi olmasını ve Arabulucu'nun bir veri paketiyle ne yapacağını anlamasını gerektirmesine rağmen, birçok durumda sıradan Denetçilerle bataklıktan kurtulmanızı sağlayacaktır.

Model: Aptal ama tekrar kullanılabilir; Kontrolörler: Akıllı ama daha az yeniden kullanılabilir (onlar uygulama vardır); Arabulucular: Aptal ama tekrar kullanılabilir. Bu durumda yeniden kullanılabilirlik, başka bir uygulamaya taşınabilir anlamına gelir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.