Showing posts with label fun. Show all posts
Showing posts with label fun. Show all posts

Monday, March 17, 2008

Rob Relyea Hates my Mom

Mom, Dad, Kevin

My mother is a lovely woman. So I'm confused as to why Rob dislikes her so much.

Let me back up. Last August (when I was still at my former employer) I did some demos of new features in WPF 3.5 for Channel 9.

I was happy to see Rob reused some of the same demos for his MIX '08 Talk.

When I was watching the Add-In demo, I was surprise to see the data had remained the same--for the most part. My dad--Robert, my brothers--Brian and John, and I were still in the data set.

image

But my mother--Wynette--replaced by "Web Service". I mean, I know WCF is powerful, but it's a poor replacement for the most wonderful woman in the world--even if she has an uncommon name.

I did find it funny that the last name was left unchanged.

image

So come on Relyea. Let's hear it. I think I deserve an explanation. :-)

Wednesday, January 30, 2008

WPF Set: Now in 3D!

I last discussed Set about 3 weeks ago. At the time, my implementation was based on buttons. It worked fine, but when I saw how it looked on a friend's machine running the 'classic' theme I was appalled.

I got thinking: there has to be a way to make this game more interesting.

The answer: 3D and gratuitous animation.

The address for the XBAP hasn't changed: http://j832.com/workBlogFiles/WpfSet/

WPF Set - 3D!

The source code has been checked-in to my SVN repository. The code files actually live under J832.Wpf.BagOTricksApp, but you can build and play with the stand-alone app by loading the J832.WpfSet solution file. (Thank you, CSProj file linking feature.)

Cool stuff:

  • The listbox on the right that displays the matched sets now uses AnimatingTilePanel.
  • First use of the new WPFUtil class, which exposes a set of Animate methods. These basically formalize and abstract my simple attraction-based physics model. I support 1-dimensional (double), 2-dimensional (Point/Vector), and 3-dimensional (Point3D/Vector3D) animation. Check out ZapScroller and AnimatingTilePanel in the source to see the other places these are used.
  • I've also added some helper extension methods to WPFUtil. Very useful.
  • Implemented a couple of super-simple 3D components: ButtonBase3D and ToggleButton3D. An interesting exercise. Hoping to move FlipTile3D to these in the future.

Not cool stuff:

  • Keyboard accessibility has evaporated. With the previous implementation, you could tab around to the buttons and press spacebar to select/unselect a "card". More work than I signed up for in this iteration, but something to keep in mind.
  • WPF handles z-order great in 3D unless you have transparency in your textures. Take a look at the corners of raised cards. Very frustrating. The only work-around is to manually re-order the child elements. Lame.
  • Perf is great...on my super fast workstation. Even on my relatively beefy laptop, I notice some glitching when things are moving around. Ideally, I'd detect machines hardware limitations and degrade the animations. I should probably offer a "turn off the fancy stuff" check box. Eh, V3.

This will of course be included in the next drop of the full bag-o-tricks, but I thought it was cool enough to share out-of-band.

Have fun.

Friday, January 18, 2008

Source code, HTML, and an Exercise for the Reader

No clue why I want to be vague about this. Probably because I'm late for a party, but really wanted to share.

