DevPocalypse ? A *Basic* Asp.Net MVC + jQuery Game

Last weekend I had the privilege of speaking at the second Northern Virginia CodeCamp of the year, thanks to an invitation from Jeff Schoolcraft. For those of you who were able to make it to the event, thanks for attending, and make sure to fill out an eval! For those of you who didn’t make it (or those who did and want a deeper peek at the code I presented), feel free to check out the code to my sample app – posted below.

DevPocalypse

ASP.Net MVC + jQuery = Simple Multiplayer Action

The basic idea of the game is that multiple players can exist on a grid (a “screen”) and move around to unoccupied spaces (“blocks”) adjacent to their current location. I had grand hopes of being able to click another player to attack them and include some basic chat, but alas, it was not meant to be. At least not for this presentation. My hope is to continue working on this as a single sample app I can use to illustrate various MVC techniques for future speaking engagements.

Let’s take a gander at what the app looks like when it is running:

DevPocalypse-Screenshot

Yup, like I said: basic. So those two little guys are players. You can’t see it in a screenshot, but when you click a square next to where your player is standing, jQuery will smoothly animate the transition of your character from the current block to the new block. What is even neater is that when a player on a different computer moves their player, you also see the same jQuery animation execute. How are we doing this? Well first we use a simple polling script (from Game.js):

   1: $(document).ready(function() {
   2:     updateScreen();
   3:     setInterval(updateScreen, updateFrequency * 1000);
   4: });

Ultimately, this code calls an action named GetCurrentScreen on the GameController. Currently this executes twice a second so as to be nice and responsive, but of course I have no idea how that would handle under load. Here is the entire GameController class:

   1: using System;
   2: using System.Linq;
   3: using System.Web.Mvc;
   4: using DevPocalypse.Domain;
   5: using DevPocalypse.Domain.Repositories;
   6: using DevPocalypse.Website.App.ModelBinders;
   7:
   8: namespace DevPocalypse.Website.Controllers
   9: {
  10:     [Authorize]
  11:     public class GameController : Controller
  12:     {
  13:         public ICharacterRepository CharacterRepository { get; set; }
  14:         public IScreenRepository ScreenRepository { get; set; }
  15:
  16:         public ViewResult Index()
  17:         {
  18:             ViewData["Title"] = "Play!";
  19:             return View();
  20:         }
  21:
  22:         public JsonResult GetCurrentScreen(
  23:             [ModelBinder( typeof( CurrentCharacterBinder ) )]
  24:             Character currentCharacter
  25:             )
  26:         {
  27:             // IE will cache aggressively if we don't set our expiration date
  28:             Response.ExpiresAbsolute = DateTime.Now.AddYears( -1 );
  29:
  30:             // get screen character is on, and a list of all characters on that screen
  31:             var screen = ScreenRepository.Retrieve().Where( s => s.ID == currentCharacter.ScreenID ).Single();
  32:             var characters = CharacterRepository.Retrieve().Where( c => c.ScreenID == screen.ID ).ToList();
  33:             return Json( new { Screen = screen, MyCharacter = currentCharacter, Characters = characters } );
  34:         }
  35:
  36:         public void MoveTo(
  37:             [ModelBinder( typeof( CurrentCharacterBinder ) )]
  38:             Character currentCharacter,
  39:             int x,
  40:             int y
  41:             )
  42:         {
  43:             currentCharacter.X = x;
  44:             currentCharacter.Y = y;
  45:             CharacterRepository.Update( currentCharacter );
  46:         }
  47:     }
  48: }

Pretty simple, huh? Note how nice and easy it was to return an anonymous type as a JSON (JavaScript Object Notation) object via the Json(obj) method. Finally, here is the bit of Game.js that performs the actual animation (this is done in a loop updating all characters – hence the id and c variables):

   1: $("#" + id).animate({
   2:     left: currentCharacters[c].X * 33,
   3:     top: currentCharacters[c].Y * 33
   4: }, updateFrequency * 1000 / 4);

Gotta love jQuery. :-) There is plenty more to look at in the source, so feel free to download it, check it out, play around with it – use it for whatever you want.

Thanks, and I hope to see you at the next CodeCamp!

Download: DevPocalypse.zip (762.63 kb)