Roy Triesscheijn’s Weblog

My programming world

Vacation time is over

Posted by Roy Triesscheijn on July 24th, 2010

Just a quick post to let everyone know that I’m back from vacation :) . Gotta expect at least one interesting article in the comming weeks. Or wel… I should really write some.

As always ideas are welcome!

Tags:
Posted in Blog | 2 Comments »

More A* improvements

Posted by Roy Triesscheijn on June 27th, 2010

As you might know I’ve written quite a lot of articles on the A* algorithm.

This week I was contacted by Roman Kazakov (fourfor[AT]hotmail.com). He had a look at my previous A* articles and came up with a number of ways to speed up my latest version even more! Unfortunately he doesn’t have a blog, so he asked me to publish his enhancements here, so that everyone can use them. So I’ll forego the rest of this introduction and let the man speak.

(Note: the following quote is the last unedited part of an e-mail of Roman Kazakov).

Hi Roy, my name is Roman Kazakov and I am Russian guy, but live in Latin America. My Spanish is perfect, but my English is “so so”, I hope you understand me. :) I am not a professional programmer. This is just my hobby from university. And as “free lancer” I work with VS 2008 C# + DevXpress + SQL Server 2008.
I would like to present you my optimization for you program AStar. Oh, by the way, my game is 2D, and this example is in 2D dimension, but this version will by work and 3D too and more faster.
Here is code of FindPathReversed:

 private static BreadCrumb3 FindPathReversed5Final(bool[,] worldBlocked, Point2D start, Point2D end)
        {
            // Here we dont use the class Poin2D. It is bad idea use Class just for two int values (X Y)
            List<BreadCrumb3> openList2 = new List<BreadCrumb3>(256);
            BreadCrumb3[,] brWorld = new BreadCrumb3[worldBlocked.GetLength(0), worldBlocked.GetLength(1)];
            BreadCrumb3 node;
            int t1, t2;
            int tmpX, tmpY;
            int cost;
            int diff;
            t1 = worldBlocked.GetLength(0);
            t2 = worldBlocked.GetLength(1);
            BreadCrumb3 current = new BreadCrumb3(start.X, start.Y);
            current.cost = 0;

            BreadCrumb3 finish = new BreadCrumb3(end.X, end.Y);
            brWorld[current.X, current.Y] = current;
            openList2.Add(current);

            while (openList2.Count > 0)
            {
                //Find best item and switch it to the 'closedList'
                current = openList2[0];
                openList2.RemoveAt(0);
                int position = 0;
                cost = openList2.Count;
                do
                {
                    int left = ((position << 1) + 1);
                    int right = left + 1;
                    int minPosition;

                    if (left < cost && openList2[left].cost < openList2[position].cost)
                    {
                        minPosition = left;
                    }
                    else
                    {
                        minPosition = position;
                    }

                    if (right < cost && openList2[right].cost < openList2[minPosition].cost)
                    {
                        minPosition = right;
                    }

                    if (minPosition != position)
                    {
                        node = openList2[position];
                        openList2[position] = openList2[minPosition];
                        openList2[minPosition] = node;
                        position = minPosition;
                    }
                    else
                    {
                        break;
                    }

                } while (true);

                current.onClosedList = true;

                //Find neighbours
                for (int i = 0; i < 8; i++)
                {
                    tmpX = current.X + surrounding2[i, 0];
                    tmpY = current.Y + surrounding2[i, 1];
                 //   tmp = current.position + surrounding[i]; //This is is a really slow!!!
                    /*if (tmp.X >= 0 && tmp.X < t1 &&
                tmp.Y >= 0 && tmp.Y < t2 &&
                !worldBlocked[tmp.X, tmp.Y])*/
                    if (tmpX >= 0 && tmpX < t1 &&
             tmpY >= 0 && tmpY < t2 &&
             !worldBlocked[tmpX, tmpY])
                    {
                        //Check if we've already examined a neighbour, if not create a new node for it.
                        if (brWorld[tmpX, tmpY] == null)
                        {
                          //  node = new BreadCrumb3(tmpX,tmpY);
                           // brWorld[tmpX, tmpY] = node;
                            brWorld[tmpX, tmpY] = node = new BreadCrumb3(tmpX, tmpY); // This is more fast!
                        }
                        else
                        {
                            node = brWorld[tmpX, tmpY];
                        }

                        //If the node is not on the 'closedList' check it's new score, keep the best
                        if (!node.onClosedList)
                        {
                            diff = 0;
                            if (current.X != node.X)
                            {
                                diff += 1;
                            }
                            if (current.Y != node.Y)
                            {
                                diff += 1;
                            }
                            cost = current.cost + diff + ((node.X - end.X) * (node.X - end.X)) + ((node.Y - end.Y) * (node.Y - end.Y));//node.position.GetDistanceSquared(end);

                            if (cost < node.cost)
                            {
                                node.cost = cost;
                                node.next = current;
                            }

                            //If the node wasn't on the openList yet, add it
                            if (!node.onOpenList)
                            {
                                //Check to see if we're done
                               // if (node.Equals(finish)) // This is slow too!!!
                                if (node.X == finish.X && node.Y == finish.Y)
                                {
                                    node.next = current;
                                    return node;
                                }
                                node.onOpenList = true;
                                openList2.Add(node);

                                int position2 = openList2.Count - 1;

                                int parentPosition = ((position2 - 1) >> 1);

                                while (position2 > 0 && openList2[parentPosition].cost > openList2[position2].cost)
                                {
                                    node = openList2[position2];
                                    openList2[position2] = openList2[parentPosition];
                                    openList2[parentPosition] = node;
                                    position2 = parentPosition;
                                    parentPosition = ((position2 - 1) >> 1);
                                }

                            }
                        }
                    }
                }
            }
            return null; //no path found
        }

Comments:
Look in my screenshots which i made it for you. For looking performance I used ANTS Performance Profiler 5.2. This is a great “stuff”!
Also you can use your benchmark. Check the file zip attached. There is all source and information for compiled.
Comments about code:
The general “thing” in programming in C# is do not use Obj Class and etc. where really dont need to use that! The best performance is just “Value type” and List<>
Array, maybe Struct.
In my optimized code I deleting class MinHeap where T : IComparable. Why?! Because is really slow, and I dont know why. Also use class Point2D just for 2(3) types X and Y( and Z), it was a bad idea. And many thing more. Looked my code and you understand which changes I made it. I hope this is help you. And please put this optimization on you wonderful web page http://roy-t.nl, as New Optimized Version A*.
When we made the games, we looking for more faster algorithm and code. This article will be help a many people as us.
We made the games of our dreams…

Roman also included a couple of pictures to show the speed gain of his code
Original code (by me)

New implementations (by Roman)

Tags: , , , , , ,
Posted in Blog, General Gamedesign, XNA | No Comments »

Re: Writing a book ????

Posted by Roy Triesscheijn on June 21st, 2010

Some of you might look a but strange at the title, it is the exact same title as TheZman’s latest blog post.

His post got me to think again about a project I’d like to start on *(Oh god, this makes me think of the oh so many projects that I want to start on!). Writing a book? It takes quite a lot of courage and determination to write a good technical book. Hell I know that I haven’t yet acquired the technical skills for it. (Maybe I haven’t even mastered English  enough yet). So obviously I’m not think about writing a technical book.

However I would like to write a book for people who are not into (game-) programming or maybe even games in general. I would like to introduce readers to a kind of ‘ambiance’ that gives us developers such a comfortable feeling when developing for games. I would like to tell people how difficult game programming is, what games really are (in my opinion that is). And what some games with attention to detail, and attention to the real world, can bring to people.

Hell it would be a book worthy of a game-evangely. Of course there should be added technical parts, but the book I’d like to write would also contain parts that you could take a good sit for and read for pleasure.

This however brings me to how to actually release a book. Of course I could just put it up here as a pdf and be done with it, but that’s not really what I had in mind. Publishing a game, getting your name on there somewhere is also something that could thrive me into making a  book.

Oh well, first back to spell and style checking my blog posts I guess. But maybe I could do a small primer someday, say 50 pages, and see what people think. (And count the number of mistakes, to see how long it would take to correct a full book…).

Tags: , ,
Posted in Blog, Personal | 2 Comments »

Thoughts: automatic tests and user interfaces

Posted by Roy Triesscheijn on June 7th, 2010

Lately I’ve been working on a rather large project (software web shop that automatically adds and updates products). The customer required that a large part of the software was automatically tested. We accomplished this by using PHPUnit (somewhat quirky, but it got the job done). However there was one big problem.

The problem

