Javascript MVC application design (canvas)

I’m having difficulty grasping how to structure/architect a canvas application using an MVC like approach in Javascript. UI will be fairly fluid and animated, the games fairly simplistic but with heavy emphasis on tweening and animation. I get how MVC works in principle but not in practice. I’ve googled the buggery out of this, read an awful lot, and am now as confused as I was when I started.

Some details about the application area:

  • multi screen game framework – multiple games will sit within this framework
    common UI “screens” include: settings, info, choose difficulty, main menu etc.
  • multiple input methods
  • common UI elements such as top menu bar on some screens
  • possibility of using different rendering methods (canvas/DOM/webGL)

At the moment I have an AppModel, AppController and AppView. From here I was planning to add each of the “screens” and attach it to the AppView. But what about things like the top menu bar, should they be another MVC triad? Where and how would I attach it without tightly coupling components?

Is it an accepted practice to have one MVC triad within another? i.e. can I add each “screen” to the AppView? Is “triad” even an accepted MVC term?!

My mind is melting under the options… I feel like I’m missing something fundamental here. I’ve got a solution already up and running without using an MVC approach, but have ended up with tightly coupled soup – logic and views and currently combined. The idea was to open it up and allow easier change of views (for e.g. swapping out a canvas view with a DOM based view).

Current libraries used: require.js, createJS, underscore, GSAP, hand rolled MVC implementation

Any pointers, examples etc., particularly with regards to the actual design of the thing and splitting the “screens” into proper M, V or C would be appreciated.

…or a more appropriate method other than MVC

[NB, if you’ve seen this question before it’s because I asked it in 2 other incorrect stackexchange communities… my brain has stopped functioning]

2

MVC has been covered in so many places so there shouldn’t be much to re-iterate here. Essentially you want your object graph, helpers, and logic to be contained in the model tier. The views will be the screens that get pushed out to fill the dynamic part of the page (and may contain a light amount of logic and helpers). And the controller, which be a lightweight implementation to serve the screens based on what was available from the object graphs, helpers, and logic.

Model

This should be where the meat of the application sits. It can be tiered out into a service layer, a logic layer, and an entity layer. What does this mean for your example?

Entity layer

This should house the definitions of your game’s models and internal behaviors. For example, if you had a game for minesweeper, this would be where the board and square definitions were along with how they change their internal state.

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

So the MineTile will know its internal state, such as if it is showing or was examined (this.pristine), if it was one of the tiles that has a mine (this.hasMine) but will not determine if it was supposed to have a mine. That will be up to the logic layer. (To go even further into OOP, MineTile could inherit from a generic Tile).

Logic layer

This should house the complex ways that the application will interact with changing modes, keeping state, etc. So this would be where a mediator pattern would be implemented in order to maintain the state of the current game. This would be where the game logic resided for determining what happens during a game over for example, or for setting up which MineTiles will have a mine. It would make calls into the Entity layer to get instantiated levels based on logically determined parameters.

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

Service layer

This will be where the controller has access to. It will have access to the logic layer for building the games. A high level call may be made into the service layer in order to retrieve a fully instantiated game or a modified game state.

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

Controller

Controllers should be light weight, essentially this is what is exposed as the client to the model. There will be many controllers, so structuring them will become important. Controller function calls will be what the javascript calls hit based on UI events. These should expose the behaviors available in the service layer and then populate or in this case modify views for the client.

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

View

The views should be organized relative to the controller’s behaviors. They will probably be the most intensive part of your application since it deals with canvasing.

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

So now you have your entire MVC setup for this one game. Or at least, a bare bones example, writing the whole game out would have been excessive.

Once this is all done, there will need to be a global scope for the application somewhere. This will hold the lifetime of your current controller, which is the gateway to all of the MVC stack in this scenario.

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

Using MVC patterns are very powerful, but do not worry too much about adhering to every nuance of them. In the end, it is the game experience that will determine if the application is a success 🙂

For consideration: Don’t Let Architecture Astronauts Scare You by Joel Spolsky

2

Here is what you’ve done wrong already — you have hand-rolled an MVC while in a state of confusion, and without any MVC under your belt.

Take a look at PureMVC, it is language agnostic and can be a good platform to get your feet wet with actually doing MVC.

Its code is small and comprehensible, and this will allow you to tweak it to your needs as you progress.

Start out writing a small simple game with it, minesweeper would be good. A lot of what Travis J said is good, especially about the Model.
I would only add that you need to remember that Controllers (at least in PureMvc) are stateless, they come into existence, do their BRIEF work and go away. They are the knowledgeable ones. They are like functions. “Fill the grid, cuz the Model changed”, “Update the Model, cuz a button was pushed”

The Views (Mediators in PureMVC) are the dumbest, and the Model is only slightly smarter. Both abstract the implementation, so you (Controllers) never directly touch UI or DB.

Every element of your UI (like in a winforms app for example) has a View (Mediator – you see why this is a better term now?), but Mediators can also be made for meta-concerns like “Control Color” or “Focus Manager” which operate across UI elements. Think in layers here.

UI and DB events can automatically invoke Controllers (if you use a smart naming scheme), and certain Controllers can be phased out — a Mediator can be made to directly listen for a Model Data change event and be delivered its data package.

Although this is kind of a cheat and requires the Model to know a bit about what is out there, and the Mediator to understand what to do with a data package, but it will keep you from getting swamped with mundane Controllers in many cases.

Model: Dumb but resusable; Controllers: Smart but less reusable (they ARE the app); Mediators: Dumb but reusable.
Reusability in this case means portable to another app.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật