New Screenshots Posted

April 29, 2009

More screenshots have been posted on the screenshots page.

Advertisements

Building a Game UI System, Part 1

April 28, 2009

In War of Words, there’s a fairly sophisticated UI that displays all of the character attributes while you play the game.  Things like health, status, level, gamerpic, score, and spells needs to be conveyed to the player.  One of the most frustrating things in game creation can be UI programming.

In the past, I’ve pieced together the UI by putting all of the coordinates in code and piecing everything together by hand.  This works only for the simplest UIs.  Now that I’ve got to do something more challenging, it’s time to develop something a little more robust.  The solution is to model a lot of other UI frameworks (for example, WinForms) and make it work for the things I need and within the context of the XNA framework.

We start by making an abstract base class that all UI parts implement.  We’ll call this class UIElement and it will be able to hold references to child elements, have a position (relative to a parent), a size, and it will receive Draw and Update calls to show itself and animate itself if needed.  Here’s the class in it’s entirety:

/// <summary>
/// Represents the base class for UIElements.
/// </summary>
public abstract class UIElement
{
    /// <summary>
    /// Master element constructor.
    /// </summary>
    public UIElement()
    {
        // we're the master!
        MasterElement = this;
        // TODO: set bounds based on viewport
        Bounds = new Rectangle(0, 0, 1280, 720);

        Children = new UIElementCollection();
    }

    /// <summary>
    /// Non-master child element constructor.
    /// </summary>
    public UIElement(UIElement parent, int x, int y, int width, int height)
    {
        Bounds =
            new Rectangle((int)parent.Position.X + x,
                                 (int)parent.Position.Y + y, width, height);
        Parent = parent;

        Parent.Children.Add(this);
        Children = new UIElementCollection();
    }

    /// <summary>
    /// Gets/sets the absolute position of the element.
    /// </summary>
    public Vector2 Position
    {
        get
        {
            return new Vector2(Bounds.X, Bounds.Y);
        }
        set
        {
            Bounds.Offset((int)value.X - Bounds.Left, (int)value.Y - Bounds.Top);
        }
    }

    /// <summary>
    /// Gets the width of the element.
    /// </summary>
    public virtual int Width
    {
        get
        {
            return Bounds.Width;
        }
    }

    /// <summary>
    /// Gets the height of the element.
    /// </summary>
    public virtual int Height
    {
        get
        {
            return Bounds.Height;
        }
    }

    /// <summary>
    /// Gets the rectangle bounds of the element.
    /// </summary>
    public Rectangle Bounds { get; private set; }

    /// <summary>
    /// Gets the parent element of the element.  This will be null
    /// for master elements.
    /// </summary>
    public UIElement Parent { get; private set; }

    /// <summary>
    /// Gets the child element collection.
    /// </summary>
    public UIElementCollection Children { get; private set; }

    /// <summary>
    /// Gets whether any children are contained at this element.
    /// </summary>
    public bool HasChildren
    {
        get { return Children.Count > 0; }
    }

    /// <summary>
    /// Gets/sets the master element.
    /// </summary>
    public static UIElement MasterElement { get; private set; }

    /// <summary>
    /// Gets a value of true if the UI element is the
    /// </ins>master element.
    /// </summary>
    public bool IsMaster
    {
        get
        {
            return this == MasterElement;
        }
    }

    /// <summary>
    /// Draws the element and its children.
    /// </summary>
    public void Draw(SpriteBatch spriteBatch)
    {
        OnDraw(spriteBatch);

        // draw each child
        foreach (UIElement child in Children)
        {
            child.Draw(spriteBatch);
        }
    }

    /// <summary>
    /// Meant to be overridden in the concrete classes in order to
    /// allow an element to draw itself.
    /// </summary>
    ///
    protected virtual void OnDraw(SpriteBatch spriteBatch)
    {

    }

    /// <summary>
    /// Updates the element and its children.
    /// </summary>
    public void Update(GameTime gameTime)
    {
        OnUpdate(gameTime);

        foreach (UIElement child in Children)
        {
            child.Update(gameTime);
        }
    }

    /// <summary>
    /// Meant to be overridden in a concrete class to provide
    /// updating for each UI element.
    /// </summary>
    protected virtual void OnUpdate(GameTime gameTime)
    {

    }

Central to my system is the concept of a “master” UIElement. The master element is the root of the UI hierarchy and represents the entire game screen.  Any child elements of the master element are then placed within the master element relative to it (which makes them relative to the screen itself).  To create the master element, you simply use the parameterless constructor.  There is always a reference available to the master element with the static UIElement.MasterElement property.  Master elements have a value of null for their Parents.

To make non-master elements, you use the second constructor.  This constructor calls for a parent element, the relative x and y coordinates within the parent element and a specific size.  Currently, my UI system does not allow resizing elements but there’s no reason why you couldn’t extend it to do that.

The Position property gets the current position of the upper-left corner of the element.  This position is actually in screen coordinates even though relative coordinates are used to initially position it.  This allows ease of access within the draw routine so that you can pass Position to SpriteBatch to position your sprite (or whatever way you are drawing).  It can also set the element relative to its current position (which in turn is relative to its parent).

You can also see that the Children property allows you to access the child UIElements of the element.  When you construct a non-master element, it will automatically place your element as a child of the parent.

The Update() and Draw() methods are called by your code to update and draw the element and its children automatically.  The protected methods OnUpdate() and OnDraw() are the methods that can be overridden to provide element-specific drawing and updating.  For example, if you are making an UIElement that displays a simple text string, you’d want to override OnDraw() and provide the correct SpriteBatch.DrawString() call to display it.

I’ll be writing more on UIElement and specific implementations of it in future posts.


The Need for Speed

April 24, 2009

Er, perhaps the lack of need for speed… I just played the game while bumping up the speed by several factors.  It becomes very challenging very quickly.  Currently, the speed of the rising blocks is clocked at 3.6px/sec.  This translates to about 2.5 minutes before the screen becomes saturated with blocks and you get killed.  It is a pretty good pace, but anything above it becomes very challenging.  This is sort of a problem because it doesn’t leave a lot of opportunity to make the game harder.  It becomes a frantic make-words game where you start spelling “TIN” and “TAN” all the time.  Not that much fun.

So how do I go about making it harder if the speed of the game shouldn’t increase too much?  The solution may lie in the random letter generation.  In easier difficulties, I could randomly generate the same way I currently am – use a true English letter frequency table.  This creates opportunities to make words that align well with the common language.

So for harder difficulties, I was thinking about skewing the random letter probability table.  This would in essence steal away from frequent letters to make less frequent letters more frequent (I hope that makes sense).  For example, less E’s would be made and more K’s for example.  For the hardest difficulties, X’s, Z’s, and Q’s would be increased.  This of course will lead to players being required to spell harder words and thusly gain more points (leading to more magic and more experience).

The “skewing” I’m talking about wouldn’t necessarily be a lot.  Just adding one more Z to the probability table would increase its chance of appearing by 50%.

On a related note, I was also thinking of increasing the probability of specific letters when other letters are generated.  For example, Q’s are almost always followed by U’s.  If you have no U, you can’t make a word involving Q.  This is sort of a problem because U also happens to be less frequent (the least frequent of all the vowels).  I’ll be thinking more about this one.


Screenshots Posted

April 23, 2009

I’ve put up some screenshots of the prototype.  I’ll probably be posting more as time goes on.  See this page to get a look at them (also linked at the top of this page).


Design Considerations

April 22, 2009

War of Words is progressing nicely.  I’ve been a little torn between two competing thoughts on some of the core gameplay.

The first idea is the simpler of the two.  It involves having special defenses and attacks while playing a battle game.  These defenses and attacks are made by making a word using a special letter.  These special letters appear for every 30 points you receive (that number can be changed of course).  It is a simpler idea to implement because you just need to mark certain letters as “special” and then detect when they are being used.  Then you start some effect code to implement the action (one such action is removing a row from your game board, for example).

The second idea is a more elaborate but more strategic approach – using a spell casting system.  In this case, the same actions are available (actually a lot more of them are available) but you can choose to cast them at anytime as long as you have the ability to do so.  In order to cast a spell, you need to have learned it, you need to equip it, and then you need to have the cost covered.  Cost in this case is in magic points (MP) which is a resource gathered by making words.  Better spells cost more and you have a specific maximum amount of MP that you can use.  This keeps things down to specific levels.

This second idea also implies many other RPG gameplay elements such as level, experience, and hit points.  I’m really leaning towards this model and have pretty much decided on it.

As a player, you’ll be able to bring up to six spells with you into battle.  The spells list will be much larger (25-30 probably) and they will all do different things bringing a lot of different strategies.  You can learn spells one of two ways:  1) at certain levels and 2) defeating a certain enemy will give it to you if you already don’t have it.  Some spells will even carry a further equipment cost.  This cost means that some of them will take more than one “slot” in your equipment list.  A really powerful spell might take 2 or 3 slots and that means you are forced to carry less spells.  You can change your equip list only outside of battles.

Everything in this system is tied to word score.  Word score relates to how many points you get for each word you spell.  This translates to XP (experience) and to MP.  If you win or lost a battle, you get the XP equivalent to your word score.  If you run away from a battle, you get nothing.  MP is replenished in battle with the same score (up to MP max however).   This makes the system a lot simpler.

You are rewarded for words in the following ways:

  • Rarer letters (such as K, Z, Q, X, or J) are worth a lot more than frequent letters (such as S, R, L, N, T, or vowels).
  • Longer words are given bonus points.  Spell a 10 letter word for 15 extra points.  This starts at lengths of 6 or 7 (not decided yet).  Short words consisting of frequent letters score very little points (such as 2-5).  They will help you keep your board managed, but they won’t give you a lot of XP or MP.
  • There are also special letter tiles that double or triple the score of a word (similar to Scrabble).  There are also spells that you can cast that do this same thing for a temporary amount of time.

As you can see, the gameplay is getting more elaborate but is also coming together.  I’ve already started programming some of it.


Making Progress

April 16, 2009

Well, I’m definitely making some progress on the core gameplay mechanic.  Lately I’ve been trying to make the powerup system work correctly.  Every once in a while (after getting a certain amount of points by scoring words), you’ll get a special letter block that looks different than the normal ones – these are powerup blocks.  When you form a word using this special block, something good for you happens.  Here’s a list of some of the things:

  • Halt your rising blocks temporarily
  • Destroy a row out of your side
  • Destroy a column out of your side
  • Advance your opponent’s foul line
  • Retract your foul line

There’s more that I’ll probably think of too.  Most of these are implemented, but they need to be jazzed up and made into nice looking effects.

I’ve also decided on a theme for the backgrounds – medieval tapestries!  I’d like to get some artwork that looks like primitive medieval tapestries made from hand stitching and cross-stitch.  Check out the famous Bayeux tapestry to get an idea of what I mean.  My wife can sew and cross-stitch, so we might even make these “tapestries” for real and then scan them in or take pictures.  I still need to sketch them and neither one of us is an artist….


Working Game Logo

April 13, 2009

I’ve been working on a game title graphic for a little while and I’ve come up with something that might work:

smalltitle1It has a cool rust-like texture on it.  I don’t know if I will keep this style or not, so for right now I’m calling this my “working logo.”