Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Hosted-services / Azure

An Experiment in HTML5 Gaming

5.00/5 (6 votes)
20 May 2013CPOL11 min read 28K   255  
Using Windows Azure to build an online board game.

 

Introduction 

This article was created as part of the Windows Azure Developer Challenge, which is made up of five challenges designed to explore different services provided by Windows Azure. Over the next few weeks, we will be updating this article as we tackle each challenge. 

Our Story  

 

As geeks, we have geeky friends and geeky pastimes such as Game Night. Game Night was a monthly opportunity to unashamedly act like geeks for hours. We sat around the table, consumed adult beverages, played board games, and over analyzed each player's strategy and tactics after the game ended. Full time jobs, significant others, and a few babies later and Game Night was no more. Our passion for playing games, however, never wavered.  

Recently, a few of us have been kicking around the idea of bringing Game Night back, but we wanted to do it in a very cool way.  Being web developers, we decided to explore the idea of creating an online board game.  Such a game could take place over several days or even weeks and could be played on our own time. 

This contest gave us the perfect opportunity to explore implementing this idea. 

 

Why Azure 

With Windows Azure, we do not have to be network/database gurus to publish an application online and can instead focus on core implementation. Because setting up or modifying services is so streamlined, we have the freedom to experiment with different applications and not invest a significant amount of time in creating the infrastructure. 

What Lies Ahead 

Below is an overview of what we will be covering in each challenge. 

 

  1. Getting Started - You just read it! Smile | <img src= 
  2. Build a Website - We will walk through how to quickly spin up a website using Windows Azure.  We’ll also explore how to use SignalR to create the game lobby. 
  3. Using SQL on Azure - We will create a simple game and use a database to store various information.
  4. Virtual Machines - We will show how to migrate an existing application to a VM to improve scalability and explore opportunities to enhance the application.
  5. Mobile Access - We will create a mobile application that will keep track of players’ games and manage notifications.

Building a Website

 

When we get together for Game Night our first course of action is sitting around the table to catch up on the game of life and select the night’s game. To recreate this experience, we will create a Lobby on the site where everyone gathers before the gaming begins. 

We will explore how to connect our new Windows Azure site to Team Foundation Service, create the Lobby, and deploy.  

The Infrastructure 

We will not recreate the outstanding tutorials provided by Microsoft on the Windows Azure site for creating a new website. If you need some help getting started, go here.  

In this section, we will tie Team Foundation Service, Visual Studio, and Windows Azure together to help manage source control and deployments. 

Linking Team Foundation Service to Visual Studio

The first step to building out our infrastructure is to set up some form of source control and connect it to Visual Studio. Feel free to use any flavor of source control you prefer but for the purposes of this tutorial, we will utilize Team Foundation Service. 

Team Foundation Service is a cloud-hosted service version of Microsoft’s popular Team Foundation Server software. As of this writing, TFS is still in preview and you can sign up for free here. Once you have signed up, you will want to create a new team project. The details of the project are up to you. After the project has been created we will need to link the Visual Studio to TFS.

From your main team project page, click the “Open new instance of Visual Studio” link in the Activities section.  

 

Image 2

 

When Visual Studio opens you will see your TFS account in Team Explorer. 

Adding a solution to Team Foundation Service 

Open an existing solution, or create a new one in Visual Studio. For this demo, we are using the Base template of an ASP.NET MVC4 project. Right-click on the solution, and select Add Solution to Source Control.

 

Image 3

 

Accept or change the defaults and choose the OK button. Once the process completes, open the shortcut menu of the solution and choose "Check In...". 

Connecting the project to Windows Azure

Now that source control is set up, we will want to connect the team project to our Windows Azure website. When we do this, we gain a number of benefits.  We will be able to set up automatic deployment, view our deployment history, and even roll back our website to a previous build if things go wrong.  

To start, go to your Windows Azure portal and select your website. On the Quick Start page choose "Set up deployment from source control".  

In the wizard, select Team Foundation Service and then type in the name of your TFS account (https://youraccount.visualstudio.com). You may be asked to enter your password. 

Image 4 

 

When the popup dialog appears, choose Accept to authorize Azure to configure your team project in TFS.

When authorization succeeds, you will see a dropdown containing a list of your TFS team projects. Select the name of team project that you created in the previous steps and click accept. 

In these few short moments we have successfully set up a new TFS team project, which provides you and your team members cloud-based source code, build management, agile development and issue item tracking. We have also tied that team project to Windows Azure for greater control over deployments, and we have a great IDE for coding. 

Windows Azure, Visual Studio, and Team Foundation Service allowed us to quickly build out this robust infrastructure which will save us time down the road.   

Now we can begin coding! 

Creating a Lobby 

In this section we will explore using SignalR to enable some of the key features in the Lobby. SignalR is an awesome wrapper package that sits on top of WebSockets and allows real-time communication between the client and server. For more info, check out the SignalR site here

To get started, add the SignalR NuGet package to the Web project. Using the Package Manager Console, type the following. 

Image 5

 

Using the GUI, search SignalR and select Microsoft ASP.NET SignalR. 

 

Image 6

 

We will also want to make sure our project has a reference to jQuery. If you used one of the MVC4 templates (except Empty) you should be good to go. 

Now that the project has all of the necessary SignalR references, we will create a simple chat feature in the lobby so that users can communicate with one another. 

The first step to getting SignalR initialized is to register the default routes to SignalR hubs. Add the line "RouteTable.Routes.MapHubs()" to the global.asax Application_Start method.  Make sure it is above the normal routes call.  

 

C#
RouteTable.Routes.MapHubs();
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes); 

 

The next step is to create a SignalR Hub.  We will name this one LobbyHub.

 

public class LobbyHub : Hub
{ 
    public void Send(string name, string message)
    {
        Clients.All.addNewMessage(name, message);
    }
    public void Login(string name, string color)
    {
        Clients.All.addNewUserToList(name, color);
    }
} 

 

 

The method “Login” will be called when a user first enters the lobby and “Send” will be called whenever a user sends a message.  

 

Now let’s make the view.  Create a Home Controller and an Index view.  This view will be our main lobby and will contain a user list, a chat box, and a text box for writing your messages.

 

@Html.Hidden("displayName")
@Html.Hidden("displayColor")
<div>
    @Html.TextBox("message")
    <button id="sendmessage">Send</button>
</div>
<div class="chat-window main">
    <h2>Chat</h2>
    <ul id="discussion"></ul>
</div>
<div class="chat-window side">
    <h2>Users</h2>
    <ul id="userList"></ul>
</div>

 

 

 

 

If you'd like, use this CSS in your Site.css file.  It's nothing fancy, but it'll make the page look good enough for testing. 

.player-box {
    position: fixed;
    top: 100px;
    left: 500px;
    border: 1px solid #333;
    width: 100px;
    height: 100px;
    text-align: center;
    -moz-transition: -moz-transform 1s;
    -webkit-transition: -webkit-transform 1s;
    transition: transform 1s;
}
.large { width: 200px; height: 200px; }
.spin {
    -moz-transform: rotateZ(360deg);
    -webkit-transform: rotateZ(360deg);
    transform: rotateZ(360deg);
}
.chat-window {
    display: inline-block;
    vertical-align: top;
    border:1px solid #333;
    height:400px;
    overflow-y:scroll;
}
    .chat-window.side { width:15%; }
    .chat-window.main { width:50%; } 
.controls {
    border: 1px solid #333;
    margin-top: 10px;
    width: 300px;
}
    .controls div {
        display: inline-block;
        border: 1px solid #666;
        background-color: #F5F5F5;
        padding: 5px;
        margin: 10px;
        text-align:center;
} 

 

 

 

Now lets hook up SignalR.

 

