Button Masher Game in WPF and C#

I’ve been trying to learn WPF with C# as the backend instead of PowerShell. Since there’s a lot more information on using C# over PowerShell, I decided I would take the plunge and learn as much as I could to create some apps.

This is the first app that I completed. In all honesty, it only took me around 2 hours to get the functionality completed. I did this whilst feeling ill and waiting for the wife to get back from work. I was really surprised by how easy it was for me to understand and write in C# and I was quite proud of the final outcome.

The app will probably look really different on your screen but it looks really nice on my computer. This is what the app looks like once it’s loaded:

The goal of the game is for one person to mash the A button as fast as possible and for another person to mash the B button as fast as possible. The first person to mash their respective buttons 100 times is the winner. It then displays a winning screen and allows the users to play again:

Here is a little GIF of what the game looks and feels like:

And here is the download for the game’s exe file:

ButtonMasher

Now for the nitty gritty stuff. I have included the XML and C# code used for the project below and will also include them as downloads:

XML

<Window x:Class="ButtonMasher.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ButtonMasher"
        mc:Ignorable="d"
        Title="Button Masher" Width="450" MinHeight="145" MinWidth="300" KeyDown="WindowKeyDown" SizeToContent="Height" Icon="Icon.ico">
    <Window.Background>
        <LinearGradientBrush StartPoint="-1,-1" EndPoint="1.5,1.5" >
            <GradientStop Color="#FF018A8F" Offset="0.41" />
            <GradientStop Color="#FF00FFD6" Offset="1" />
        </LinearGradientBrush>
    </Window.Background>
    <Grid Name="Grid">
        <Grid.Background>
            <ImageBrush ImageSource="Winner_Background.jpg" Stretch="UniformToFill" Opacity="0" />
        </Grid.Background>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Label Visibility="Visible" Name="PlayerOneLabel" Content="0" FontSize="46" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontFamily="Arial"  />
        <Label Visibility="Visible" Name="PlayerTwoLabel" Content="0" FontSize="46" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1" Foreground="White" FontFamily="Arial"/>
        <ProgressBar Visibility="Visible" Name="ProgressBar1" Margin="10,5" Background="Transparent" BorderBrush="White" BorderThickness="2" Minimum="0" Maximum="100" Value="0" HorizontalAlignment="Stretch" Height="20"  Grid.Row="1" VerticalAlignment="Center" >
            <ProgressBar.Foreground>
                <LinearGradientBrush EndPoint="0,0.5" StartPoint="1,0.5">
                    <GradientStop Color="#83EAF1" Offset="0"/>
                    <GradientStop Color="#63A4FF" Offset="1"/>
                </LinearGradientBrush>
            </ProgressBar.Foreground>
        </ProgressBar>
        <ProgressBar Visibility="Visible" Name="ProgressBar2" Margin="10,5" Background="Transparent" BorderBrush="White" BorderThickness="2" Minimum="0" Maximum="100" Value="0" HorizontalAlignment="Stretch" Height="20" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5"  >
            <ProgressBar.Foreground>
                <LinearGradientBrush EndPoint="0,0.5" StartPoint="1,0.5">
                    <GradientStop Color="#83EAF1" Offset="0"/>
                    <GradientStop Color="#63A4FF" Offset="1"/>
                </LinearGradientBrush>
            </ProgressBar.Foreground>
            <ProgressBar.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform Angle="180"/>
                    <TranslateTransform/>
                </TransformGroup>
            </ProgressBar.RenderTransform>
        </ProgressBar>
        <TextBlock Name="RulesTextBlock" MouseUp="ToggleRules" Visibility="Visible" Grid.Row="2" VerticalAlignment="Bottom" HorizontalAlignment="Left" FontFamily="Arial" Foreground="White" FontSize="10" Cursor="Hand" >
            See Rules
        </TextBlock>
        <TextBlock Name="WonLabel" Text="Winner" Padding="0,40,0,0" Visibility="Collapsed" Grid.ColumnSpan="2" FontSize="46" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontWeight="Bold" TextDecorations="{x:Null}" Foreground="#FFFECE26" FontFamily="Arial">
            <TextBlock.Effect>
                <DropShadowEffect BlurRadius="1" Direction="320" ShadowDepth="2"/>
            </TextBlock.Effect>
        </TextBlock>
        <Border Name="PlayAgainBorder" Visibility="Collapsed" Grid.Row="1" Cursor="Hand" Grid.ColumnSpan="2" CornerRadius="10" Margin="0,0,0,10" HorizontalAlignment="Center" VerticalAlignment="Center" MouseUp="PlayAgain">
            <Border.Style>
                <Style>
                    <Setter Property="Border.Background" Value="#FF494949" />
                    <Setter Property="Border.BorderThickness" Value="3"/>
                    <Style.Triggers>
                        <Trigger Property="Border.IsMouseOver" Value="True" >
                            <Setter Property="Border.Background" Value="#2ecc71"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Border.Style>
            <Label Content="Play Again" VerticalAlignment="Center" Foreground="White" HorizontalAlignment="Center" VerticalContentAlignment="Center" FontSize="16" FontFamily="Arial"/>
        </Border>
        <TextBlock Name="RulesSection" Foreground="White" Grid.Row="3" Grid.ColumnSpan="2" TextWrapping="Wrap" TextAlignment="Center" Padding="20" Visibility="Collapsed" FontFamily="Arial" FontSize="14">
            The rules are simple, player one (left side) has to mash the 'A' button as fast as possible while player two (right side) has to mash the 'B' button as fast as possible. The first one to reach 100 button "mashes" wins the game!
        </TextBlock>
    </Grid>
</Window>

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ButtonMasher
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        //player one score
        int player1Score = 0;
        int player2Score = 0;

        //LOAD FORM
        public MainWindow()
        {
            InitializeComponent();
        }

        //UPDATE PLAYER ONE SCORE
        void UpdatePlayerOneScore()
        {
            player1Score++;
            PlayerOneLabel.Content = player1Score;
        }

        //UPDATE PLAYER TWO SCORE
        void UpdatePlayerTwoScore()
        {
            player2Score++;
            PlayerTwoLabel.Content = player2Score;
        }

        //SET WON SCREEN VISIBILITY
        void WonScreenVisibility(bool visible)
        {
            if (visible)
            {
                //show won screen
                PlayerOneLabel.Visibility = Visibility.Collapsed;
                PlayerTwoLabel.Visibility = Visibility.Collapsed;
                ProgressBar1.Visibility = Visibility.Collapsed;
                ProgressBar2.Visibility = Visibility.Collapsed;
                RulesTextBlock.Visibility = Visibility.Collapsed;
                RulesSection.Visibility = Visibility.Collapsed;
                WonLabel.Visibility = Visibility.Visible;
                PlayAgainBorder.Visibility = Visibility.Visible;
                Grid.Background.Opacity = 100;
                MinWidth = 350;
                MinHeight = 170;
            }
            else
            {
                //hide won screen
                PlayerOneLabel.Visibility = Visibility.Visible;
                PlayerTwoLabel.Visibility = Visibility.Visible;
                ProgressBar1.Visibility = Visibility.Visible;
                ProgressBar2.Visibility = Visibility.Visible;
                RulesTextBlock.Visibility = Visibility.Visible;
                RulesSection.Visibility = Visibility.Collapsed;
                WonLabel.Visibility = Visibility.Collapsed;
                PlayAgainBorder.Visibility = Visibility.Collapsed;
                Grid.Background.Opacity = 0;
                MinWidth = 300;
                MinHeight = 145;
            }
            //switch "show" or "hide" in rules textblock
            if (RulesSection.Visibility == Visibility.Visible)
            {
                RulesTextBlock.Text = "Hide Rules";
            }
            else
            {
                RulesTextBlock.Text = "Show Rules";
            }
        }

        //WON SCREEN
        void WonScreen(string player)
        {
            if(player == "1")
            {
                WonScreenVisibility(true);
                WonLabel.Text = "Player 1 won!";
            }else if(player == "2")
            {
                WonScreenVisibility(true);
                WonLabel.Text = "Player 2 won!";
            }
        }

        //RESET SCORES AND BARS
        void Reset()
        {
            player1Score = 0;
            player2Score = 0;
            PlayerOneLabel.Content = player1Score;
            PlayerTwoLabel.Content = player2Score;
            ProgressBar1.Value = player1Score;
            ProgressBar2.Value = player2Score;
        }

        //USER PRESSES BUTTON FORM
        private void WindowKeyDown(object sender, KeyEventArgs e)
        {
            //checking which key was pressed
            if (e.Key == Key.A)
            {
                UpdatePlayerOneScore(); 
            }else if(e.Key == Key.L)
            {
                UpdatePlayerTwoScore();
            }

            //calculating progress bar value
            ProgressBar1.Value = player1Score;
            ProgressBar2.Value = player2Score;

            //checking if anyone won
            if (ProgressBar1.Value > 99)
            {
                //player one has won
                WonScreen("1");

            }
            else if (ProgressBar2.Value > 99)
            {
                //player two has won
                WonScreen("2");
            }            
        }        

        //PLAY AGAIN
        private void PlayAgain(object sender, RoutedEventArgs e)
        {
            WonScreenVisibility(false);
            Reset();
        }

        //TOGGLE RULES
        void ToggleRules(object sender, RoutedEventArgs e)
        {
            if (RulesSection.Visibility == Visibility.Collapsed)
            {
                //show rules
                RulesSection.Visibility = Visibility.Visible;
                RulesTextBlock.Text = "Hide Rules";
                SizeToContent = SizeToContent.Height;
                MinHeight = 265;
            }
            else
            {
                //hide rules
                RulesSection.Visibility = Visibility.Collapsed;
                RulesTextBlock.Text = "Show Rules";
                SizeToContent = SizeToContent.Height;
                MinHeight = 145;
            }
        }
    }
}

I really hope you enjoy this little game that I created. Please feel free to use it, change it and distribute your own version at will 🙂

Enjoy!


Leave a Reply