vGamePadのXAMLを使ったボタンデザイン



ゲームパッドのボタンデザインについて

vGamePadのUI部分はWPF(XAML)でデザインしています。
今回はその部分のみを切り出してまとめています。

まずはVisualStudioのデザイン画面のキャプチャです。
vGamePadのボタンデザイン
一番右端のツィッターボタンは例として掲載しています。

このデザインを構成するXAMLなんですが、サンプルのMainWindow.xamlを全文張ります。

<Window x:Class="GamePadSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStyle="None" Topmost="True"
        Background="Transparent" ShowInTaskbar="False"
        AllowsTransparency="True"
        Title="MainWindow" Height="Auto" Width="Auto">
    <Window.Resources>
        <ResourceDictionary>
            <Style x:Key="gridStyle" TargetType="Grid">
                <Setter Property="Opacity" Value="0.25"/>
                <Setter Property="Width" Value="64"/>
                <Setter Property="Height" Value="64"/>
            </Style>
            <Style x:Key="ellipseStyle" TargetType="Ellipse">
                <Setter Property="Fill" Value="White"/>
                <Setter Property="Stroke" Value="Black"/>
                <Setter Property="StrokeThickness" Value="5"/>
            </Style>
            <Style x:Key="textBlockStyle" TargetType="TextBlock">
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="HorizontalAlignment" Value="Center"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="FontSize" Value="32"/>
                <Setter Property="FontFamily" Value="Segoe UI,Segoe UI Symbol"/>
                <Setter Property="FontWeight" Value="Bold"/>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
    <Canvas x:Name="gamepad_canvas">
        <!-- アナログスティックの例 -->
        <Grid x:Name="stick01" Canvas.Top="0" Canvas.Left="0" Width="128" Height="128" Style="{StaticResource gridStyle}">
            <Ellipse x:Uid="stick01" Style="{StaticResource ellipseStyle}"/>
            <TextBlock x:Uid="stick01" Text="&#xE10A;" FontSize="64" Style="{StaticResource textBlockStyle}"/>
        </Grid>
        <!-- ボタンの例(通常) -->
        <Grid x:Name="button01" Canvas.Top="0" Canvas.Left="144" Style="{StaticResource gridStyle}">
            <Ellipse x:Uid="button01" Style="{StaticResource ellipseStyle}"/>
            <TextBlock x:Uid="button01" Text="1" Style="{StaticResource textBlockStyle}"/>
        </Grid>
        <!-- ボタンの例(キーボード) -->
        <Grid x:Name="button02" Canvas.Top="0" Canvas.Left="224" Style="{StaticResource gridStyle}">
            <Ellipse x:Uid="button02" Style="{StaticResource ellipseStyle}"/>
            <TextBlock x:Uid="button02" Text="&#xE144;" Style="{StaticResource textBlockStyle}"/>
        </Grid>
        <!-- ボタンの例(+字キー下) -->
        <Grid x:Name="button03" Canvas.Top="0" Canvas.Left="304" Style="{StaticResource gridStyle}">
            <Ellipse x:Uid="button03" Style="{StaticResource ellipseStyle}"/>
            <TextBlock x:Uid="button03" Text="&#xE102;" FontWeight="Normal" RenderTransformOrigin="0.5,0.5" Style="{StaticResource textBlockStyle}">
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="90.000"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
        </Grid>
        <!-- ボタンの例(Pathを使った例:vGamePadでは使ってません) -->
        <Grid x:Name="button04" Canvas.Top="0" Canvas.Left="380" Style="{StaticResource gridStyle}">
            <Ellipse x:Uid="button04" Style="{StaticResource ellipseStyle}"/>
            <Path x:Uid="button04" HorizontalAlignment="Center" VerticalAlignment="Center" Width="40.3295" Height="32.775" Stretch="Fill" Fill="black" Data="F1 M 59.7481,27.0756C 58.2644,27.7337 56.6696,28.1784 54.9961,28.3784C 56.704,27.3544 58.0162,25.7329 58.634,23.8008C 57.0352,24.749 55.2645,25.4376 53.3797,25.8086C 51.8705,24.2005 49.7202,23.1958 47.3403,23.1958C 42.771,23.1958 39.0661,26.9003 39.0661,31.4697C 39.0661,32.1181 39.1393,32.7497 39.2804,33.3553C 32.4039,33.0102 26.3071,29.7162 22.2263,24.7102C 21.514,25.9322 21.106,27.3535 21.106,28.8699C 21.106,31.7405 22.5667,34.2731 24.7869,35.7569C 23.4307,35.7138 22.1547,35.3416 21.0392,34.7219C 21.0385,34.7565 21.0385,34.791 21.0385,34.826C 21.0385,38.8348 23.8906,42.1789 27.6756,42.9392C 26.9814,43.1282 26.2504,43.2294 25.4958,43.2294C 24.9626,43.2294 24.4443,43.1775 23.939,43.081C 24.992,46.368 28.0476,48.7603 31.6683,48.8269C 28.8365,51.0462 25.2689,52.369 21.3923,52.369C 20.7245,52.369 20.0659,52.3297 19.4186,52.2533C 23.0802,54.6008 27.4295,55.9708 32.102,55.9708C 47.321,55.9708 55.6436,43.363 55.6436,32.4291C 55.6436,32.0704 55.6353,31.7136 55.6194,31.3586C 57.2362,30.192 58.6389,28.7348 59.7481,27.0756 Z "/>
        </Grid>
    </Canvas>
</Window>

基本的な考え方

vGamePadではタッチスクリーン全域を覆う1枚のウィンドウ(Canvas)上に各ボタンになる部品を配置しています。
上記XAMLを見ていただければわかると思いますがボタンになる部品そのものはButtonではありません。
基本的にGridEllipseTextBlockの3つで構成しています。

<Grid> // <- 1つのボタンを1つのGridで管理する
    <Ellipse /> // <- ボタンの〇を表示
    <TextBlock /> // <- ボタンの中身(文字列)を表示
</Grid>

ボタンテキストのフォント

vGamePadのボタンで利用している通常のフォントはSegoe UIなのですが、キーボードなどの絵文字フォントとしてSegoe UI Symbolを使っています。
XAMLで直接指定する場合、

<TextBlock Text="&#xE144;"/>

のように、”&#xNNNN;”の形式で設定します。
ちなみにプログラム(C#)では”\uNNNN”になります。
どのコードがどんな絵文字なのかはSegoe UI Symbolのページを参照してください。
また、0x10000以降にもいろいろな絵文字が存在します。
絵文字いろいろ

ボタンテキストの回転

+字キーのデザインは上下左右が必要になるため主に音楽の再生に使うPLAYアイコン(0xE102)を回転させて各方向のボタンテキストとしています。
XAMLは回転させることも簡単にできるのですが、ちょっといろいろと必要になります。

<TextBlock Text="&#xE102;" RenderTransformOrigin="0.5,0.5">
    <TextBlock.RenderTransform>
        <TransformGroup>
            <ScaleTransform/>
            <SkewTransform/>
            <RotateTransform Angle="90.000"/>
            <TranslateTransform/>
        </TransformGroup>
    </TextBlock.RenderTransform>
</TextBlock>

RotateTransformのAngleが回転角度を表しています。
90度、180度、270度をそれぞれ指定することでそれぞれの方向を示したように見えるわけです。

フォントにないイメージの指定

vGamePadでは使っていないのですが、ジオメトリを使った図形をボタンイメージとして使うこともできます。

<Path Data="F1 M ... Z"/>

指定方法はいろいろあるのですが、例ではツィッターアイコンをPathで指定しています。
実際、このジオメトリはこんなすごいこともできるようです。
XAML でクラウディアさんを描いてみました(グラバグさんのブログより)
しかしながら素人のわたくしには自作で恰好のいいデザインを作るのは無理でございます。
なので、他力本願、他の方のお力を借りてアイコンを作成します。
今回のようなボタンアイコンのデザインであれば、
Modern UI Iconsをオススメします。
一覧の中からアイコンを選択するだけでXAMLデータを生成してくれる優れものです。
作成されたXAMLを単純にコピペするだけで作れてしまいます。

次回、実際のタッチイベントをどのように処理しているかをまとめます。


Leave a comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です