The web shop was built with the Zend Framework in true MVC fashion. This meant that it was very easy to write unit tests for the model. However the model wasn’t that complex, just a bunch of queries and some massaging of the fetched data. The most interesting things happened in the views and we had no clue how to test the views automatically. Because we had a hard deadline, and didn’t have time to fully dive into this problem, one of our testers committed himself to test all the views every day. This was feasible because we didn’t have too many views.

Current approaches

Automatically testing user interfaces is hard, especially in web languages. In a C# or Java application you can at least fill in text boxes and ‘press’ some buttons via code, although this will require you to (temporarily) make a lot of stuff public. In web languages you don’t have this amount of direct control; the closest thing would be to write a lot of Javascript. However Javascript’s state is lost on page transitions so you’d have to write the state to a file, fetch it on the next page, continue testing there, and so on. This seems like a really big bunch of work, with not much gain. However maybe there is a framework out there, which does just this thing. Maybe you can tune it to navigate the web shop for you, however there is still another big problem.

Presentation is important

For a user interface it is very important how everything looks. In web apps a small typo can make a page totally unreadable. A possible approach would be to strictly specify where a control should appear (maybe in pixels relative to the browser’s borders). But this is not possible to check with any Javascript or any other web front-end language I know. Maybe an application can make a screenshot and compare this with a screenshot that was deemed correct? Even this approach might not work very well as this would already give an error when the text on a label was partially changed.

Possible solution

I’ve come up with the following solution so far. This is just an idea which I’ve just cooked up (and the reason for this post) but I believe that it would work. Unfortunately there is no product available on the market yet that does these things.

In my opinion a good user interface tester would test in two steps. One test focused on content correctness and one focused on visual correctness.

The content correctness test would roughly follow the following steps:

• Request a page from the server

• Fill in controls and click buttons, following a predefined ‘test path’

• Verify that returned pages contains correctly filled in elements (does the label with name label1 contain the text “hello world”?). This could be done by adding a special identifier to each control that needs to be tested. The identifier can be hidden in ‘comments’ so that even during testing the web application stays compatible with normal browsers.

For every step a screenshot is made from the render output in the most popular web browsers. If the content correctness test succeeds the visual correctness test is executed, which contains the following test.

• Record control positions and sizes by ‘scanning’ the screenshots using OCR techniques. Might be aided by cross referencing the page’s source code.

• Test if controls are inside predefined ‘control locations’. Think of setting this up by dragging rectangular boxes over a screenshot to specify where a control should approximately be.

• If a control is not entirely on the correct location calculate a badness percentage.

• If the accumulated badness percentage is too high: fail the test and generate a nice picture, clearly marking the deviations.

• Also give the tester the option to select a failed test as the new correct references. This is useful for quickly updating tests when larger parts of the interface are changed.

Of course this approach doesn’t solve all the problems of testing user interfaces. And user interfaces will also have to be checked manually once in a while. However I think an application capable of performing the above tests would be very handy. Most of the above is also applicable to non-web applications btw.

I would very much like to hear everyone’s thoughts on this. How do you currently test user interfaces, have you come up with a feasible way to test large user interfaces?

Tags: , , , , , ,
Posted in Blog, General Coding | 2 Comments »

Busy busy busy

Posted by Roy Triesscheijn on May 15th, 2010

As you might’ve noticed by the lack of updates. I’m rather busy because I’m stil working on the ISEP project for the Rijksuniversiteit Groningen. It’s quite a lot of work and we’re currently busy with the final 3 week crunch to get everything  done. I hope life goes back to normal after that and that I can blog some interesting stuff again. If not it will probably be quite silent here till the start of the summer vacation, in which I have some really cool projects planned which I’m planning to show you guys!

Kind regards,

Roy Triesscheijn

Posted in Blog | No Comments »

Tutorial page

Posted by Roy Triesscheijn on April 20th, 2010

Because I’ve created quite a few tutorials the last two years. I’ve created a new page where you can browse through all the tutorials! I’ll try to make this more visible shortly, as I still think the menu bar is often overlooked. (However I quite like this theme, I’m just to lazy to find a new one, or fix it myself).  I’m also working on a page where I can post all the programming related books I’ve bought, together with a small review, I want to make it flashy, so it might take a while before you’ll see that.

Anyway without further introduction: The Tutorial Page

Oh btw, if anyone of you have an idea for a tutorial that you’d like to see, please make a request, post here, e-mail me (roy-t[at]hotmail[dot]com) twitter me or whatever, and if I find the subject interesting I’ll try to make a tutorial about it.

Tags: ,
Posted in Blog | 2 Comments »

Serialization: BLOB, INI, XML and JSON

Posted by Roy Triesscheijn on April 12th, 2010

BLOB

As a regular programmer I was quite accustomed to storing program information as blob files (binary large objects). In C# this is really easy, you just mark a class as serializable via the [Serializable()] attribute, special fields that you don’t wish to be serialized you mark as [NonSerialized]. Finally you create a BinaryFormatter for the actual serialization and de-serialization and you’re done.
Source code (note: there’s no error handling in any of the source code to keep things short) would look something like this:

[Serializable()]
public class SerializeBLOB
{
	public string name = "Hello my name is...";

	[NonSerialized]
	public SerializeBLOB circularReference;

	public static void Serialize(SerializeBLOB obj, Stream stream)
	{
		BinaryFormatter bf = new BinaryFormatter();
		bf.Serialize(stream, obj);
	}

	public static SerializeBLOB DeSerialize(Stream stream)
	{
		BinaryFormatter bf = new BinaryFormatter();
		return (SerializeBLOB)bf.Deserialize(stream);
	}
}

Pointing the stream at a file would generate a binary file. Using blobs is very easy, it takes only a few lines of code to store and retrieve an object. However the generated output is not human readable. And a program which was written in a different language and/or has no access to the original class file (be it in compiled form or not) will not understand, let alone modify the file, correctly without a lot of effort.

INI

A different take on this are INI-files, which are files where an attribute is named and a value is followed. An ini file could look like this:

name=someName
number=18

This file is human readable and easily understood and edited by either computers or humans. This file was generated by the following code, which is not really complex, but there are some big problems which I haven’t solved yet.

public class SerializeINI
{
	public string name = "someName";
	public int number = 18;

	public static void Serialize(SerializeINI obj, Stream stream)
	{
		StringBuilder sb = new StringBuilder();
		sb.AppendLine("name=" + obj.name);
		sb.AppendLine("number=" + obj.number.ToString());
		StreamWriter writer = new StreamWriter(stream);
		writer.Write(sb.ToString());
	}

	public static SerializeINI DeSerialize(Stream stream)
	{
		StreamReader reader = new StreamReader(stream);
		SerializeINI obj = new SerializeINI();
		string line;
		while((line = reader.ReadLine()) != String.Empty)
		{
			string[] id_value = line.Split('=');
			switch (id_value[0])
			{
				case "name":
					obj.name = id_value[1];
					break;
				case "number":
					obj.number = Int32.Parse(id_value[1]);
					break;
			}
		}

		return obj;
	}
}

As you can see, serialization and de-serialization is not as automated as you’d hope for. We have to write the code for each action ourselves, which can be cumbersome if we are dealing with large and/or numerous classes. Also classes that we serialize need to have only public fields that we want to store, or have some kind of constructor (that maybe accepts a nice struct) that allows us to set all fields. There’s also another problem, there is no clear syntax on arrays, we could of course invent some syntax, but this would differ from program to program. Another problem is how do we save text that contains a ‘=’ char. We could solve this by using escaping or by using a special dummy character, although these problems are all solvable, the way these problems are solved differ from application, which makes it hard to make applications interact with each other.

In the comments Alex correctly states that with reflection you could get automatically get all the objects members automatically, you can even introduce your own attributes or respond to the existing attributes like [nonserialized]. Of course this would make ini serialization and de-serialization a lot easier. However reflection code is often very complex so I won’t put any source code here. But maybe I’ll write a separate tutorial about reflection.

XML

So let’s try another type of serialization, XML (eXtensible Markup Language) has been quite the buzz lately, it’s being used to create web pages (XHTML) and a lot of web services and web APIs communicate via XML. Some databases even allow us to save XML and to search through XML and in .Net there is even a separate XML namespace (System.XML). As with most things, it’s trivially easy to serialize to XML in .NET.

 <Human>
  <Name>Anthony</Name>
  <Age>38</Age>
 <Stuff  test='123'>something</Stuff>
</Human>

XML is human readable and very understandable by machines. However the syntax is a bit complex sometimes. The tree like structure is understandable, but when do we write an attribute between two tags like ‘Name’ or do we use the parameter syntax like in ‘Stuff’? Or both. There’s also a lot of confusion about arrays, we could use a tree like structure and creating a new leaf for each element in the array, but there are other solutions.
The syntax for serialization to XML looks quite like that of serialization to BLOB. We mark the class as serializable by setting it as a root element via [XMLRootAttribute(…)] and stuff we don’t want to serialize we mark with [XmlIgnore]. To beautify the XML output we can even add attributes to different fields to specify the arguments, type and name).

[XmlRootAttribute("TestRoot")]
public class SerializeXML
{
	public string name = "Hello my name is...";

	[XmlIgnore]
	public SerializeXML circularReference;

	public static void Serialize(SerializeXML obj, Stream stream)
	{
		XmlSerializer xs = new XmlSerializer(typeof(SerializeXML));
		xs.Serialize(stream, obj);
	}

	public static SerializeXML DeSerialize(Stream stream)
	{
		XmlSerializer xs = new XmlSerializer(typeof(SerializeXML));
		return (SerializeXML)xs.Deserialize(stream);
	}
}

JSON

JSON (Javascript Serialized Object Notation) is not as well known as any of the previously mentioned techniques, also don’t mind the name, JSON is usable in any programming language. JSON is slightly easier to read and requires less typing than XML, the notation is much cleaner, and there is always only one way to store data. The graphs at http://json.org/ show how easy it is to learn how to read and write a JSON file (however the website is quite biased). A JSON file would look like this (from Wikipedia):

{
     "firstName": "John",
     "lastName": "Smith",
     "age": 25,
     "address": {
         "streetAddress": "21 2nd Street",
         "city": "New York",
         "state": "NY",
         "postalCode": "10021"
     },
     "phoneNumber": [
         { "type": "home", "number": "212 555-1234" },
         { "type": "fax", "number": "646 555-4567" }
     ]
 }

New knowledge for me is that JSON in .Net is fully integrated into the .Net Framework. But you have to manually add the references to “System.ServiceModel.Web” and System.Runtime.Serialization.XmlObjectSerializer to your project to take full advantage of this. Take a look at the following sourcecode:

    [Serializable()]
    public class SerializeJSON
    {
        //Add the references System.ServiceModel.Web
        //and System.Runtime.Serialization.XmlObjectSerializer
        //to your project to be able to see DataContractJSONSerializer
        public string name = "Hello my name is...";

        [NonSerialized]
        public SerializeJSON circularReference;

        public static void Serialize(SerializeJSON obj, Stream stream)
        {
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(SerializeJSON));
            js.WriteObject(stream, obj);
        }

        public static SerializeJSON DeSerialize(Stream stream)
        {
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(SerializeJSON));
            return (SerializeJSON)js.ReadObject(stream);
        }
    }
}

As you can see the JSON serialization syntax closely matches that of the BLOB (BinaryFormatter) syntax, which makes it easy to use, but there is less control over the output than with XML.

Conclusion

BLOB files are handy for data that doesn’t need to be edited by anything else than your own application, INI files are something from the past, but might still have a right to exist because it is so easy to edit them by hand, INI files are still heavily used in the game industry to set a lot of properties at game. Big engines like the Unreal Engine still use a lot of INI files. XML has a slightly more difficult syntax but you can give a lot of meaning to attributes and it is very customizable how attributes are stored. Also the support from the .NET framework is incredible and XML is a widely appreciated standard. JSON is less widely adopted than XML except in JAVASCRIPT driven web applications but JSON has a very clear syntax. However XML is more expressive as it is a bit more difficult to give extra meaning to an attribute in JSON than it is in XML, but JSON is a purer form of storing data where XML might be a bit too multi-purpose sometimes.
As with all techniques there is no ‘winner’, all techniques have their uses and I look forward to use all of them.

Other cool things to know is that JSON can be directly evaluated in javascript by using the eval(…) function. And for XML there is a full query language called XPATH which allows you to query your XML files like you would query a database.

Special thanks to creator1988 for pointing me to the JSON serializer.
kick it on DotNetKicks.com

Tags: , , , , , , ,
Posted in Blog, General Coding | 4 Comments »

Immediate GUIs in XNA: Scrollbars

Posted by Roy Triesscheijn on March 30th, 2010

Introduction

Last time we’ve made a small IMGUI framework, now we are going to add scrollbars, or sliders if you prefer that term, to our set of controls. Sliders work a bit differently than buttons because you’ll have to know last time’s value to show the slider correctly, and we can’t store state for each slider in the IMGUI itself (or well, that goes against the idea).

Setup

Load last time’s project (see part one here)

Without further ado (and because I’m pretty busy lately) I’ll put the source code for a scrollbar here, and afterwards explain the method.

        /// <summary>
        /// Draws a vertical or horizontal scrollbar at the specified position. If the grip was moved, returns the new value, else returns the inserted value
        /// </summary>
        public float DoScrollbar(int id, Rectangle rectangle, Texture2D scrollbarTexture, Texture2D gripTexture, float max, float value, bool horizontal)
        {
            //No matter the input, value should be at least 0 and at most max
            value = Math.Min(Math.Max(value, 0), max);

            //Determine if we're hot, and maybe even active
            if (MouseHit(rectangle)) //See previous part's code for this method
            {
                hotItem = id;
                if (activeItem == -1 && mouse.LeftButton == ButtonState.Pressed)
                    activeItem = id;
            }

            //Draw the scrollbar
            spriteBatch.Draw(scrollbarTexture, rectangle, ActiveColor);

            //Position the grip relative on the scrollbar and make sure the grip stays inside the scrollbar
            //Note that the grip's width if vertical/height if horizontal is the scrollbar's smallest dimension.
            int gripPosition; Rectangle grip;
            if (horizontal)
            {
                gripPosition = rectangle.Left + (int)((rectangle.Width - rectangle.Height) * (value / max));
                grip = new Rectangle(gripPosition, rectangle.Top, rectangle.Height, rectangle.Height);
            }
            else
            {
                gripPosition = rectangle.Bottom - rectangle.Width - (int)((rectangle.Height - rectangle.Width) * (value / max));
                grip = new Rectangle(rectangle.Left, gripPosition, rectangle.Width, rectangle.Width);
            }

            //Draw the grip in the correct color
            if (activeItem == id || hotItem == id)
            {
                spriteBatch.Draw(gripTexture, grip, ActiveColor);
            }
            else
            {
                spriteBatch.Draw(gripTexture, grip, InActiveColor);
            }

            //If we're active, calculate the new value and do some bookkeeping to make sure the mouse and grip are in sync
            if (activeItem == id)
            {
                if (horizontal)
                {
                    //Because the grip's position is defined in the top left corner
                    //we need to shrink the movable domain slightly so our grip doesnt
                    //draw outside the scrollbar, while still getting a full range.
                    float mouseRelative = mouse.X - (rectangle.X + grip.Width / 2);
                    mouseRelative = Math.Min(mouseRelative, rectangle.Width - grip.Width);
                    mouseRelative = Math.Max(0, mouseRelative);
                    //We then calculate the relative mouse offset 0 if the mouse is at
                    //the left end or more to the left. 1 if the mouse is at the right end
                    //or more to the right. We then multiply this by max to get our new value.
                    value = (mouseRelative / (rectangle.Width - grip.Width)) * max;
                }
                else
                {
                    //same as horizontal bit in the end we inverse value,
                    //because we want the bottom to be 0 instead of the top
                    //while in y coordinates the top is 0.
                    float mouseRelative = mouse.Y - (rectangle.Y + grip.Height / 2);
                    mouseRelative = Math.Min(mouseRelative, rectangle.Height - grip.Height);
                    mouseRelative = Math.Max(0, mouseRelative);
                    value = max - (mouseRelative / (rectangle.Height - grip.Height)) * max;
                }
            }
            return value;
        }

As you can see a scrollbar is a bit more complicated than a button, but the code is still pretty short. I think the code is pretty self explanatory, but I’ll add a short overview of the steps here:
-A scrollbar is called with as parameter a float called value, this value indicates where on the scrollbar the grip should be (between 0 and max)
-First trim value so that it is between 0 and max
-Determine if the mouse is over the scrollbar, and if so check if the mouse is being pressed
-Draw our scrollbar background in the right color
-Now calculate where our grip should be positioned and how big it should be (two code paths, one for horizontal and one for vertical)
-If we have a scrollbar background of 60×500 we want our grip to be of size 60×60, and vice-versa
-If we have a value near max we want the grip to be more to the right (or top) and vice-versa
-Now draw our grip
-Last, if the scrollbar is the activeItem, we need to check if the mouse (and thus the grip) was moved (again two code paths).
-This is slightly tricky so take a good look at that code.
-In the end, return the value (which was changed if the grip was moved).

Well, now we have that nice scrollbar, how are we going to use it?

        private IMGUI imgui; //construct/load these fields somewhere
        private Texture2D backgroundTexture;
        private Texture2D gripTexture;
        private float scrollvalue = 0;

        public void DrawImGui()
        {
            imgui.Update(gameTime); //normally you would do this in the Update method of your screen
                                              //but for code-compactness reasons in tutorials, I'll just add it here

            imgui.Begin();

            scrollvalue = imgui.DoScrollbar(1, new Rectangle(10, 10, 300, 50), backgroundTexture, gripTexture, 100, scrollvalue, true);
            //More GUI items

            imgui.End();
        }

(Note the call to imgui.Update(…) which I might have forgotten last time (oops).

Easy isn’t it? A simmilar technique is used for text input, but you’d need an extra state to keep track of the item the mouse last clicked that receives keyboard input, I’ll go over that next time. I would add a nice picture here to show you how this all looks, but tbh my programmer art is so ugly that I’m scared it would frighten you away from using this technique.

kick it on GameDevKicks.com

Tags: , , , ,
Posted in Blog, General Gamedesign, XNA | 1 Comment »

End of march update

Posted by Roy Triesscheijn on March 25th, 2010

As you might have noticed there where not so much updates as usual this month. Me and a few classmates have been very busy working on a project for Q-Free Netherlands, a company that works on automatic license plate recognition software. Unfortunately we don’t get to work on the core product, but until I see and sign the non disclosure agreement I can’t really say what I’m working. (Nothing so exciting that it should require a NDA to be signed, but it’s standard practice in most industries). The assignment is part of the International Software Engineering Project, and my team works together with three Swedish students via video conferencing. The teachers have set up a very nice TRAC environment and I’m really starting to like TRAC, altough it is a very spartan environment.

Other than that I’ve worked a tiny bit on Space Ace, but I’ve got nothing new to show. I’ve drawn out some ideas with the help of my roommates which have been stuck in my head since I began working this project.

I hope to be able to finish my Immediate GUI tutorial next week, or the week after, so stay tuned for that!

Tags: , ,
Posted in Blog | No Comments »

Immediate GUIs in XNA: Setup and a button

Posted by Roy Triesscheijn on March 10th, 2010

Introduction

Part 2 (Scrollbars) is located here

Immediate GUI’s are a pretty new concept to creating and drawing GUIs. One of the big differences between an Immediate (IM) GUI and a normal GUI is that an IMGUI is non persistent. Every frame a manager determines which screens/buttons/widgets have to be drawn and only these are drawn. There are no Button objects, Form objects or objects at all. GUI items are immediately drawn by calling a method. Most of these methods are prefixed by ‘Do’ to show the immediate nature of the button. Because of this, IMGUIs have a very low memory profile. However some objects are created every frame for drawing purposes and these might go havoc with the garbage collector if you don’t watch them properly (especially on the Xbox).

Because no objects are used, we have to use a special trick to keep track of ‘events’. To accompany this, every GUI item that can have a certain state, or can return something (for example a button, for which we want to know if it was clicked) is given a unique id (usually an integer).  The IMGUI manager holds a couple of variables to determine what item was clicked, what item the mouse was over and what item is receiving keyboard input. So the state literally consists of 3 integers, instead of a great series of objects.

Let’s create a framework for our own IMGUI in XNA.

Setup

Fire up a new XNA Windows Game project and create a new class called IMGUI. Add the following using statements:

using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

After that add the following fields:

private SpriteBatch spriteBatch;
private MouseState mouse;
private int hotItem = -1;
private int activeItem = -1;

We need a SpriteBatch to draw our GUI. The hotItem will store the ID of the item where the mouse is over. The activeItem will store the item being clicked. We will also store the mouse state so we don’t have to get the mouse state in every GUI item.

Let’s add an update method to automatically update our mouse.

public void Update(GameTime gameTime)
{
    mouse = Mouse.GetState();
}

Nothing fancy here, but this will keep track of the mouse.

We want our IMGUI to be selfcontained but we still need to begin and end our spriteBatch. We also need to clear the hotItem (the item where the mouse is over) before beginning. And at the end we need to check if the mouse is still pressed, if not we need to store in activeItem that no item is being clicked. To accommodate this, we will make a Begin() and End() methods, not unlike those of the normal spriteBatch.

public void Begin()
{
        //Clear hot items before we begin.
        hotItem = -1;
        spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
}

public void End()
{
    spriteBatch.End();
    //If the user isn't clicking anything anymore, unset the active item.
    if (mouse.LeftButton == ButtonState.Released)
    {
        activeItem = -1;
    }
}

It might still seem a bit odd why we have to do this. But when we create our first GUI item, it will make a lot more sense. So let’s get right on it!

/// <summary>
/// Draws a standard button with specified texture at the location of the rectangle
/// and returns if the button was clicked.
/// </summary>
/// <param name="id">Unique ID</param>
/// <param name="rectangle">Rectangle specifying the position of the button</param>
/// <param name="texture">Texture for the button</param>
/// <returns>True if button was clicked, otherwise False</returns>
public bool DoButton(int id, Rectangle rectangle, Texture2D texture)
{
      //Determine if we're hot, and maybe even active
      if (MouseHit(rectangle))
      {
      	hotItem = id;
            if (activeItem == -1 && mouse.LeftButton == ButtonState.Pressed)
                    activeItem = id;
      }

      //Draw the button
      Color drawColor;
      if (hotItem == id)
      {
      	if (activeItem == id)
            {
            	drawColor = Color.White;
            }
            else
            {
                 drawColor = Color.LightGray;
            }
      }
      else
      {
            drawColor = Color.Gray;
      }
            spriteBatch.Draw(texture, rectangle, drawColor);

      //If we are hot and active but the mouse is no longer down, we where clicked
      //Line updated after comment by anonymous user, I feel so silly now!
      return mouse.LeftButton == ButtonState.Released && hotItem == id && activeItem == id
}
//Small helper function that checks if the mouse is contained in the rectangle
//Might even be unneeded but I like not having to manually write ‘new Point…’ every time.
private bool MouseHit(Rectangle rectangle)
{
      return rectangle.Contains(new Point(mouse.X, mouse.Y))
}

As you can see this is not much code for a button, because we got rid of all the state information and just bother ourselves with drawing a button, we don’t need to do much at all. Let’s look at what we have here.  First we determine if the mouse is over our button. If that is the case we are ‘hot’. We set the hotItem to our id, we also check if no item is active, and if the mouse’s left button is pressed. If so we set ourselves to be the activeItem as well.

We then start to draw our button (nothing fancy, we just change the tint we apply to our texture, and then draw the texture at the specified place).

At the end of our method we check if the mouse was released. If the mouse released and we where the hot and active item (the mouse is over our button and the mouse was pressed when over our button) then we return true to signal that we where clicked, else we return false. Because we store those nifty hot and active item integers this is all we need to determine if we were pressed.

Using the button and the IMGUI would look something like this:

        IMGUI imgui = new IMGUI(spriteBatch);
        private Texture2D buttonTexture;
        public void DrawImGui()
        {
            imgui.Update(gameTime); //normally you would do this in the Update method of your screen
                                              //but for code-compactness reasons in tutorials, I'll just add it here
            imgui.Begin();

            if (imgui.DoButton(1, new Rectangle(0, 0, 64, 64), buttonTexture))
            {
                Console.Out.WriteLine("The button with id: 1 was pressed");
            }

            //More GUI items

            imgui.End();
        }

Easy isnt it? Just make sure that you keep your ids unique, and that you give the same button the same id every frame. Of course after a button is no longer used, you can reuse the id (make sure though that you wait at least one frame, or to check that the hotItem and activeItem where not set to the id you are going to reuses, else some false clicks might occur, but generally this shouldn’t be a problem).

If there is more animo I’ll write a following part somewhere next week. Here we are going tot tackle scrollbars and textfields, which are slightly more interesting because they require their own output to be inputted next frame.

Oh btw, one of the biggest sources on immediate GUIs is the website mollyrocket.com IMGUI video I’ve directly linked the one hour long video. Skip the first few minutes about “why this is a video tutorial, because he doesn’t have much time etc..” and delve straight into the interesting part!

Update 30-03-2010 added a call to imgui.Update(..) which I forgot and only saw in the next installment in this series.

kick it on GameDevKicks.com

Tags: , , , , , ,
Posted in Blog, General Gamedesign, XNA | 6 Comments »