I was told it’s always good to start with a joke but I’m not that funny

So I will start with a game.

I’ve been doing so many demos with Visual WebGui and application for so long and I think it’s time to do some fun and games. I will write a more specific post later on Visual WebGui what we do (For this post I want to believe you all ready know what it is).

I really have to get this out of my system and also I don't think you can’t call a platform a platform if no one develops a game on it. So here is the first ever (as far as I know) Visual WebGui based Game.

My very own Picture Scramble. If you don't know what is a picture scramble game the idea is very very simple and old. What you basically have a picture that was cut to a specific number of cubes and one of those cubes preferably the bottom right one is removed. Next you need to scramble the pictures and sort them back to the original picture by moving a picture to the open space that was created by removing the bottom right cube. For this example I’ve used “Chips” my cat as a model you can see the picture before I sorted it and after. Don’t let the picture fool you, he is the devil spawn.

image image

 

So I create a new VWG application template and Enabled Visual WebGui integration to allow access to Visual Studio’s integrated options of VWG to my project.

image      image

Next I’ve added a new VWG User Control SlicedPictureBox.cs. This control will hold a slice of the source image.

image      image

Make our SlicedPictureBox inherit from PictureBox and add a few members.

public class SlicedPictureBox : PictureBox

{

    #region Members

 

    //The current image slice part

    private Point mobjSlicePart = new Point(0, 0);

 

    //The location of the current slice

    private Point mobjPicLocation = new Point(0, 0);

 

    //The size of the grid that cuts the image

    private Size mobjGridSize = new Size(1, 1);

 

    //The size of source image

    private Size mobjSourceSize = new Size(1, 1);

 

    //A resource handle to the image

    private ResourceHandle mobjSource = null;

 

    #endregion Members

Next we will add properties for these members.

public Point SlicePart

{

    get { return mobjSlicePart; }

    set { mobjSlicePart = value; }

}

 

public Point PicLocation

{

    get { return mobjPicLocation; }

    set { mobjPicLocation = value; }

}

 

public Size GridSize

{

    get { return mobjGridSize; }

    set

    {

        this.Update();

        mobjGridSize = value;

    }

}

The last property we need to add is for the ResourceHandle Source. Resource handles are actually pointers to the actual resource. When a control requires a resource such as an Image it should declare a ResourceHandle typed property that will link to an external located resource that will be retrieved through HTTP.

public ResourceHandle Source

{

    get { return mobjSource; }

    set

    {

 

        mobjSource = value;

        if (mobjSource != null)

        {

            Bitmap bm = new Bitmap(mobjSource.ToStream());

            // Calculate the Crop size

            int intCropWidth = bm.Size.Width / mobjGridSize.Width;

            int intCropHeight = bm.Size.Height / mobjGridSize.Height;

            //Set the size of the control according to Crop size

            this.Size = new Size(intCropWidth, intCropHeight);

        }

    }

}

 

 

 

Every control in VWG implements IGatewayComponent that provides a way for a component to handle requests. We will override the ProcessGatewayRequest function and set the behavior of our resources handle. What we will do is create a cropped image from the master resource according to the grid size.

protected override Gizmox.WebGUI.Common.Interfaces.IGatewayHandler ProcessGatewayRequest(HttpContext objHttpContext, string strAction)

{

    if (mobjSource != null)

    {

        Bitmap bm = new Bitmap(mobjSource.ToStream());

 

        int intCropWidth = bm.Size.Width / mobjGridSize.Width;

        int intCropHeight = bm.Size.Height / mobjGridSize.Height;

 

        Bitmap cropped = new Bitmap(intCropWidth, intCropHeight);

        Graphics g = Graphics.FromImage(cropped);

        g.DrawImage(bm, new Rectangle(0, 0, cropped.Width, cropped.Height), intCropWidth * mobjSlicePart.X, intCropHeight * mobjSlicePart.Y, cropped.Width, cropped.Height, GraphicsUnit.Pixel);

        g.Dispose();

 

        cropped.Save(objHttpContext.Response.OutputStream, ImageFormat.Jpeg);               

    }

    return null;

}

 

In the control constructor we will set the Image ResourceHandle property that was inherited from the PictureBox class to a new GatewayResourceHandle.

public SlicedPictureBox()

{

    this.Image = new GatewayResourceHandle(new GatewayReference(this, "picture"));

}

Now that we have our slice picture box control let’s start creating the application itself.
Open form1 in design mode and add a panel docked to bottom and place two textboxes and a button on it. One text box will hold the number of rows and one will hold the number of columns.

image

 

 

 

 

Next we will add a few members.

// Amount of rows

int mintRows;

 

//Amount of Columns

int mintColumns;

 

//The currently opened space to move an image to

Point mobjOpendPoint;

 

//A collection of Points that represent the images location in the grid

List<Point> mobjPointList;

 

//A collection of images.

List<SlicedPictureBox> mobjSlicedPictureBoxList;

 

//A collection of shuffled images.

List<SlicedPictureBox> mobjShuffledSlicedPictureBoxList;

 

The first method that we will create will be FillPointList.

/// <summary>

/// Fill the point collection with the necessary points

/// according to the row and columns that where set by the user.

/// </summary>

private void FillPointList()

{

    mobjPointList = new List<Point>();

    mobjOpendPoint = new Point(mintRows-1, mintColumns-1);

    for (int x = 0; x < mintRows; x++)

    {

        for (int y = 0; y < mintColumns; y++)

        {

            if (!((x == y) && (y == mintColumns-1)))

            {

                mobjPointList.Add(new Point(x, y));

            }

        }

    }

}

 

The second method is SlicePictures.

/// <summary>

/// Creates a collection of SlicedPictureBox. Each SlicedPictureBox gets a

/// point that represent the part that it needs to crop with the ProcessGatewayRequest

/// function.

/// </summary>

private void SlicePictures()

{

    mobjSlicedPictureBoxList = new List<SlicedPictureBox>();

 

    foreach (Point objPoint in mobjPointList)

    {

        SlicedPictureBox objSlicedPictureBox = new SlicedPictureBox();

        objSlicedPictureBox.GridSize = new Size(mintRows, mintColumns);

        objSlicedPictureBox.Source = new ImageResourceHandle("Image1.jpg");

        objSlicedPictureBox.SlicePart = objPoint;

        objSlicedPictureBox.BorderStyle = BorderStyle.FixedSingle;

        objSlicedPictureBox.Click += new EventHandler(objSlicedPictureBox_Click);               

        mobjSlicedPictureBoxList.Add(objSlicedPictureBox);               

    }

}

 

Open form1 in design mode and add another panel docked to fill. Rename it to MainPanel. This panel will hold the scrambled puzzle.
Go back to the code section of form1 and add a new method DrowPicturees.


/// <summary>

/// clears the main panel from all the pictures and draws a new set of pictures.

/// </summary>

private void DrowPicturees()

{

    this.MainPanel.Controls.Clear();

    foreach (SlicedPictureBox objSlicedPictureBox in mobjShuffledSlicedPictureBoxList)

    {

        objSlicedPictureBox.Left = objSlicedPictureBox.Width * objSlicedPictureBox.PicLocation.X;

        objSlicedPictureBox.Top = objSlicedPictureBox.Height * objSlicedPictureBox.PicLocation.Y;

        this.MainPanel.Controls.Add(objSlicedPictureBox);

    }

}


 

Last method we need to add is Shuffle.

 

/// <summary>

///Fills the mobjShuffledSlicedPictureBoxList with images from

///mobjSlicedPictureBoxList but scrambles the order of the images

/// </summary>

private void Shuffle()

{

    mobjShuffledSlicedPictureBoxList = new List<SlicedPictureBox>();

    Random randNum = new Random();

    int objNumberofSlice = mintColumns * mintRows-1;

    for (int i = 0; i < objNumberofSlice; i++)

    {

        int intNext = randNum.Next(0, objNumberofSlice - i);

        SlicedPictureBox objSlicedPictureBox = mobjSlicedPictureBoxList[intNext];

        mobjSlicedPictureBoxList.Remove(objSlicedPictureBox);

        Point objPoint = mobjPointList[i];

        objSlicedPictureBox.PicLocation = objPoint;

 

        mobjShuffledSlicedPictureBoxList.Add(objSlicedPictureBox);

 

    }

}

Now let’s add an event to click of the button. On that click event we will read the rows and columns size and create the scramble puzzle.

private void button1_Click(object sender, EventArgs e)

{

    mintRows = int.Parse(objRows.Text);

    mintColumns = int.Parse(objColumns.Text);

 

    FillPointList();

 

    SlicePictures();

 

    Shuffle();

 

    DrowPicturees();

 

}

All we need to do now is run the application and play. Enter the amount of rows and columns you want and press the shuffle button.

image

 

If you want to download this code you can use this link.

I hope you enjoyed this post. I know I have.  

Print | posted on Sunday, January 04, 2009 11:04 AM

Feedback

No comments posted yet.
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: