Posts Tagged: XNA

Oktoberfest 2012

This is a video board created for DuClaw Brewing Company to display what’s on tap at the Maryland Brewer’s Oktoberfest. Created to run on Xbox 360 or Windows 7 connected to a big ass Flat Panel television and a set of very loud speakers. The board also plays promotional videos on a set schedule and has a few more animations and effects not shown in this clip.

The board actually runs on 3 different screens all with their own content, beer selection, videos, etc. We wrote the original for Oktoberfest 2009 and it gets updated each year. It’s pretty much a giant video game written with XNA and C#.

You’re gonna want to crank the sound for this. It’s OK, I’ll wait. Done?

This is a demo of what happens on screen when you change the beer selection with the controller.

XNA Multi Monitor Support

The information that follows pertains to an older version of XNA and may not be applicable

Imagine an XNA game running two monitors, one for the 3d game, and a second having a full screen tactical map of the game.

The easy part is actually splitting the game windows to multiple monitors, the difficult part is synchronizing the two parts to work together (which I will leave up to you). You can create a simple subclass of GraphicsDeviceManager and then create the two game windows on separate threads. When instantiating the Game class, pass in the index of the monitor you want to target (the index is visible in the display options dialog of your pc).

public class TargetedGraphicsDeviceManager : GraphicsDeviceManager
    {
        private int target = 1;

        public TargetedGraphicsDeviceManager(Game game, int displayTarget) : base(game)
        {
            target = displayTarget;
        }

        protected override void OnPreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs args)
        {
            args.GraphicsDeviceInformation.PresentationParameters.FullScreenRefreshRateInHz = 0;
            args.GraphicsDeviceInformation.PresentationParameters.IsFullScreen = false;

            base.OnPreparingDeviceSettings(sender, args);
        }

        protected override void RankDevices(List<GraphicsDeviceInformation> foundDevices)
        {
            List<GraphicsDeviceInformation> removals = new List<GraphicsDeviceInformation>();
            for (int i = 0; i < foundDevices.Count; i++)
            {
                if (!foundDevices[i].Adapter.DeviceName.Contains("DISPLAY" + target))
                    removals.Add(foundDevices[i]);
            }
            foreach (GraphicsDeviceInformation info in removals)
            {
                foundDevices.Remove(info);
            }

            base.RankDevices(foundDevices);
        }
    }

In your game class, just replace the GraphicsDeviceManager with your new subclass and provide a new constructor for targeting the display index. We also add a call in the Update method to toggle to full screen on the first pass.

public class AmazingGame : Microsoft.Xna.Framework.Game
    {
        TargetedGraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Game1()
        {

        }

        public Game1(int monitorIndex) : this()
        {
            graphics = new TargetedGraphicsDeviceManager(this, monitorIndex);
            Content.RootDirectory = "Content";
        }

protected override void Update(GameTime gameTime)
        {
            // full screen
            if (!graphics.IsFullScreen)
                graphics.ToggleFullScreen();

            // other code

            base.Update(gameTime);
        }

// ALL OTHER CODE FOR THE GAME CLASS

}

In your applications call to Main() you need each game window running on its own thread, so create a new thread for each window you want to run and call Join() to wait for it to exit.

static class Program
    {
        static void Main(string[] args)
        {
            ThreadStart runLeftSideDelegate = new ThreadStart(RunLeftSide);
            Thread runLeftSideThread = new Thread(runLeftSideDelegate);
            runLeftSideThread.IsBackground = false;
            runLeftSideThread.Start();

            ThreadStart runRightSideDelegate = new ThreadStart(RunRightSide);
            Thread runRightSideThread = new Thread(runRightSideDelegate);
            runRightSideThread.IsBackground = false;
            runRightSideThread.Start();

            runLeftSideThread.Join();
            runRightSideThread.Join();
        }

        static void RunLeftSide()
        {
            int index = 1;
            using (AmazingGame game = new AmazingGame(index))
            {
                game.Run();
            }
        }

        static void RunRightSide()
        {
            int index = 2;
            using (AmazingGame game = new AmazingGame(index))
            {
                game.Run();
            }
        }

    }

That’s pretty much as easy as it gets, and there may be some room for improvement there. You can use some other classes to help synchronize your game windows, just remember to thoroughly check for run/lock/race conditions in the shared classes and data.

Gearing up for Oktoberfest with XNA

In October of 2009 we decided to spice up the local Oktoberfest with some technology.

Using an Xbox 360, a 52″ LCD TV, and some liberally applied XNA via C# we cooked up some pretty good results.

It all started with the problem that we needed to display which beers we had on tap at any given time. The old method was using magnetic signs but we also wanted to show some videos during the event. So we brainstormed a little and came up with the idea of writing a video game in C# that would run off the Xbox 360. The idea was that we could change the beers currently on tap (and displayed on our huge 52″ LCD) using the wireless controller. We wired the videos up to a countdown and the played along at specified times during the event.

The idea was a little crazy at first, but the results were phenomenal. The crowd reaction was hard to put into words and the other breweries presenting beer that day were less than enthusiastic about our stealing the show.

This is a video clip of what happened on screen when we used the wireless controller to change the beer. HINT: Crank up your speakers for this one to get the full effect!

http://www.facebook.com/v/104608602901296

Here is a really good blogpost about the event involving us:
http://beerinbaltimore.blogspot.com/2009/10/weekends-events.html

This is a clip of the crowd reaction, the video isn’t the greatest quality but we managed to rock the house.