Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Creating and exploring a 3D maze with Silverlight 5

There's something about mazes than amazes me. They seem simple, but the math behind them can be very complicated (at least for a guy like me). Yet they have a draw that's hard to resist. Then there's the whole being inside of one, working your way out (i.e. just about every adventure game ever written?).

Today's project takes us through not only the creation/generation of a random maze, but how, using the power of the new 3D features in Silverlight 5, we can also explore our creations too...

Create a 3d maze with Silverlight 5.0

I would like to start this post saying I'm not a game development expert. During the first times of my work with computers I've been fascinated by the matter but I never gone deep on this development branch. Once I've meet the first time Silverlight 5.0 and I known about the 3D programming the first idea I had is to create a very simple maze as the one someone could write as the basis of a 3D game. In this post I want to briefly illustrate the work you can download at the end of the text. Here you can view a short video of the result of my work.

The maze in this video is made totally with the 3D API in Silverlight 5.0 and is totally compatible with the RTW bits. The maze is randomly generated every time you load the program and you can control the movement using the keyboard.

Generate the maze

At the base of the example there is a random generation algorithm. I think there are lot of algorithms you can find on internet and probably the one I used is really simple, but it is really effective.

The maze if based on a square divided in a number of cells and every cell has a wall on every side. Once I decided the size of the side I fill the square of cell and then I choose a random cell on a side. Then I search for an adjacent cell to move to. If the cell exists I remove the walls between the two cells then I move to the new position

...

public void Generate()
  {
      ThreadPool.QueueUserWorkItem(
          o =>
          {
              int progress = 0;

              Stack<Cell> stack = new Stack<Cell>();
              this.Reset();

              Cell cell = this.GetRandom(0);
              cell.Type = CellType.Enter;
              cell.Visited = true;

              while (true)
              {
                  Cell adiacent = this.GetAdiacentNonVisited(cell);

                  if (adiacent != null)
                  {
                      stack.Push(cell);
                      adiacent.Visited = true;
                      cell = adiacent;

                      progress++;

                      this.OnGenerationProgressChanged((int)(progress * 100.0 / (this.Width * this.Height)));
                  }
                  else
                  {
                      if (stack.Count > 0)
                          cell = stack.Pop();
                      else
                          break;
                  }
              }

              cell = this.GetRandom(this.Height - 1);
              cell.Type = CellType.Exit;

              this.OnGenerationCompleted();
          });
  }

Create the 3D view

Once the maze has been calculated it is time to render it using Silverlight 3D API. The rendering is made creating a square plan representing the floor of the maze and then iterating over oll the cells and creating the remaining walls.

A wall is exactly a parallelepiped created on a side. Since the thickness of the square side is zero, the wall is created across this line. some point external and some point internal. To avoid gaps in the corners all the walls include the corner of the square, also if another wall already used the same space.

Silverlight 3D API let you create every kind of figure using a collection of edges. The edges are drawn to create triangles. A triangle is the sole surface you can create connecting three edges, that for sure is part of a single plane. Every other surface you can create can be constructed using a collection of triangles but is not necessarily part of a single plane. So to create the rectangle representing a face of a wall you have to use two triangles.

...