And you're smart. You'll figure it out.

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="VS Copy-Paste to HTML" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <RichTextBox Name="m_richTextBox" TextChanged="m_richTextBox_TextChanged" />
        <TextBox Grid.Column="1" Name="m_textBoxHTML" />
    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void m_richTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        m_textBoxHTML.Clear();
        m_textBoxHTML.AppendText("<div style=\"font-family:monospace;\">" + Environment.NewLine);
        foreach (Paragraph paragraph in m_richTextBox.Document.Blocks.Cast<Paragraph>())
        {
            foreach (Run run in Decompose(paragraph.Inlines))
            {
                m_textBoxHTML.AppendText(toCleanedColoredSpan(run));
            }
            m_textBoxHTML.AppendText("<br/>" + Environment.NewLine);
        }
        m_textBoxHTML.AppendText("</div>");
    }

    private string toCleanedColoredSpan(Run run)
    {
        SolidColorBrush solidColorBrush = run.Foreground as SolidColorBrush;
        if (solidColorBrush == null)
        {
            return cleanString(run.Text);
        }
        else
        {
            if (solidColorBrush.Color == Colors.Black)
            {
                return cleanString(run.Text);
            }
            else
            {
                string colorString = solidColorBrush.Color.ToString();
                Debug.Assert(colorString.Length == 9);

                colorString = colorString.Substring(3);

                return string.Format("<span style=\"color:#{0};\">{1}</span>",
                    colorString, cleanString(run.Text));
            }
        }
    }

    private string cleanString(string source)
    {
        source = HttpUtility.HtmlEncode(source);
        source = source.Replace(" ""&nbsp;");
        return source;
    }

    private static IEnumerable<Run> Decompose(IEnumerable<Inline> inlines)
    {
        foreach (Inline inline in inlines)
        {
            if (inline is Span)
            {
                foreach (Run run in Decompose(((Span)inline).Inlines))
                {
                    yield return run;
                }
            }
            else if (inline is Run)
            {
                yield return (Run)inline;
            }
            else
            {
                throw new NotSupportedException();
            }
        }
    }
}

Tuesday, January 8, 2008

WPF Set - This is a good stopping spot

WPF Set - 2008-01-08

  • The graphics pretty much match the actual game now.
  • Moved the New Game button to minimize accidental clicking.
  • Some small tweaks to the game logic.

URLs are the same as before:

Bleh! The third night this darn game has kept me up past midnight. I need another hobby.

Sunday, January 6, 2008

The Game "Set" in WPF (Redux)

Yesterday (well, early this morning) I posted my first stab at the game Set implemented in WPF.

Amazing what 20 hours of bake time can do.

  • Removed insanely complex and unnecessary optimization that made the code for SetGame.TryPlay almost un-readable.
  • Cleaned up the 'test' mode by removing it. If you build/run DEBUG, you'll get a Test button. If you build/run RELEASE, you won't.
  • Used binding in the WPF app where it makes sense.
  • Added a bunch of caching to the card generation on the WPF side. Re-creating a bunch of brushes and pens is silly.
  • Added a test project: WpfSet_Test to run the data model through its paces.
  • Fixed deployment to actually use Visual Studio Deploy functionality. (Yesterday, I just uploaded the files from the build directory.) If you accessed the XBAP yesterday, please refresh and make sure the title says at least "WPF Set - 2008-01-06" and not "WPF Set - 2008-01-05." If refreshing doesn't move you beyond 2008-01-05, there is something fishy with your application cache. Drop me a line and I'll try to fix it.

The XBAP URL hasn't changed.

I've combined the source and binaries into one zip file [53KB]. I've always thought having dated copies of files was goodness, but then I realized if someone links to the old version, they'll never get updates. I'm going to try to keep an updated read-me in the zip file so folks know what version they've downloaded.

As always, send me an email or a comment if you have questions.

Happy Setting.

The Game "Set" in WPF

Update - 2008-01-06: See this post for new details. Links below have been changed.

In theory, I have so many more important projects to work on. This was one of those ideas that got legs faster than I realized I should be working on something else.

If you haven't heard of Set, check it out company site or the Wikipedia entry.

WPF Set - 2008-01-08

Building the data model was half the fun. This is some of my first code that uses Linq features from .NET 3.5. I'm blown away. Without a doubt as big as generics. Wow!

The UI is super minimal and that was the goal. Get it all working and ponder prettier/sexier things later.

So, if you want to play:

As I've discussed before, you can also take a look at the source on my SVN share using you favorite SVN client.

Future ideas:

  • Add a timer and a notion of players. I think I'd layer this on top of the existing game model to keep things simple and clean.
  • It would be cool to layer a 3D UI on top of the game model, too. I have some crazy ideas based on the Flip3D stuff from the bag-o-tricks.

Hope you enjoy it!

Note 1: Thanks to Karen for the details on making an XBAP project.

Note 2: I'll give a cookie to anyone who sends me an SVN patch that fixes the shapes so they match what's really in the game. (Drop me an email via the link on the right.) 2008-01-08: No cookie for you.

Other bug fixes are always appreciated.