Click here to Skip to main content
15,884,298 members
Articles / Web Development / HTML

BrainVita Game using JQuery

Rate me:
Please Sign up or sign in to vote.
4.38/5 (8 votes)
16 Mar 2010CPOL3 min read 44K   463   9   9
Using JQuery features to implement BrainVita Game

Introduction

How to play the game?

BrainVitaBoard.png

You jump one marble horizontally/vertically over another to an empty space. A marble can jump over only one piece at a time. Other moves are considered not valid. The marble that is 'jumped over' is removed from the board. Your motive is to leave least no. of pieces on the board. That is in the end only one marble is to be left over on the board.

You move like this:

  1. Drag the marble marked '1'
  2. Check the empty space marked '3'
  3. Empty the marble marked '2'

Basically marble '1' has jumped over marble '2' and moved to '3'. Marble '2' is removed from board, empty space '3' gets occupied by the marble that was moved from position '1'.

Background

JQuery has a rich set of feature rich JavaScript library. JQuery gives a big advantage of being cross browser, animation, rich UI interactions, drag and drop facility, etc. Using the same features, we can build a small game called BrainVita. Basic knowledge of JQuery is essential to go through this article. The Google APIs are loaded from the Google website and hence the user needs to be connected to the internet for the game to work.

Using the Code

Create an HTML page and put a layout to create the game board.

HTML
<table border="0" cellpadding="1" cellspacing="1" style="border: solid 1px green">
      <tr>
          <td align="center"><button id="reset">Reset Board</button><br />
          </td>
      </tr>
      <tr>
          <td>&nbsp;</td>
      </tr>
      <tr>
          <td>
              <div id="Brainvita"></div>
          </td>
      </tr>
  </table>

Define a table layout for formatting.

Define a button named "reset" which helps us in resetting the BrainVita game board.

Define div tag with id "BrainVita" as a placeholder for the game board to be drawn using a JavaScript function explained a little later.

Load the JQuery API through the generic API load function provided:

JavaScript
<!--load the Google api loader-->
 <script type="text/javascript" src="http://www.google.com/jsapi"></script>

 <!--load the specific api required-->

 <script type="text/javascript">
     google.load('jquery', '1.3.2');
     google.load('jqueryui', '1.7.2');
 </script>

Set the button "reset" button click event handler and draw the board on load of the page.

JavaScript
/// Click event handler for the Reset Board button
$(document).ready(function()
{
    // attach the click event handler for the
    // reset board button
    $('#reset').click(function ()
    {
        // redraw the board
        DrawBoard();
        //$('#messages').text('Resetting the board..Complete!');
    });

    // Load the board on load of the window
    DrawBoard();
});

$(document).ready(function()) behaves as a window.onLoad function in Javascript.

$('#reset').click(function ()) attaches click event handler to the button named "reset". DrawBoard() function prepares the BrainVita game board to start the game on load of the page.

DrawBoard() function does the following. Prepare the game board.
Note: Put the Red.png image file in the same directory as your HTML file.

JavaScript
// empty the div element first
$('#Brainvita').empty();

// Build the Board
var gameBoard = "<table border='0' cellspacing='3' cellpadding='2'>";
for(var rows = 0; rows < 7; rows++)
{
    gameBoard+= "<tr>";
    for(var cols = 0; cols < 7; cols++)
    {
        var imgId = " id = 'i" + rows + cols + "' ";
        var divId = " id = 'd" + rows + cols + "' ";
        var altValue = " alt = 'i" + rows + cols + "' ";
        if(rows < 3 && cols > 1 && cols < 5)
        {
            gameBoard+= GetImageMarble(divId, imgId, altValue);
        }
        else if(rows > 1 && rows < 5)
        {
            // the center marble
            if(rows == 3 && cols == 3)
            {
                gameBoard+= GetEmptyMarble(divId);
            }
            else
            {
                gameBoard+= GetImageMarble(divId, imgId, altValue);
            }
        }
        else if(rows > 4 && cols > 1 && cols < 5)
        {
            gameBoard+= GetImageMarble(divId, imgId, altValue);
        }
        else
        {
            // other non usable marble slots on the board
            gameBoard+= "<td></td>";
        }
    }

    gameBoard+= "</tr>";
}

gameBoard += "</table>";

// attach the newly created table
// to the Brainvita div tag
$('#Brainvita').html(gameBoard);

Now attach the draggable event handler for the image tags whose id starts with "I". Please note that revert attribute it says if it's invalid then return back to the original position of the object which is being dragged.

JavaScript
// now build the drag and drop system
        $("img[id^='i']").draggable({ containment: '#Brainvita',
                revert: 'invalid',
                tolerance: 'fit'}); 

Now attach the droppable event handler for all the div tags whose id starts with "d". This contains the logic to determine whether the move is valid or not.

Important attributes to notice in the droppable event handler are:

  • accept attribute tells the function when the droppable object is acceptable or not. If the move is valid, the function returns true, else false. This causes the marble dragged to come to the starting position.
  • drop attribute tells the function what actions are to be performed once the draggable object is accepted.
JavaScript
$("div[id^='d']").droppable({
			accept: function(event) {
			    var returnFlag = false;
			    if(event[0].nodeName == "IMG")
			    {
			        var destId = this.id;
                    var srcId = event[0].id;
                    var destNo = parseInt(destId.substring(1,3));
                    var srcNo = parseInt(srcId.substring(1,3));
                    var result = Math.abs(destNo - srcNo);
                    var removeNo = 0;

                    // check if the destination div tag is empty
                    // if empty then invalid move
                    if($(this).length == 1 && result != 0)
                    {
                        switch(result)
                        {
                            case 2:
                                // horizontal move
                                removeNo = ((destNo - srcNo) > 0) ?
					destNo - 1 : destNo + 1;
                                break;
                            case 20:
                                // vertical move
                                removeNo = ((destNo - srcNo) > 0) ?
					destNo - 10 : destNo + 10;
                                break;
                        }

                        if((result == 2 || result == 20) && removeNo != 0)
                        {
                            // valid move remove the middle marble
                            var elementToBeRemoved = (removeNo < 10) ? "0" +
						removeNo : removeNo;

                            // make sure the inbetween item has an img item
                            if($("#i" + elementToBeRemoved).length == 1 &&
                            $("#i" + ((destNo < 10) ? "0" + destNo : destNo)).length == 0)
                            {
                                // valid move
                                returnFlag = true;
                            }

                            // log the trace
                            //$("#Trace").append("<BR>Accept Event destId=" +
                            //destId + " srcId=" + srcId + " destNo=" + destNo +
                            //" removeNo=" + removeNo + " returnFlag=" + returnFlag);
                        }
                    }
                }
                return returnFlag;
			},
			hoverClass: 'board-state-Active',
			drop: function(event, ui) {
			    var destId = this.id;
                var srcId = ui.helper.context.id; //event.srcElement.id;
                var destNo = parseInt(destId.substring(1,3), 10);
                var srcNo = parseInt(srcId.substring(1,3, 10));
                var result = Math.abs(destNo - srcNo);
                var removeNo = 0;

                // check if the destination div tag is empty
                if($(this).length == 1 && result != 0)
                {
                    switch(result)
                    {
                        case 2:
                            removeNo = ((destNo - srcNo) > 0) ? destNo - 1 : destNo + 1;
                            break;
                        case 20:
                            removeNo = ((destNo - srcNo) > 0) ? destNo - 10 : destNo + 10;
                            break;
                    }

                    // Check to see if the move is valid
                    if((result == 2 || result == 20) && removeNo != 0)
                    {
                        // swap the id and alt value so as to recognize next time
                        ui.helper.context.id = "i" + ((destNo < 10) ? "0" +
						destNo : destNo);
                        ui.helper.context.alt = ui.helper.context.id;

                        // frame the element to be removed id
                        var elementToBeRemoved = (removeNo < 10) ? "0" +
						removeNo : removeNo;

                        // remove the inbetween item has an img item
                        if($("#d" + elementToBeRemoved).length == 1)
                        {
                            // remove the inbetween item
                            $("#i" + elementToBeRemoved).remove();

                            // empty the div tag
                            $("#d" + elementToBeRemoved).empty();

                            // log the trace
                            //$("#Trace").append("<BR>Drop Event: destId=" +
                            //destId + " srcId=" + srcId + " destNo=" + destNo +
                            //" removeNo=" + removeNo);
                        } // end if
                    } // if((result == 2 || result == 20) && removeNo != 0)
                } // if($(this).length == 1 && result != 0)
	} // end of function
}

The other JavaScript helper functions are below:

JavaScript
/// Gets a table column with  a marble in it
    function GetImageMarble(divId, imgId, altValue)
    {
        var imgTag = "<td align='center' valign='middle'><div ";
        imgTag = imgTag + divId;
        imgTag = imgTag + "><img ";
        imgTag = imgTag + altValue + imgId;
        imgTag = imgTag + " src='";
        imgTag = imgTag + "Red.PNG'";
        imgTag = imgTag + " class=\"marble\"></div></td>";
        return imgTag;
    }

    /// Gets an empty table column
    function GetEmptyMarble(divId)
    {
        return "<td><div " + divId + "></div></td>";
    }

Add these styles between the Head tag of your HTML Page:

CSS
<style type="text/css">
.marble { width: 48px; height: 48px; border: 0px;position:inherit; top:0px; left:0px}
.marbleHover { width: 40px;height:40px; border:2px; border-color:red}
.divclass {border: 1px solid blue; width: 50px;height:50px; text-align:center;}
.board-state-Hover {border: 2px solid red; width: 50px;height:50px;}
.board-state-Active {border: 1px solid green; width: 50px;height:50px;}
</style>

Points of Interest

Being new to JQuery myself, I thought I will write my favorite game to understand the drag and drop features of JQuery. The API provides a very simple and new way of writing JavaScript code which is very easy to understand and learn as well. There is good documentation available as well on www.jquery.com.

License

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


Written By
Architect XChanging
India India
Working as Dotnet Architect as Xchanging Singapore

A Computer Science Graduate with over 11 years of Experience in software development. Significant experience in SDLC with technical expertise in Architecting .NET Enterprise solutions and Web applications using .NET Patterns ASP.NET, C#, Web Services, SOA.

Comments and Discussions

 
GeneralMy vote of 4 Pin
ahagel16-Apr-12 15:06
professionalahagel16-Apr-12 15:06 
GeneralRe: My vote of 4 Pin
Gana16-Apr-12 17:05
Gana16-Apr-12 17:05 
BugSmall bug - marble inside box alignment Pin
ahagel16-Apr-12 15:05
professionalahagel16-Apr-12 15:05 
GeneralRe: Small bug - marble inside box alignment Pin
Gana16-Apr-12 17:05
Gana16-Apr-12 17:05 
SuggestionIE problem fixed Pin
Brakster9-Apr-12 1:34
Brakster9-Apr-12 1:34 
GeneralRe: IE problem fixed Pin
Gana16-Apr-12 17:06
Gana16-Apr-12 17:06 
Thanks for pointing out the issue and the resolution
Thanks for your comments
GeneralMy vote of 5 Pin
k8ganda13-Jan-11 2:03
k8ganda13-Jan-11 2:03 
GeneralNice Game [modified] Pin
Khaniya16-Mar-10 21:08
professionalKhaniya16-Mar-10 21:08 
GeneralRe: Nice Game Pin
Gana17-Mar-10 18:10
Gana17-Mar-10 18:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.