This time around we want to know about your favourite / most used Visual Studio add-in. I can’t include them all so if your favourite isn’t here, be sure to add a comment to this post to let the world know. Otherwise, Visual Studio extensions, prepare to do battle…
I must admit I’m really enjoying reading Learning XNA 3.0 by Aaron Reed – so much so I even bought a few extra copies and gave them away on Twitter. Of course there are plenty of other places to learn about XNA. The XNA Creators Club Online has just unveiled a fantastic resource for people who want to learn about building XNA games for Windows Phone 7 as part of their educational series on XNA Game Studio 4.0.
Create Games for Windows Phone 7 includes an Education Roadmap that will walk you through an introduction to building 2D and 3D games on the platform, how to optimise for performance and how to add some polish to your game to give it that professional touch.
The first set of labs / samples is available now and looks like this:
Others will follow in quick succession. You can also follow the team on Twitter: @XNACommunity.
I think I’ll finish the book before I move onto those though I’m tempted to take a quick look just to check them out.
BTW, I’m trying to get hold of some more Windows Phone 7 related books to give away. Make sure you’re following me on Twitter at @MikeOrmond – that’s where I’ll announce when I have some more to give away.
Just a quick one to say I noticed the patterns and practices team have published a new Windows Phone 7-related guide.
Key themes are a WP7 client backed by a Windows Azure cloud service. As you’d expect from p&p, this stuff is very comprehensive.
If you want to know more, check out the project overview, high-level architecture and UI mockups.
Look out for more about this and related projects in next week’s MSDN Flash.
Another example of where you might want to access XNA APIs from a WP7 Silverlight application; touch gesture support. Although Silverlight offers manipulation support, it has no direct support for the higher level concept of “gestures” (eg tap, flick). You could certainly build that yourself in Silverlight OR you may be able to use the gesture support from the XNA Framework. I say “may” as I haven’t tested this exhaustively but my initial efforts suggest it seems to work just fine.
To access the XNA gesture support you’ll need to add a reference to the Microsoft.Xna.Framework.Input.Touch XNA assembly. I’ve also added a reference to Microsoft.Xna.Framework as that contains the definition for the Vector2 struct that I use to give some feedback of the gesture position / scope for the purposes of the demo. You may not need it in your app.
In the Microsoft.Xna.Framework.Input.Touch namespace is a class called TouchPanel that is the entry point for gesture support in XNA. It allows us to enable gestures, specify what types of gestures we want to register an interest in, check if a gesture is “available”, read available gestures etc.
An XNA application operates in a “game loop”. In other words, rather than being event-driven (the user has clicked on a button), it’s time based and polls for input at specific intervals (typically 30 times / second on a WP7 device). As a result there is no way for the TouchPanel to notify us that a gesture has occurred. We can’t subscribe to a GestureReady event or anything of that nature. However, Silverlight does expose touch related events (manipulations) so, by hooking into these (in my case I just used ManipulationCompleted) I know that some touch event has occurred and I can query the TouchPanel to see if a gesture is available.
Here’s the app UI (not much to it in this case):
I’ve wired up the ManipulationCompleted event to the LayoutRoot element (Grid).
<Grid x:Name="LayoutRoot" Background="Transparent" ManipulationCompleted="ManipCompleted">
And here’s the code:
using System.Threading; using System.Windows.Input; using Microsoft.Phone.Controls; using Microsoft.Xna.Framework.Input.Touch; namespace Gestures { public partial class MainPage : PhoneApplicationPage { public MainPage() { InitializeComponent(); // Enable gestures and subscribe to flick and tap TouchPanel.EnabledGestures = GestureType.Flick | GestureType.Tap; } // Silverlight can notify us that a touch manipulation has completed // Seems like a good time to check if we have a gesture private void ManipCompleted( object sender, ManipulationCompletedEventArgs e) { // The IsGestureAvailable property will tell us if a gesture // has been recognised. It's possible there's more than one while (TouchPanel.IsGestureAvailable) { // Read the current gesture GestureSample gesture = TouchPanel.ReadGesture(); // Temporarily update page title to indicate type of gesture // and its properties (for the purpose of the demo). if (gesture.GestureType == GestureType.Flick) { PageTitle.Text = string.Format( "flick {0}, {1}", gesture.Delta.X, gesture.Delta.Y); RestoreTitleDelayed(1500); } else { PageTitle.Text = string.Format( "tap {0}, {1}", gesture.Position.X, gesture.Position.Y); RestoreTitleDelayed(1500); } } } // Queue a work item on a separate thread (so we don't lock the UI) // to restore the page title after a specified delay private void RestoreTitleDelayed(int delay) { ThreadPool.QueueUserWorkItem((object o) => { Thread.Sleep(delay); Dispatcher.BeginInvoke(() => { PageTitle.Text = "waiting"; }); }); } } }
Now when I either tap or flick on the screen, the gesture is recognised and reported (briefly) in the page title. Here’s a quick video of the demo app in action:
One of the things I showed at the WPUG meeting was accessing XNA APIs from Silverlight. In some cases because it’s the only way to achieve what you need (eg access to the microphone) and in others because it makes your life easier (eg gestures). In this post I’ll cover microphone access from Silverlight. Peter Foot’s blog entry helped me a lot in getting this up and running.
Access to the microphone is provided through the Microsoft.Xna.Framework.Audio namespace in the Microsoft.Xna.Framework assembly. You’ll need to add a reference to this XNA assembly from your WP7 Silverlight app if you need microphone access.
The class we’re interested in is Microphone. This class provides access to all the available microphones on the system and exposes a static property – Default – that returns the Microphone instance for the current default recording device. Once we Start the microphone, it begins buffering data and, at some point, will fire the BufferReady event. At this point it’s our responsibility to empty the buffer. This goes on until we want to stop recording. To do that we simply call Stop().
Once we have this data we can use the SoundEffect class to play it back and even mess with it a little. I’ve wired the pitch parameter up to a slider in my app so I can sound like either Pinky and Perky or Don LaFontaine depending on my mood. Here’s video of the app in action:
As you can see, the UI is ultra-simple:
Start and Stop are just buttons to start and stop recording (for ease, stop also initiates playback). The pitch slider is on the right.
using System; using System.IO; using System.Windows; using Microsoft.Phone.Controls; using Microsoft.Xna.Framework.Audio; namespace HelloSoundWorld { public partial class RecordSound : PhoneApplicationPage { MemoryStream ms; Microphone mic = Microphone.Default; // Wire up an event handler so we can empty the buffer when full // Crank up the volume to max public RecordSound() { InitializeComponent(); mic.BufferReady += Default_BufferReady; SoundEffect.MasterVolume = 1.0f; } // When the buffer's ready we need to empty it // We'll copy to a MemoryStream // We could push into IsolatedStorage etc void Default_BufferReady(object sender, EventArgs e) { byte[] buffer = new byte[1024]; int bytesRead = 0; while ((bytesRead = mic.GetData(buffer, 0, buffer.Length)) > 0) ms.Write(buffer, 0, bytesRead); } // The user wants to start recording. If we've already made // a recording, close that MemoryStream and create a new one. // Start recording on the default device. private void start_Click(object sender, RoutedEventArgs e) { if (ms != null) ms.Close(); ms = new MemoryStream(); mic.Start(); } // The user wants to stop recording. Checks the microphone // is stopped. Reset the MemoryStream position. // Play back the recording. Pitch is based on slider value private void stop_Click(object sender, RoutedEventArgs e) { if (mic.State != MicrophoneState.Stopped) mic.Stop(); ms.Position = 0; SoundEffect se = new SoundEffect( ms.ToArray(), mic.SampleRate, AudioChannels.Mono); se.Play(1.0f, (float)slider1.Value, 0.0f); } } }
Run this and you’ll hit an InvalidOperationException. There’s something else we need to do:
We need to add some boilerplate code to make sure the XNA Framework is happy. You can find more information here.
Add a new class (in your App.xaml.cs will do):
public class XNAAsyncDispatcher : IApplicationService { private DispatcherTimer frameworkDispatcherTimer; public XNAAsyncDispatcher(TimeSpan dispatchInterval) { this.frameworkDispatcherTimer = new DispatcherTimer(); this.frameworkDispatcherTimer.Tick += new EventHandler(frameworkDispatcherTimer_Tick); this.frameworkDispatcherTimer.Interval = dispatchInterval; } void IApplicationService.StartService(ApplicationServiceContext context) { this.frameworkDispatcherTimer.Start(); } void IApplicationService.StopService() { this.frameworkDispatcherTimer.Stop(); } void frameworkDispatcherTimer_Tick(object sender, EventArgs e) { FrameworkDispatcher.Update(); } }
And hook this up in the constructor for the App (Application) class:
this.ApplicationLifetimeObjects.Add( new XNAAsyncDispatcher(TimeSpan.FromMilliseconds(50)));
Which adds it as a service to the Silverlight application. XNA should now be happy. Record away!
Today we’re hosting one of our Windows Phone 7 deployment labs and I’ve been spending some time with a partner trying to determine if they’ll be able to do what they need to do on a Windows Phone 7 device. They have a rich media app which needs to be able to modify the HTML DOM based on certain events. We needed to explore whether we could grab some info from one web page and use it to modify another page.
We didn’t get off to the greatest of starts. Using the WebBrowser control and InvokeScript() we continually encountered an 80020006 error. We tried everything to get to the bottom of it. To cut a long story short we were being given the runaround by the bugbear of all webdev debugging – caching. Despite restarting the emulator, cached versions of the page were still being served. This wasn’t immediately obvious however and only after a couple of hours of hair-pulling and straw-clutching did we figure out what was happening.
So, I’m happy to confirm all works as expected and happy to provide the warning *watch out for caching of WebBrowser on the emulator*.
Here’s some code to illustrate what we wanted to do. Firstly a simple HTML page hosted on my server:
<html> <head> <script> function hello() { return 'hello'; } function sayHello(sayWhat) { return sayWhat; } </script> </head> <body> Hello </body> </html>
There are actually two identical pages (ie with the same source). I’ve called them Page1 and Page2 just for the novelty value. The app itself looks like this:
ie two WebBrowser controls. That’s it. The idea is we navigate to one page, call a JavaScript function, get the return value and pass that to a JavaScript function in the other page. Here’s the XAML for the WebBrowser controls:
<phone:WebBrowser Name="webBrowser1" IsScriptEnabled="True" /> <phone:WebBrowser Name="webBrowser2" IsScriptEnabled="True" Grid.Row="1" />
Note that the IsScriptEnabled property on each WebBrowser control is set to True – a requirement in order to be able to invoke a JavaScript function in the loaded page. The rest of the code looks like this:
using System; using System.Diagnostics; using System.Windows; using System.Windows.Input; using Microsoft.Phone.Controls; namespace WindowsPhoneApplication1 { public partial class MainPage : PhoneApplicationPage { const string uriBase = @"http://mikeo.members.winisp.net/"; public MainPage() { InitializeComponent(); Loaded += new RoutedEventHandler(MainPage_Loaded); } void MainPage_Loaded(object sender, RoutedEventArgs e) { string noCache = DateTime.Now.ToLongTimeString(); webBrowser1 .Navigate(new Uri(uriBase + @"page1.html?t=" + noCache)); webBrowser2 .Navigate(new Uri(uriBase + @"page2.html?t=" + noCache)); } private void MouseDown(object sender, MouseButtonEventArgs e) { string s1 = (string)webBrowser1.InvokeScript("hello"); Debug.WriteLine(s1); string s2 = (string)webBrowser1.InvokeScript("sayHello", s1); Debug.WriteLine(s2); } } }
My intention here is not to show off some magical feature but just to confirm this works as I was beginning to doubt my sanity. Note the use of the querystring in the URIs (adding a time parameter). This prevents the page being cached while debugging. Shame we didn’t spot this earlier :(.
Paul’s post yesterday about his “WP7 Dev Lab in a box” made me question my whole approach to life. Here’s Paul’s setup:
My aspirations were a little lower. Here’s my setup:
Yes, those are my (clean) socks. Admittedly Paul has more devices but I’d argue it’s still overkill. I even have a system in operation where Samsung devices get cream socks; LGs get beige. What could be simpler and more effective? Unlike Paul’s kit, mine may not survive a plane crash but then I have no plans to fly anywhere in the immediate future.
Firstly thanks to Matt and WPUG for the great meeting last night and to all the people who braved the weather to turn up and listen to me chat about a few aspects of Windows Phone 7. I don’t have any slides to publish – I didn’t use any – but I did cover the following:
I’ll follow-up with a few posts with source for the demos etc which some of you will hopefully find useful
This week’s MSDN Flash guest post is from friend and colleague Eric Nelson. Eric’s just moved to a new role inside Microsoft (good luck Eric!) but was more than happy to put pen to paper for the MSDN Flash to share his thoughts on a couple of recent announcements. Cue Eric….
Using the right tool for the job - introducing WebMatrix and LightSwitch
For many years being a .NET developer meant being a Windows Forms developer or being a Web Forms developer. Two technologies for two distinct types of applications - Smart Clients and web applications. Those were simple times, fondly remembered.
Fast forward to 2010. We also now have Windows Presentation Foundation, Silverlight and ASP.NET MVC. We went from two to five significant technology choices for applications in a relatively short time. Yet, I don't come across many developers unhappy with this situation. Interestingly over the last month I have seen brand new applications being built using each of these five technologies. Why can this be true? It turns out the underlying reasons are pretty straightforward:
Indeed there are developers using Visual Foxpro, Access, "classic ASP", PHP and Visual Basic 6.0 because of the reasons above.
Another observation I would make is that the .NET Framework we have in 2010 is a lot larger than the one we had in 2002. Perhaps a little unkindly, I sometimes refer to the .NET Framework as a "kitchen sink" Framework - it includes everything including the kitchen sink :-). The advantage is I am confident that I can solve pretty much everything with the .NET Framework. But it does sometimes feel a little overwhelming - too many knobs, too many buttons, too many options, too many choices. Especially if you are a new developer, new to the .NET Framework or indeed a "non-professional" developer who just wants something a little more than HTML.
We realized that there was more that we could do to help. Which is why in the space of only a few weeks we have released two new approaches to building applications - WebMatrix and Visual Studio LightSwitch. Both at their core are about simplifying building applications using the .NET Framework. It is unlikely you would want to become proficient in both as they target different scenarios - but hopefully the following will encourage you to try both. Enjoy.
In early July we released the beta of WebMatrix. WebMatrix is an "all in one" tool that in a single install delivers everything needed to start building dynamic HTML web pages and sites. Although it does support development with PHP, it offers a new .NET Framework based model to create web applications as a group of ASP.NET Web Pages. Server side C# or VB can be "in-lined" with the client side HTML markup. It is targeted at non-professional developers to make it easier to create new web page or sites from scratch, or use Microsoft’s Web Application Gallery to customize popular ASP.NET and PHP open source community applications.
Top level features:
You can download the beta now.
At the start of August we announced Visual Studio LightSwitch. LightSwitch is intended to be the simplest way to build business applications for the desktop and cloud. It provides the tools to rapidly develop professional applications from pre-built templates in a simplified development experience.
LightSwitch is targeted at business developers and power users creating custom LOB applications leveraging data from multiple sources that can be easily deployed to the desktop or cloud. In many respects, LightSwitch harks back to the days of the 4GL. This is not a bad thing. I have had some great experiences building small and large solutions using the better 4GLs of the early 1990's in a fraction of the time it would have taken me in C/C++.
The first public beta of LightSwitch will be available for download by the time you read this.
Posted via email from mikeormond's posterous
Time to turn to serious matters in this MSDN Flash poll. When it comes to working late at the office, what’s the fuel that keeps your brain working best? What do you turn to when the chips are down (or still in the fryer)? What is your food of champions?
As they say on Masterchef, “Voting doesn’t get tougher than this!”
And, almost catching up with myself, here are the results of the Social Media poll from the last Flash (11th August). This is a slightly different style where you can rate from 1 to 5 (or opt not to vote at all for a particular option).
The results below reflect the scores for each category averaged across the people who voted in that category. eg a very few people voted for Virtual Worlds and the score of 1.47 reflects the average of those people. It doesn’t assume a score of 0 for those that didn’t vote. Sadly, there’s no way I can untangle the results to see what they’d look like if I made the assumption that not voting for a particular category meant you didn’t use it at all. I shall have to design the survey more carefully in future (or use a different survey tool).
Anyway, it seems Social Networking, Forums, Blogs and MicroBloggin (I think that should have said MicroBlogging) all come out fairly close at the top.
I’m a bit surprised to see Video and Photo sharing sites so low down. Virtual Worlds? Were they just a fad?
Apologies, I just realised that I’d missed out a complete set of results from the MSDN Flash poll. Back in the 28th July edition we asked what your main job function was. Of course I got a lot of feedback saying “I do 7 of these” and the like. Honestly I know. I understand the world doesn’t conform to the nice simple model Microsoft tends to try and apply to it. That was why I used the word “main”.
If you spend 14.29% of your time on each of them equally, then just pick one. It’s only a survey after all. Pick your favourite. Pick the one you wished you spent 100% of your time on. Now it’s a survey of “Main Job Function + Preferred Job Function of Those Wearing Many Hats”.
I like that. It has a nice ring to it.
The good news is the right sort of people do seem to be reading the Flash. This marketing lark is amazing isn’t it – it’s like magic. I’m curious what the 9.2% “Other IT Professional”’s do. Let me know; given I came up with the categories it’s clear they could do with some refinement!
My colleague Paul Foster and I will be running some Windows Phone 7 deployment labs – as promised – to enable folks building WP7 applications to deploy and test their applications on devices. We have a series of London dates at the moment – we do plan to add other locations as well.
Dates are as follows (or check the calendars below):
August: 26th, 31st
September: 1st, 6th, 13th, 16th, 21st, 22nd, 24th, 28th, 29th
October: 6th, 7th
All these labs will be held at Microsoft’s London offices near Victoria. You’ll be able to deploy your app to a developer device, test it, do some debugging, iterate, usual kind of stuff. You can book either a morning or an afternoon session. You’ll need to bring your own laptop with you.
All devices will be running a build compatible with the latest public release of the Windows Phone Developer Tools (currently the beta release). In other words, your app should simply deploy and run without changes. There will be at least one MS person there (probably Paul or myself) to help.
If you want to attend a lab, drop me a mail at mike.ormond AT microsoft.com (or get in touch via this blog or Twitter - @MikeOrmond – I’m not fussy). Tell me a little about who you are and the app you’re building and let me know which is your preferred date and whether you’d like a morning or afternoon session. We’ll do our best to accommodate you.
Looking forward to seeing some cracking apps over the next few weeks.