@section scripts {
    <script src="~/Scripts/jquery-2.0.0.js"></script>
    <script src="~/Scripts/jquery.signalR-1.0.1.js"></script>
    <script src="~/signalr/hubs"></script>
    <script>
        $(function () {
            var lobby = $.connection.lobbyHub,
                $displayName = $("#displayName"),
                $displayColor = $("#displayColor");
            lobby.client.addNewMessage = function (name, message) {
                $("#discussion").append("<li><strong>" + htmlEncode(name) + "</strong>: " + htmlEncode(message) + "</li>");
            };
            lobby.client.addNewUserToList = function(name, color) {
                $("#userList").append("<li><span style='color:" + color + ";'>" + htmlEncode(name) + "</span>");
            };
            $displayName.val(prompt("Enter your name:", ""));
            $("#message").focus();
            $.connection.hub.start().done(function () {
                var color = getRandomColor();
                $displayColor.val(color);
                lobby.server.login($displayName.val(), color);
                $("#sendmessage").click(function () {
                    var $message = $("#message");
                    lobby.server.send($displayName.val(), $message.val());
                    $message.val("").focus();
                });
            });
        });
        function getRandomColor() {
            var colors = ["blue", "yellow", "red", "black", "green", "darkgrey"];
            var selectedColor = colors[Math.floor(Math.random() * colors.length)];
            return selectedColor;
        };
        function htmlEncode(value) {
            var encodedValue = $("<div />").text(value).html();
            return encodedValue;
        };
    </script>
} 

 

 

 

 

 

 

 

That's a lot to take in.  Let’s try to go through what we just did.

 

The first three lines are the references we need to get everything working. The script “~/signalr/hubs” is automatically generated by the runtime on the first request and then cached. It will contain all the magical logic SignalR needs to talk with the LobbyHub.

 

Next, we setup our variables and define the two functions our Hub will use. Remember that “Send” called “addNewMessage” and “Login” called “addNewUserToList”. 

 

Finally, we set up the hub connection and bind necessary events and objects in the DOM. Note that “lobby.server.login” will go to the LobbyHub and execute the “Login” method passing the correct parameters.

 

That’s it! Build and run your site. Any message you type into the chat will immediately be rendered on all other clients accessing this page. 

 

More fun with SignalR 

Chatting is fun and all, but this is going to be a game site, so we should make the page a little more interactive. Let’s make a mini-game! In this mini-game, the user will make a box appear on the screen with their corresponding display color. They can then move the box around, resize it, and even make it spin (why not? Smile | <img src= ).

 

First, lets make a new Hub. Call this one BoxHub. 

 

public class BoxHub : Hub
{ 
    public void Create(string name, string color)
    {
        Clients.All.create(name, color);
    }
    public void Move(string name, int keyCode) 
    {
        Clients.All.move(name, keyCode);
    }
}

 

 

There are two methods here. Both are pretty straight forward. One creates the box, and the other will be in charge of moving it. 

 

Back on our Index view, we need to add a few more elements to our page. We’ll add a play button to create the box, and a box container div that will hold all the newly created boxes. The new code is in bold

 

@Html.Hidden("displayName")
@Html.Hidden("displayColor")
<div>
    @Html.TextBox("message")
    <button id="sendmessage">Send</button>
    <button id="play">Play</button>
</div>
<div class="chat-window main">
    <h2>Chat</h2>
    <ul id="discussion">
    </ul>
</div>
<div 
class="chat-window side">
    <h2>Users</h2>
    <ul id="userList"></ul>
</div>
<div class="controls">
    <h2>Controls</h2>
    <div>Z</div>
    <div>X</div>
    <div>&#8592;</div>
    <div>&#8593;</div>
    <div>&#8595;</div>
    <div>&#8594;</div>
    <div>Enter</div>
</div>
<div id="boxContainer"></div> 

 

 

 

 

 

 

Finally, let’s update our javascript. We will need to add a connection to BoxHub and define the new create and move functions.  

 

var lobby = $.connection.lobbyHub,
    box = $.connection.boxHub,
    $displayName = $("#displayName"),
    $displayColor = $("#displayColor");
box.client.create = function(name, color) {
    $("#boxContainer").append("<div id='playerBox_" + name + "' class='player-box' style='background-color:" + color + ";'></div>");
};
box.client.move = function (name, keyCode) {
    var $playerBox = $("#playerBox_" + name);
    switch (keyCode) {
                    case 39: // right 
                        $playerBox.css("left", "+=50");
                        break;
                    case 37: // left
                        $playerBox.css("left", "-=50");
                        break;
                    case 38: // up
                        $playerBox.css("top", "-=50");
                        break;
                    case 40: // down
                        $playerBox.css("top", "+=50");
                        break;
                    case 90: // Z
                        if ($playerBox.hasClass("large")) {
                            $playerBox.removeClass("large");
                        } else {
                            $playerBox.addClass("large");
                        }
                        break;
                    case 88: // X
                        if ($playerBox.hasClass("spin")) {
                            $playerBox.removeClass("spin");
                        } else {
                            $playerBox.addClass("spin");
                        }
                        break;
                    case 13: // Enter
                        break;
    }
}; 

In our hub connection area, we need to add the new DOM bindings.

 

$.connection.hub.start().done(function () {
    var color = getRandomColor();
    $displayColor.val(color);
    lobby.server.login($displayName.val(), color);
                
    $("#sendmessage").click(function () {
        var $message = $("#message");
        lobby.server.send($displayName.val(), $message.val());
        $message.val("").focus();
    });
    $("#play").click(function() {
        box.server.create($displayName.val(), $displayColor.val());
        $("#play").attr("disabled", "disabled");
    });
    $(document).keydown(function (e) {
        if (e.which == 39 || e.which == 37 || e.which == 38 ||
             e.which == 40 || e.which == 90 || e.which == 88 ||
             e.which == 13) {
            box.server.move($displayName.val(), e.which);
        }
    });
}); 

 

 

 

Build this and run the project. When you click the “Play” button, your player box will appear! You can move it around with the arrow keys, resize it with ‘Z’ and make it spin with ‘X’.

Go ahead and check in this code and Windows Azure will handle the deployment!   

 

Challenge Two Wrap-Up

We have covered a lot of ground - from source control to deployment to chat to movable colored boxes - in this challenge. If you'd like a closer look at our code, feel free to download the source at the top of this article. Alternately, you can visit the site we set up for this competition: http://proprane.azurewebsites.net  

Be on the lookout for the Bob! He is surely hiding somewhere in that page. In the next challenge, we will look at integrating SQL with our website to aid in authentication and authorization, improve our SignalR implementation, and more! Stay tuned!

Using SQL on Azure  

We want to give the user to ability to log in, track games played and wins and losses.  This will require a database of some kind.  Thankfully, Azure makes it very easy for us to create a database and hook it up to our site.

We don't want to do the normal thing here, we are going to try to push ourselves a bit.  Since Windows Azure lets us create 10 free websites, we thought it would be cool to put all those to use.  We will have a central API site that connects to our main user db.  All login and player stats will be stored there and every game we create can call it.

The lobby and each game we create are their own separate websites as well.  This grants us a number of benefits.  It’ll keep the code clean, allow us to track enhancements and bug fixes independently of each other, and it shares the server load.  If everything was on one website it would get bogged down pretty quickly.

Creating a Web API Project 

In this section we will go through creating a db that stores general user information.  We will also create the Web API project that will connect to it. 

From Chat to a Dashboard 

Lets take the chat site we made earlier and enhance it to be a full on user dashboard.

Playing a Game 

Finally!  Okay, there isn't anything special here, but we will create a simple game that the player can interact with and then save info back to our central db.  This will be more of a proof of concept than an actual game.  That comes in the next challenge! 

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)