Rx:SSSsssss... (That's the sound of Reactive Extensions, Windows Phone 7 and a Snake...)
- Posted: Jun 08, 2011 at 6:00 AM
- 6,832 Views
Reactive Extensions is something I've not post on much (cough... at all... cough). Reactive Extensions (Rx) are kind of, sort of, not really, but it's one way to think of them, "LINQ to Events".
Here's a short description from Reactive Extensions for .NET Overview for Windows Phone
Reactive Extensions for .NET Framework is a managed library that provides APIs for writing reactive applications. Reactive applications are driven by their environment. In the reactive model, data streams, asynchronous requests, and events are represented as observable sequences. The application can subscribe to these observable sequences to receive asynchronous messages as new data arrives. Reactive Extensions allows the application to compose these sequences using query operators.
If your application interacts with multiple sources of data, such as user input events, web services requests, and system notifications, the conventional way to manage all of these interactions is to implement separate handlers for each of these data streams. Inside these handlers, you must provide the code to coordinate between all of the different data streams and process this data into a useable form. Reactive Extensions allows you to write a query that combines all of these data streams into a single stream that triggers a single handler. The work of filtering, synchronizing, and transforming the data is performed by the Reactive Extensions query so that your handler can just react to the data it receives and do something with it.
So where's the fun? What would a simple game look like that used Rx? Say maybe a Windows Phone 7 game?
Continuing my experiments with Reactive Extension I put together a small example that show an alternative use of the library to create a little game. The game is the widely known Snake that many of us have played on his own Nokia when it is the sole game in the ancient models. Please take note that the game I wrote is not complete since it is first of all an example of the use of a technology and how it can simplify the development of a slightly complex logic like the one that is behind this game.
The core of the game is based on two separate uses of the Reactive Extensions. From one side I have a main loop that is based on a frequent timeout that in a complete version of the game could be used to change the game speed. In this version it is set to 75 milliseconds. Every time the timeout is elapsed I move forward the Snake of one position saved in two variables XDirection and YDirection. This variable can assume the values of 1 or -1 if the snake is moving along the direction and 0 if the snake is moving along the opposite direction.
The object of the game (note, like Andrea said, it's not a full and complete game, with menus, history, etc) is to drive your snake to an indicated spot on the screen. You drive your snake, which is constantly moving, by touching different parts of the screen, which changes the snake's direction of travel.
Sounds easy, but it's actually kind of challenging.
So what's all the excitement about? The amount of code you don't have to write. The amount of code in this game is amazingly limited. 95% is setup, tear down, infrastructure code. The guts, the primary logic, the dealing with the moving of the snake and handling the user interaction is uses surprisingly little code.
void MainPage_Loaded(object sender, RoutedEventArgs e)
// GESTIONE DEL TOUCH DELLO SCHERMO
ev => this.ManipulationStarted += ev,
ev => this.ManipulationStarted -= ev)
X = Math.Sign(o.EventArgs.ManipulationOrigin.X - 240),
Y = Math.Sign(o.EventArgs.ManipulationOrigin.Y - 400)
if (this.XDirection != 0 && this.YDirection == 0)
this.XDirection = 0;
this.YDirection = o.Y != 0 ? o.Y : this.YDirection;
else if (this.XDirection == 0 && this.YDirection != 0)
this.XDirection = o.X != 0 ? o.X : this.XDirection;
this.YDirection = 0;
// GESTIONE DELLO SNAKE
new Point(0, 0),
p => this.IsRunning,
p => p,
p => TimeSpan.FromMilliseconds(75),
p => this.NewPoint(p))
.TrailWhile(o => o > this.Lenght)
That's really about all there is to the primary game logic. Sure there's drawing methods, and a few helpers, but the working code is what you see above.
Rx is currently under utilized, unappreciated and not on most developers radar screens. But if you're doing anything with events, be they user interaction, external, hardware, etc, etc (and don't most programs?) then Rx might be worth a look.
Here’s a few more links you might find interesting: