Forum rules
A place to show off your creations with noesisGUI and comment on them. From XAML snippets to full projects.
 
User avatar
sfernandez
Site Admin
Topic Author
Posts: 1165
Joined: 22 Dec 2011, 19:20

RPG Stats Panel

09 May 2014, 11:18

This example explains how to use data binding to show the stats of a player in a simple panel control. The design is kept simple because it's not the goal of this sample. The code is written for Unity, but can easily be adapted to native C++ classes.
SimpleStatsPanel.png
First we create a xaml that describes the interface of a Stats control (that could be reused to show the stats of various players at the same time if you want):

Assets/RPG/StatsPanel.xaml
<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="StatsPanel">
    
    <UserControl.Resources>
        <Style x:Key="HeaderText" TargetType="TextBlock">
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="FontFamily" Value="#Barkentina 1"/>
            <Setter Property="FontSize" Value="13"/>
            <Setter Property="Margin" Value="12,2,0,0"/>
            <Setter Property="Stroke" Value="#80000000"/>
            <Setter Property="StrokeThickness" Value="0.75"/>
        </Style>
        <Style x:Key="StatText" TargetType="TextBlock">
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="FontFamily" Value="#Barkentina 1"/>
            <Setter Property="FontSize" Value="20"/>
            <Setter Property="Stroke" Value="#80000000"/>
            <Setter Property="StrokeThickness" Value="1.5"/>
        </Style>
        <Style x:Key="StatBar" TargetType="ProgressBar">
            <Setter Property="MinHeight" Value="5"/>
            <Setter Property="Foreground" Value="Silver"/>
            <Setter Property="Background" Value="Gray"/>
            <Setter Property="Margin" Value="8,0"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ProgressBar">
                        <Border x:Name="PART_Track" Background="{TemplateBinding Background}" CornerRadius="1">
                            <Grid x:Name="PART_Indicator" HorizontalAlignment="Left">
                                <Border Background="{TemplateBinding Foreground}" CornerRadius="0.5" Margin="1"/>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <LinearGradientBrush x:Key="SeparatorBg" EndPoint="1,0" StartPoint="0,0">
            <GradientStop Color="#0CFFFFFF"/>
            <GradientStop Color="#F2FFFFFF" Offset="0.15"/>
            <GradientStop Color="#F2FFFFFF" Offset="0.85"/>
            <GradientStop Color="#0CFFFFFF" Offset="1"/>
        </LinearGradientBrush>
    </UserControl.Resources>
    
    <Border BorderBrush="#FFDEEA68" BorderThickness="2" CornerRadius="2" Padding="8">
        <Border.Background>
            <LinearGradientBrush EndPoint="0.5,0" StartPoint="0,0" SpreadMethod="Reflect">
                <GradientStop Color="#BD000000"/>
                <GradientStop Color="#8F000000" Offset="0.25"/>
                <GradientStop Color="#BD000000" Offset="1"/>
                <GradientStop Color="#8F000000" Offset="0.75"/>
            </LinearGradientBrush>
        </Border.Background>
        <StackPanel MinWidth="200">
            
            <TextBlock Text="HEALTH" Style="{StaticResource HeaderText}"/>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                <TextBlock Text="{Binding Health}" Style="{StaticResource StatText}"/>
                <TextBlock Text="/" Style="{StaticResource StatText}" Margin="2,0"/>
                <TextBlock Text="{Binding HealthMax}" Style="{StaticResource StatText}"/>
            </StackPanel>
            <ProgressBar Value="{Binding Health}" Minimum="0" Maximum="{Binding HealthMax}" Style="{StaticResource StatBar}"
                Background="#FF3F892F" Foreground="#FF46FF00"/>

            <Rectangle Height="2" Fill="{StaticResource SeparatorBg}" Margin="0,2"/>

            <TextBlock Text="ATTACK" Style="{StaticResource HeaderText}"/>
            <TextBlock Text="{Binding Attack}" Style="{StaticResource StatText}" HorizontalAlignment="Center" Padding="0,0,0,5"/>

            <Rectangle Height="2" Fill="{StaticResource SeparatorBg}" Margin="0,2"/>

            <TextBlock Text="DEFENSE" Style="{StaticResource HeaderText}"/>
            <TextBlock Text="{Binding Defense}" Style="{StaticResource StatText}" HorizontalAlignment="Center" Padding="0,0,0,5"/>

            <Rectangle Height="2" Fill="{StaticResource SeparatorBg}" Margin="0,2"/>

            <TextBlock Text="GOLD" Style="{StaticResource HeaderText}"/>
            <TextBlock Text="{Binding Gold}" Style="{StaticResource StatText}" HorizontalAlignment="Center" Padding="0,0,0,5"/>

            <Rectangle Height="2" Fill="{StaticResource SeparatorBg}" Margin="0,2"/>

            <TextBlock Text="EXPERIENCE/NEXT" Style="{StaticResource HeaderText}"/>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                <TextBlock Text="{Binding Experience}" Style="{StaticResource StatText}"/>
                <TextBlock Text="/" Style="{StaticResource StatText}" Margin="2,0"/>
                <TextBlock Text="{Binding NextLevel}" Style="{StaticResource StatText}"/>
            </StackPanel>
            <ProgressBar Value="{Binding Experience}" Minimum="0" Maximum="{Binding NextLevel}" Style="{StaticResource StatBar}"
                Background="#FF2F8589" Foreground="Cyan"/>

            <Rectangle Height="2" Fill="{StaticResource SeparatorBg}" Margin="0,2"/>

        </StackPanel>
    </Border>