private void AddWall(List<VertexPositionColor> edges, float xOffset, float zOffset, float xSize, float zSize)
  {
      var wall = new List<VertexPositionColor>();

      Vector3 topLeftFront = new Vector3(xOffset, this.Height, zOffset + zSize);
      Vector3 bottomLeftFront = new Vector3(xOffset, 0.0f, zOffset + zSize);
      Vector3 topRightFront = new Vector3(xOffset + xSize, this.Height, zOffset + zSize);
      Vector3 bottomRightFront = new Vector3(xOffset + xSize, 0.0f, zOffset + zSize);
      Vector3 topLeftBack = new Vector3(xOffset, this.Height, zOffset);
      Vector3 topRightBack = new Vector3(xOffset + xSize, this.Height, zOffset);
      Vector3 bottomLeftBack = new Vector3(xOffset, 0.0f, zOffset);
      Vector3 bottomRightBack = new Vector3(xOffset + xSize, 0.0f, zOffset);

      Color c1 = Color.FromNonPremultiplied(200, 200, 200, 255);
      Color c2 = Color.FromNonPremultiplied(150, 150, 150, 255);
      Color c3 = Color.FromNonPremultiplied(100, 100, 100, 255);

      // Front face
      wall.Add(new VertexPositionColor(topRightFront, c1));
      wall.Add(new VertexPositionColor(bottomLeftFront, c1));
      wall.Add(new VertexPositionColor(topLeftFront, c1));
      wall.Add(new VertexPositionColor(topRightFront, c1));
      wall.Add(new VertexPositionColor(bottomRightFront, c1));
      wall.Add(new VertexPositionColor(bottomLeftFront, c1));

      // Back face 
      wall.Add(new VertexPositionColor(bottomLeftBack, c1));
      wall.Add(new VertexPositionColor(topRightBack, c1));
      wall.Add(new VertexPositionColor(topLeftBack, c1));
      wall.Add(new VertexPositionColor(bottomRightBack, c1));
      wall.Add(new VertexPositionColor(topRightBack, c1));
      wall.Add(new VertexPositionColor(bottomLeftBack, c1));

      // Top face
      wall.Add(new VertexPositionColor(topLeftBack, c2));
      wall.Add(new VertexPositionColor(topRightBack, c2));
      wall.Add(new VertexPositionColor(topLeftFront, c2));
      wall.Add(new VertexPositionColor(topRightBack, c2));
      wall.Add(new VertexPositionColor(topRightFront, c2));
      wall.Add(new VertexPositionColor(topLeftFront, c2));

      // Left face
      wall.Add(new VertexPositionColor(bottomLeftFront, c3));
      wall.Add(new VertexPositionColor(bottomLeftBack, c3));
      wall.Add(new VertexPositionColor(topLeftFront, c3));
      wall.Add(new VertexPositionColor(topLeftFront, c3));
      wall.Add(new VertexPositionColor(bottomLeftBack, c3));
      wall.Add(new VertexPositionColor(topLeftBack, c3));

      // Right face 
      wall.Add(new VertexPositionColor(bottomRightBack, c3));
      wall.Add(new VertexPositionColor(bottomRightFront, c3));
      wall.Add(new VertexPositionColor(topRightFront, c3));
      wall.Add(new VertexPositionColor(bottomRightBack, c3));
      wall.Add(new VertexPositionColor(topRightFront, c3));
      wall.Add(new VertexPositionColor(topRightBack, c3));

      edges.AddRange(wall);
  }

Moving the player and making walls solid

Viewing the maze rendered the first time is for sure wonderful, but the very great thing is being able to navigate inside it with the keyboard. Every time a property of the Observer object is updated the change is reflected externally with the Change event. The event cause the update of the camera position and then the redraw of the scene. Using up and down arrow you can move forward and backward and with left and right arrows it is possible to turn the course in these directions. Additionally you can use PageUp and PageDown to tilt up and down the camera as the player tilt the head.

To catch the keyboard events continuously I use a trick. This is because keyboard event in silverlight does not repeats automatically. Using a KeyboardState class I created I check for KeyUp and KeyDown changing the status of monitored keys. Then a timer changed the observer properties according with the pressed keys. This tecnique allows also to use more that a single key at a time allowing the observer to turn since it is moving forward.

...

Working with 3D

Working with 3D in silverlight is for sure interesting but it requires a good knowledge of 3D math to achieve good results. Every time you get something really effective since it is a low level API using it programming interface becomes mostly difficult. So if you need to work with 3D I suggest to use an hi level framework that abstracts the API and let you think in terms of solid figures instead of collection of edges. Balder is for sure a good example of what I mean: http://balder.codeplex.com/

Download: http://www.silverlightplayground.org/assets/sources/SLPG.Maze.zip (270kb)

Here's a snap of the solution;

image

SNAGHTML46d8698f

And it running on my notebook (which run, for me at least, the first time with no issues, tweaks, etc. it just worked. Smiley

If you're thinking about playing with the new 3D capabilities available in Silverlight 5, or are a maze fan, this project might be worth a peek or two for you...

Tag:

Follow the Discussion

  • GineerGineer Gineer

    So what's the final answer then: Is Silverlight dead or not?

  • Reminds me of a 3D maze that I had as a screen saver on a old Windows 98 computer!

  • Shantanu ChandraSChandra Me & my gadgets...

    Stay hungry, stay foolish...

    sorry for the stupid questions...

    would love if you could redirect me to a post where I could find the answers to the following questions::

    1. Can we write the silverlight in C++...because the above language looks similar to C++ code...
    2. Where can I find  list of datatypes similar to "Cell", "Stack", "List"
    3. What does  Stack<Cell> do

    4. Where can I start learning Silverlight from the basics as low as datatypes.
    what was your source of learning???

  • Bohdan Trotsenkomodosansrev​es modosansrev​es

    @SChandra: in brief, no, C++ is not allowed.

    Check out silverlight.net site.

  • RajeshRajesh

    @SChandra

    Get the book fun with silverlight 4
    http://www.amazon.com/Fun-Silverlight-Illustrated-Creating-Applications/dp/1463506023/

    to start learning silverlight.

    More info at http://Silverlightfun.com

    To have a basic refresher on silverlight 3d check http://msdn.microsoft.com/en-us/magazine/hh547098.aspx

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.