Programming4us
         
 
 
Windows Phone

Programming Windows Phone 7 : Simple Clocks (part 2)

1/6/2011 3:26:21 PM

An XNA clock program doesn’t need a timer because a timer is effectively built into the normal game loop. However, the clock I want to code here won’t display milliseconds so the display only needs to be updated every second. For that reason it uses the SuppressDraw method to inhibit superfluous Draw calls.

Here are the XnaSimpleClock fields:

Example 3. XNA Project: XnaSimpleClock File: Game1.cs (excerpt showing fields)
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont segoe14;
Viewport viewport;
Vector2 textPosition;
StringBuilder text = new StringBuilder();
DateTime lastDateTime;
. . .
}

Notice that instead of defining a field of type string named text, I’ve defined a StringBuilder instead. If you’re creating new strings in your Update method for display during Draw (as this program will do), you should use StringBuilder to avoid the heap allocations associated with the normal string type. This program will only be creating a new string every second, so I really didn’t need to use StringBuilder here, but it doesn’t hurt to get accustomed to it. StringBuilder requires a using directive for the System.Text namespace.

Notice also the lastDateTime field. This is used in the Update method to determine if the displayed time needs to be updated.

The LoadContent method gets the font and the viewport of the display:

Example 4. XNA Project: XnaSimpleClock File: Game1.cs (excerpt)
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
segoe14 = this.Content.Load<SpriteFont>("Segoe14");
viewport = this.GraphicsDevice.Viewport;
}

The logic to compare two DateTime values to see if the time has changed is just a little tricky because DateTime objects obtained during two consecutive Update calls will always be different because they have will have different Millisecond fields. For this reason, a new DateTime is calculated based on the current time obtained from DateTime.Now, but subtracting the milliseconds:

Example 5. XNA Project: XnaSimpleClock File: Game1.cs (excerpt)
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

// Get DateTime with no milliseconds
DateTime dateTime = DateTime.Now;
dateTime = dateTime - new TimeSpan(0, 0, 0, 0, dateTime.Millisecond);

if (dateTime != lastDateTime)
{
text.Remove(0, text.Length);
text.Append(dateTime);
Vector2 textSize = segoe14.MeasureString(text);
textPosition = new Vector2((viewport.Width - textSize.X) / 2,
(viewport.Height - textSize.Y) / 2);
lastDateTime = dateTime;
}
else
{
SuppressDraw();
}

base.Update(gameTime);
}


At that point it’s easy. If the time has changed, new values of text, textSize, and textPosition are calculated. Because text is a StringBuilder rather than a string, the old contents are removed and the new contents are appended. The MeasureString method of SpriteFont has an overload for StringBuilder, so that call looks exactly the same.

If the time has not changed, SuppressDraw is called. The result: Draw is called only once per second.

DrawString also has an overload for StringBuilder:

Example 6. XNA Project: XnaSimpleClock File: Game1.cs (excerpt)
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Navy);

spriteBatch.Begin();
spriteBatch.DrawString(segoe14, text, textPosition, Color.White);
spriteBatch.End();

base.Draw(gameTime);
}

And here’s the result:



SuppressDraw can be a little difficult to use—I’ve found it particularly tricky during the time that the program is first starting up—but it’s one of the primary techniques used in XNA to reduce the power requirements of the program.

Other -----------------
- Programming Windows Phone 7 : Simple Clocks (part 1)
- Windows Phone7: Pinning a Contact to Start
- Windows Phone7: Adding a Picture or Ringtone to a Contact
- Windows Phone7: Deleting a Contact
- Programming Windows Phone 7: XNA Orientation
- Programming Windows Phone 7: Orientation Events
- Windows Phone 7: Editing a Contact
- Windows Phone 7: Finding a Contact
- Windows Phone 7: Adding a Contact
- Windows Phone 7: Linking Contacts
- Programming Windows Phone 7 : Silverlight and Dynamic Layout (part 2)
- Programming Windows Phone 7 : Silverlight and Dynamic Layout (part 1)
- Programming Windows Phone 7 : An XNA Program for the Phone (part 3)
- Programming Windows Phone 7 : An XNA Program for the Phone (part 2)
- Programming Windows Phone 7 : An XNA Program for the Phone (part 1)
- Programming Windows Phone 7 : Points and Pixels
- Windows Phone 7 : Changing Caller ID Settings
- Windows Phone 7 : Forwarding Calls
- Windows Phone 7 : Checking Voicemail
- Windows Phone 7 : Making Conference Calls
 
 
Most View
- Windows Small Business Server 2011 : Deploying Network Printers (part 2) - Installing a Network-Attached Printer, Installing a Network Printer Manually
- Windows Server 2008 : Configuring Windows Media Services (part 10)
- Windows Phone 7 : Image and ImageSource
- Exchange Server 2010 : Edge Transport and Messaging Security (part 2) - Edge Transport Configurations
- Defensive Error Handling : Using Transactions and XACT_ABORT to Handle Errors
- SQL Server 2008: Administering Database Objects - Working with Tables (part 4) - Check Constraints
- Exchange Server 2003 : Creating and Managing Address Lists and Recipient Policies (part 3) - Working with Offline Address Lists & Creating and Applying Recipient Policies
- Building Android Apps : Animation - Sliding Home
- SharePoint 2010 : Using Enterprise Search (part 2) - Administering Content Sources
- Optimizing Exchange 2007 Servers & Monitoring Exchange Server 2007
Top 10
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 3) - Configuring Recipient Filtering
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 2)
- Implementing Edge Services for an Exchange Server 2007 Environment : Utilizing the Basic Sender and Recipient Connection Filters (part 1)
- Implementing Edge Services for an Exchange Server 2007 Environment : Installing and Configuring the Edge Transport Server Components
- What's New in SharePoint 2013 (part 7) - BCS
- What's New in SharePoint 2013 (part 6) - SEARCH
- What's New in SharePoint 2013 (part 6) - WEB CONTENT MANAGEMENT
- What's New in SharePoint 2013 (part 5) - ENTERPRISE CONTENT MANAGEMENT
- What's New in SharePoint 2013 (part 4) - WORKFLOWS
- What's New in SharePoint 2013 (part 3) - REMOTE EVENTS