</UserControl>
Then we create the class that backs up this panel. Notice how we set the DataContext property, so bindings in the xaml can be resolved. The class that provides the bindings to the data, exposes the properties and calls NotifyPropertyChanged to notify Noesis that a property has changed, so we can update the UI:

Assets/RPG/StatsPanel.cs
using UnityEngine;
using System.Collections;

[Noesis.Extended]
[Noesis.UserControlSource("Assets/RPG/StatsPanel.xaml")]
public class StatsPanel : Noesis.UserControl
{
    public StatsPanel(PlayerStats playerStats)
    {
        SetDataContext(playerStats);
    }
}

[Noesis.Extended]
public class PlayerStats : Noesis.BaseComponent
{
    private float _health;
    public float Health
    {
        get { return this._health; }
        set { if (this._health != value) { this._health = value; NotifyPropertyChanged("Health"); } }
    }

    private float _healthMax;
    public float HealthMax
    {
        get { return this._healthMax; }
        set { if (this._healthMax != value) { this._healthMax = value; NotifyPropertyChanged("HealthMax"); } }
    }

    private float _attack;
    public float Attack
    {
        get { return this._attack; }
        set { if (this._attack != value) { this._attack = value; NotifyPropertyChanged("Attack"); } }
    }

    private float _defense;
    public float Defense
    {
        get { return this._defense; }
        set { if (this._defense != value) { this._defense = value; NotifyPropertyChanged("Defense"); } }
    }

    private float _gold;
    public float Gold
    {
        get { return this._gold; }
        set { if (this._gold != value) { this._gold = value; NotifyPropertyChanged("Gold"); } }
    }

    private float _experience;
    public float Experience
    {
        get { return this._experience; }
        set { if (this._experience != value) { this._experience = value; NotifyPropertyChanged("Experience"); } }
    }

    private float _nextLevel;
    public float NextLevel
    {
        get { return this._nextLevel; }
        set { if (this._nextLevel != value) { this._nextLevel = value; NotifyPropertyChanged("NextLevel"); } }
    }
}
Finally, you can create this panel any time and show it in the UI:
void ShowStatsPanel(PlayerStats playerStats)
{
    var statsPanel = new StatsPanel(playerStats);
    this._statsPanelContainer.SetContent(statsPanel);
}
And the result would look like the screenshot at the start of this post.

I hope you liked :)
Attachments
StatsPanel.unitypackage
(741 KiB) Downloaded 319 times

Who is online

Users browsing this forum: No registered users and 2 guests