Developing a Dice Game Using ASP.NET Futures Drag and Drop Techniques

Nowadays, with Ajax being used by more and more web applications, drag & drop support to some degree becomes the magic weapon for various heavyweight Ajax frameworks. As one of the famous Ajax solutions, Microsoft ASP.NET AJAX has not declined to shoulder responsibility and put forward its own server-side and client-side drag & drop solutions. However, in this article, we’ll focus on ASP.NET AJAX client-side drag & drop programming with the development of a simple dice game.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 13
April 09, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Drag & drop is the tremendous improvement within the desktop applications area that has vastly increased software application efficiency. However, it is a pity that JavaScript itself does not provide built-in support for the mouse drag & drop operation. Later, with the introduction of DHTML techniques various, browsers started to bring forward their own drag & drop solutions. To eliminate the differences between the solutions provided by various browsers, multifarious JavaScript libraries turned out, whose goals are nearly all the same: providing a cross-browser compatible solution and simplifying drag & drop programming.

Author's Note: To follow along with the dice game development in this article, you're assumed to have installed Visual Studio 2005 and at least the two components of ASP.NET AJAX, which are ASP.NET 2.0 AJAX Extensions and ASP.NET Futures July 2007. In addition, it is highly advisable that you download the source files accompanying this article.

Drag & drop support by ASP.NET Futures

In this section, we’ll first explore the inner workings of cross-browser drag & drop client-side support byASP.NET Futures. To achieve a drag & drop operation, we should take into consideration three factors:

—Draggable items - DOM elements that can be moved around the page, while drop targets are elements that act as "containers" for draggable items. The MS AJAX framework allows us to define draggable elements by implementing theIDragSource interface.

—Drop targets - a class that implements theIDropTargetinterface. In fact, we can also create a class that implements both theIDragSourceandIDropTargetinterfaces.

—DragDropManager - a global object that is instantiated at runtime and is generally used to launch dragging operations and to register drop targets. As you may have doped out, the DragDropManager serves as the headquarters for the whole drag & drop operation by invoking the corresponding methods of the interfaces IDragSource and IDropTarget.

Thus, we can take the following steps to create a drag & drop UI:

—Create draggable items by implementing the IDragSource interface. The class that implements this interface is also responsible for calling the Web.UI.DragDropManager.startDragDrop() method in order to start the dragging operation (typically, this is done via an event handler for the mousedown event of the control's element). Each draggable item has its owndataType, which is an identifier that allows you to group draggable items (the predefined dataType isHTML).

—Create drop targets by implementing the IDropTarget interface. A class that implements this interface is responsible for registering the drop target by invoking the Web.UI.DragDropManager.registerDropTarget() method. Each drop target has a list of accepted DataTypes that specify what "types" of draggable items can be dropped on that target.

Author's Note: Within the file PreviewDragDrop.js, which is shipped with ASP.NET Futures, there are only a pair of built-in behaviors (i.e. DragDropList and DraggableListItem) that support the drag & drop operation. Therefore, to gain a more intensive comprehension of the IdragSource, IdropTarget, and DragDropManager interfaces, as well as the relations between them, the recommended approach is to further study the source code of the DragDropList and DraggableListItem behaviors in the PreviewDragDrop.js file. Once you have grasped the main ideas of the two behaviors, you are sure to reach the summit of ASP.NET AJAX-related drag & drop programming.

Now, let’s concentrate on the main idea of this article, which is developing a dice game with drag & drop support.

Let’s first take a quick look at the final result we hope to achieve.

Visualizing the finish line

In the dice game, we are to create two custom behaviors that are inherited from the IDragSource and IDropTarget interfaces respectively, and perform drag & drop operations at the proper times with the help of the DragDropManager object.Figure1shows theinitialrun-time snapshot of thedice game (CustDragDropDemo.aspx). Here theplayercandrag one of the six dice at the top onto the lower-bottom box with a question mark in it. The question mark will then be replaced with the number of dots the player picks. Of course, as a rule, the six die at the top should be positioned at random with the dot number ranging from one to six.

Figure 1—the initial run-time snapshot of the dice game

Figure2showsone of therun-time snapshots of thedice game, where the player has selected a die with five dots.When the player clicks ‘Restart the game,’ the box at the lower bottom again displays a question mark and the six numbers (1~6) have also been repositioned randomly under the six small boxes with the back covers being the same pattern.

This kind of game is pretty simple in desktop application scenarios. However, in web areas, it is still difficult to tackle, mainly because of the incompatibility between browsers. Next let's dig into the how-to solutions.

Create an ASP.NET AJAX CTP-Enabled Web Site

Launch Visual Studio 2005 and then select the "File | New Website…" menu item to create a new website using the template named "ASP.NET AJAX CTP-Enabled Web Site." Name the projectClientDragDropTest (select Visual C# as the built-in language). After that, the system should automatically add references to the necessary assemblies—Microsoft.Web.Preview.dll and System.Web.Extensions.dll (you cannot see it, since it’s put into .NET GAC). And also, you can see aScriptManagerserver control automatically added to the Default.aspx page. Simply put, this server control acts as the control center for the entire ASP.NET AJAX framework. Finally, rename the Default.aspx file to CustDragDropDemo.aspx.

Next, let’s delve into how to construct the two client-side behaviors that we will utilize in this game.

Defining the two behaviors: MagicDragSourceBehavior and MagicDropTargetBehavior

Obviously, the six dice represent the drag sources. Therefore, we can define a custom behavior named MagicDragSourceBehavior. By attaching this behavior to the six client-side controls that are associated with the six dice, we can make the six die-related DOM elements draggable.

For analysis, we list the source code of MagicDragSourceBehavior, which is shown below:

Type.registerNamespace('Custom.UI');

Custom.UI.MagicDragSourceBehavior = function(element)

{

Custom.UI.MagicDragSourceBehavior.initializeBase(this, [element]);

//defined the mousedown event listener

this._mouseDownHandler = Function.createDelegate(this,

this.mouseDownHandler);

this._dragDropMagic=null;

this._visual = null;

}

Custom.UI.MagicDragSourceBehavior.prototype =

{

get_dragDropMagic: function()

{

return this._dragDropMagic;

},

set_dragDropMagic: function(dragDropMagic)

{

this._dragDropMagic = dragDropMagic;

},

//get the data type of the draggable object

//here we specify the data type must be DragDropMagic

get_dragDataType: function()

{

return 'DragDropMagic';

},

//get the data that is held in the draggable object

getDragData: function(context)

{

return this._dragDropMagic;

},

//specify the drag mode to be ‘Copy’

get_dragMode: function()

{

return Sys.Preview.UI.DragMode.Copy;

},

onDragStart: function() {},

onDrag: function() {},

// onDragEnd is called at the end of the drag & drop operation

// Here, delete the semitransparent object that shows

// the process of dragging and reconstruct it when needed

onDragEnd: function(canceled)

{

if (this._visual)

this.get_element().parentNode.removeChild(this._visual);

},

initialize: function()

{

Custom.UI.MagicDragSourceBehavior.callBaseMethod(this,'initialize');

$addHandler(this.get_element(), 'mousedown',this._mouseDownHandler)

 

},

//mousedown event handler

//Note the following code is quite similar to that used inside the onDragEnd method of the DragDropList behavior

mouseDownHandler: function(ev)

{

window._event = ev; //DragDropManager needs this

this._visual = this.get_element().cloneNode(true);

this._visual.style.opacity = '0.4';

this._visual.style.filter =

'progid:DXImageTransform.Microsoft.BasicImage(opacity=0.4)';

this._visual.style.zIndex = 99999;

this.get_element().parentNode.appendChild(this._visual);

var location =Sys.UI.DomElement.getLocation(this.get_element());

Sys.UI.DomElement.setLocation(this._visual, location.x,location.y);

Sys.Preview.UI.DragDropManager.startDragDrop(this,this._visual, null);

},

dispose: function()

{

if (this._mouseDownHandler)

$removeHandler(this.get_element(), 'mousedown',this._mouseDownHandler);

this._mouseDownHandler = null;

Custom.UI.MagicDragSourceBehavior.callBaseMethod(this, 'dispose');

}

}

//define the descriptor block so as to be used in xml-script programming

Custom.UI.MagicDragSourceBehavior.descriptor = {

properties: [

{name: 'dragDropMagic', type: Custom.UI.DragDropMagic}

]

}

Custom.UI.MagicDragSourceBehavior.registerClass

('Custom.UI.MagicDragSourceBehavior', Sys.UI.Behavior,

Sys.Preview.UI.IDragSource);

As for MagicDragSourceBehavior, the following points deserve to be mentioned:

1. This behavior is defined within the Custom.UI namespace.

2. The private variable _visual serves the same role as the private variable _dragVisual and is defined within the DragDropList behavior. These are all used to create a semitransparent element that indicates the drag & drop process.

3. The dragDropMagic propertyis very important. It corresponds to thedata propertyused inside the DragDropList behavior. In this sample, this property is used to store our custom object—Custom.UI.DragDropMagic (for brevity, we have not listed its source code; you can refer to the downloadable source code of the article), which defines two properties:backgroundColorandnumber. These represent the background color of the drop area and the dot number that is shown. Please note the relationship between this property and the data within MagicDropTargetBehavior. It will be defined later.

4. As for the methods declared in IDragSource, here we have defined them with those unused in this empty sample.

5. At the end of the event handler, mouseDownHandler, the following method is invoked:

Sys.Preview.UI.DragDropManager.startDragDrop(this,this._visual, null);

This method is responsible for notifying DragDropManager that the drag & drop operation has already started.

6. To use MagicDragSourceBehavior inside the declarative XML-Script blocks, we have also defined its descriptor with only adragDropMagic propertyexposed (as is explained above).

MagicDropTargetBehavior


Next, let’s take a look at the second behavior—MagicDropTargetBehavior, which will be attached to the droppable area in the dice game. The following is the total source code for MagicDropTargetBehavior:

//constructor definition

Custom.UI.MagicDropTargetBehavior = function(element)

{

Custom.UI.MagicDropTargetBehavior.initializeBase(this, [element]);

//Note: the private variable _dragDropMagic is used to hold data carried by the draggable object.

//In fact, in this sample, this data matters little,

//readers can take further consideration, such as exhibit this data before users or send it back to the server side

this._dragDropMagic =new Custom.UI.DragDropMagic();

}

Custom.UI.MagicDropTargetBehavior.prototype =

{

// implement methods of the IDropTarget interface

get_dropTargetElement: function()

{

return this.get_element();

},

canDrop: function(dragMode, dataType, data)

{

//only the two conditions are met, can the draggable object be droppable

return (dataType == 'DragDropMagic' && data);

},

//do the factual dropping. Here, we use the data in the draggble object to alter the background color of the droppable area and show the dot number of the dice

drop: function(dragMode, dataType, data)

{

if (dataType == 'DragDropMagic' && data)

{

this.get_element().style.backgroundColor = data.backgroundColor;

this.get_element().innerHTML = data.number;

}

},

//invoke this method when the draggable object is within the droppable area

onDragEnterTarget: function(dragMode, dataType, data)

{

if (dataType == 'DragDropMagic' && data)

{

this._dragDropMagic =data;//store the data

//use the data to modify the background color of the droppable box and the dot number of the dice

this.get_element().style.backgroundColor = data.backgroundColor;

this.get_element().innerHTML = data.number;

}

},

onDragLeaveTarget: function(dragMode, dataType, data)

{

//restore the initial content

if (dataType == 'DragDropMagic' && data)

{

this.get_element().style.backgroundColor =this._dragDropMagic.backgroundColor;

this.get_element().innerHTML =this._dragDropMagic.number;

}

},

//unused, then empty

onDragInTarget: function(dragMode, dataType, data) {},

initialize: function()

{

Custom.UI.MagicDropTargetBehavior.callBaseMethod(this,'initialize');

Sys.Preview.UI.DragDropManager.registerDropTarget(this);

},

dispose: function()

{

Sys.Preview.UI.DragDropManager.unregisterDropTarget(this);

Custom.UI.MagicDropTargetBehavior.callBaseMethod(this,'dispose');

}

}

Custom.UI.MagicDropTargetBehavior.registerClass

('Custom.UI.MagicDropTargetBehavior', Sys.UI.Behavior,

Sys.Preview.UI.IDropTarget);

Since we have made enough comments between the lines, we don't need to waste space chattering. However, the last point readers should take notice of is that both in the initializeanddispose methods,the corresponding methods of DragDropManager are invoked.

Last but not least, please remember to call the notifyScriptLoaded() methodof Sys.Application at the end of thecustDragDrop.js fileto notify theASP.NET AJAXclient-side framework that this script has been loaded successfully:

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();

Next, let’s start to consider the design of the web page for the dice game.

HTML code-related programming

Open the CustDragDropDemo.aspx page. As with other typical ASP.NET AJAX web pages, at the nearest position neighboring <form> element, we can see the definition of the ASP.NET AJAX server control ScriptManager; within which, we should add all necessary references to the related script files. Here’s the corresponding code:

<asp:ScriptManager ID="ScriptManager1" runat="server">

<Scripts>

<asp:ScriptReference Assembly="Microsoft.Web.Preview"

Name="PreviewScript.js" />

<asp:ScriptReference Assembly="Microsoft.Web.Preview"

Name="PreviewDragDrop.js" />

<asp:ScriptReference Path="~/Scripts/custDragDrop.js" />

</Scripts>

</asp:ScriptManager>

As was shown before, in the custDragDrop.js file we defined two custom behaviors, MagicDragSourceBehavior and MagicDropTargetBehavior, and an important class, Custom.UI.DragDropMagic, which represents the factual data the draggable object carries.

Next, follow the relatedHTMLelement definitions and use someCSSstyles for a beautiful look. That’s all.

<fieldset style="width: 607px" >

<legend><span style="font-size: 12pt">Please select a dice</span></legend>

<table cellpadding="8">

<tr>

<!-- Drag sources -->

<td style="height: 80px">

<div id="DragSource1" class="magicBack" />

</td>

<td style="height: 80px">

<div id="DragSource12" class="magicBack" />

</td>

<td style="height: 80px">

<div id="DragSource3" class="magicBack" />

</td>

<td style="height: 80px">

<div id="DragSource4" class="magicBack" />

</td>

<td style="height: 80px">

<div id="DragSource5" class="magicBack" />

</td>

<td style="height: 80px">

<div id="DragSource6" class="magicBack" />

</td>

</tr>

</table>

</fieldset>

<div style="width: 67%; height:80px; margin: 5px;">

<input id="restartBtn" type="button" value="Restart the game" style="width: 90px; height: 34px" />

</div>

<fieldset style="width: 264px; height: 245px">

<legend><span style="font-size: 12pt">Drop the dice here</span></legend>

<!-- Drop target -->

<div id="DropTarget" class="divDropTarget">

?

</div>

</fieldset>

Note here that we have used <fieldset> elements to lay out the page. As for the CSS style definitions, you can refer to the source code.

Next, let’s pay attention to the ASP.NET AJAX client side specific declarative XML-Script programming.

XML-Script programming

Now let’s see the xml-script code related to this dice game, which is shown in the following:

<script type="text/xml-script">

<page xmlns:script="http://schemas.microsoft.com/xml-script/2005"

xmlns:cns="javascript:Custom.UI">

<components>

<control id="DragSource1">

<behaviors>

<cns:MagicDragSourceBehavior id="b1" />

</behaviors>

</control>

<control id="DragSource12">

<behaviors>

<cns:MagicDragSourceBehavior id="b2" />

</behaviors>

</control>

<control id="DragSource3">

<behaviors>

<cns:MagicDragSourceBehavior id="b3"/>

</behaviors>

</control>

<control id="DragSource4">

<behaviors>

<cns:MagicDragSourceBehavior id="b4" />

</behaviors>

</control>

<control id="DragSource5">

<behaviors>

<cns:MagicDragSourceBehavior id="b5"/>

</behaviors>

</control>

<control id="DragSource6">

<behaviors>

<cns:MagicDragSourceBehavior id="b6" />

</behaviors>

</control>

 

 

<control id="DropTarget">

<behaviors>

<cns:MagicDropTargetBehavior/>

</behaviors>

</control>

<Button id="restartBtn" click="btnClickHandler"/>

</components>

</page>

</script>

Since the two custom behaviors we are to use are defined in the Custom.UI custom namespace, we have to add a reference to this namespace.

xmlns:cns="javascript:Custom.UI">

Next, we defined six ASP.NET AJAX client-side controls, which are bound to the six <div/> DOM elements that represent the six dice respectively. And, as is discussed above, we should apply the custom MagicDragSourceBehavior to all six controls.

Inside the descriptor block of MagicDragSourceBehavior, we’ve merely exposed one property—dragDropMagic. This property is a rather complex object. Therefore, we decide to use the JavaScript mode, rather than the xml-script mode, to specify this property for the six behaviors (which should be discussed later).

Next, the DOM element <div/> that represents the drop area is also attached to a client-side control (DropTarget), which is also decorated with another MagicDropTargetBehavior.

In the next section we'll see how we use the JavaScript mode to specify the dragDropMagic property for the above six behaviors and how we can attach a click event handler to the ‘Restart the game’ button.

JavaScript programming

As a general rule, we’d better specify the properties of the behaviors within the defaultloadevent handler—pageLoad of the client object Sys.Application. As was explained before, we specifically build a DragDropMagic to describe the possible complex data that the draggable object carries. In this game, we have to specify the dragDropMagic property for each of the six custom behaviors. The related code is shown below:

function pageLoad(sender, args)

{

var tArray = [];

createRandomArray(tArray);

$find("b1").set_dragDropMagic({backgroundColor:'orange',number:tArray[0]});

$find("b2").set_dragDropMagic({backgroundColor:'red',number:tArray[1]});

$find("b3").set_dragDropMagic({backgroundColor:'yellow',number:tArray[2]});

$find("b4").set_dragDropMagic({backgroundColor:'green',number:tArray[3]});

$find("b5").set_dragDropMagic({backgroundColor:'magenta',number:tArray[4]});

$find("b6").set_dragDropMagic({backgroundColor:'blue',number:tArray[5]});

}

Note that the $find method is the shortcut for the Sys.Application.findComponent global method. This is very important in client-side programming and is used to find the reference to the client-side component.

The effect of the createRandomArray helper function is to create six numbers ranging from 1 to 6 that should be assigned to the six dice at random with equal chance. For simplicity, we’ve directly specified the background color of the drop area. Now, you can see that when the game is launched, the six dice will be assigned six different dot numbers at random. The following gives the source code associated with the createRandomArray function.

//return an integer ranging from iFirstValue to iLastValue

function selectFrom(iFirstValue, iLastValue) {

var iChoices = iLastValue - iFirstValue + 1;

return Math.floor(Math.random() * iChoices + iFirstValue);

}

function createRandomArray(nRndArray)

{

var aNumbers = ["1", "2", "3", "4", "5", "6"];

var j=0;

var temp;

while(j<6)

{

temp=aNumbers[selectFrom(0, 5)];

if(Array.contains(nRndArray,temp))

continue;

else

{

Array.add(nRndArray,temp);

j++;

}

}

}

All of the above codes are basic JavaScript programming.

At last, let’s take a quick look at the related click event code for the ‘Restart the game’ button:

function btnClickHandler()

{

var tArray = [];

createRandomArray(tArray);

$find("b1").set_dragDropMagic({backgroundColor:'orange',number:tArray[0]});

$find("b2").set_dragDropMagic({backgroundColor:'red',number:tArray[1]});

$find("b3").set_dragDropMagic({backgroundColor:'yellow',number:tArray[2]});

$find("b4").set_dragDropMagic({backgroundColor:'green',number:tArray[3]});

$find("b5").set_dragDropMagic({backgroundColor:'magenta',number:tArray[4]});

$find("b6").set_dragDropMagic({backgroundColor:'blue',number:tArray[5]});

 

$get("DropTarget").innerHTML="?";

}

It's all so simple, isn’t it? When the player clicks the ‘Restart the game’ button, we again invoke createRandomArray to generate random numbers and assign them to the six dice. And also, we set up the necessary properties for the six dice. Finally, we restore the content of drop target to the beginner question mark.

So much for this game—you can now press F5 and give it a test! I bet you will be attracted to the friendly interface.

-DOWNLOAD SOURCE-

Summary

In this article, we developed a simple dice game using the ASP.NET AJAX client-side drag & drop technique. As was emphasized again and again, the two client-side interfaces (IDragSouce and IDropTarget) and the DragDropManager object play crucial roles in nearly all ASP.NET AJAX client-side drag & drop based applications. Therefore, to gain a more intensive comprehension of the IdragSource and IdropTarget interfaces, DragDropManager, as well as the relations between them, you are highly advised to earnestly study the source code of the two important behaviors—DragDropList and DraggableListItem in the PreviewDragDrop.js file. Once you have seized the main ideas of how to implement the two behaviors, you may have the ability to do any kind of ASP.NET AJAX-related drag & drop programming.

Apparently, the little game in this article is pretty simple. Maybe the biggest deficiency is that we have not employed the typical Web service means to provide data to the client side. But by using the many samples related to consumer Web service in ASP.NET AJAX on the Internet, it won't be difficult for you to supplement this functionality. And you may even use this small program to develop your own more complex and Ajax-based online games.

blog comments powered by Disqus
ASP.NET ARTICLES

- Implementing ASP.NET 4.0 Page.MetaDescriptio...
- ASP.Net Development Tips
- Intro to Sessions in ASP.Net
- Google Maps API Introduction in ASP.NET usin...
- Creating an ASP.NET 3.5 Gridview Image Galle...
- Encrypt QueryString in ASP.NET 3.5 using VB....
- ASP.NET 3.5 Drop Down List Controls
- Connect to Access Database with ASP.Net
- Secure Audio Streaming with ASP.Net and Flash
- Dynamic Sitemap and Navigation in ASP.Net
- Implement Gzip and Deflate Compression in AS...
- Run ASP.Net in Ubuntu with Apache
- ASP.Net Mono Website Contact Forms
- ASP.Net URL Rewriting Methods
- Murach`s ASP.NET 4 Web Programming with C# 2...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 10 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials