Article

# Soccerlight World Cup 2010

By , 11 Jul 2010
 Rate this:

## Introduction

This is my first Silverlight game. Some months ago, I had the idea to create something related to the ongoing 2010 FIFA World Cup, but for some time, I was asking myself what could be done? Fortunately, my childhood memories helped me to answer this question.

This game is a product of hours of hard work, mixing both study and trial-and-error approaches. Fortunately, when you really put focus on something, the learning curve starts getting easier. When the road is paved, you are ready to run.

## Background

In Brazil, there is a very well-known game named "Futebol de Botão" (Button Football), or "Futebol de Mesa" (Table Football), which deserves at least a brief note.

In the beginning of the 20th century, the boys in Brazil, just like in many other parts of the world, were big fans of football. There were football clubs everywhere, and the radio broadcasting helped spread this entertainment throughout Brazil. According to Wikipedia, someone had this idea to create a table football, where the field was any smooth flat surface, and the players were buttons positioned on a table. The buttons were the large ones, taken from clothes. Much for the despair of the poor mothers of that time, who had to sew new buttons, the table football became one of the most popular games among Brazilian children (specially when they were grounded and forbidden to play real football outdoors...)

Besides the use of clothing buttons, people tried other materials, such as pieces made of coconut shells and bones. The goalkeepers were just matchboxes filled in by sand or some heavy material. But finally, the industry started making buttons from plastic materials, which became the standard for commercial versions of the game.

Since most kids today prefer computer games, in this article, I tried to reproduce the feeling and atmosphere of those plastic buttons.

You can have a quick overview of the game by taking a look at the YouTube video I uploaded, in the link below:

## System Requirements

In order to get the game to work, you can download the following, if you don't have VS 2008 and Silverlight 3:

## Soccerlight Solution

Figure 1: Solution structure

The Visual Studio 2008 solution is made up mainly by the Soccerlight project, which contains the Silverlight logic itself, and other helper projects, as we can see in the following table.

 Project Description Silverlight This is the Silverlight project itself. Silverlight.Controls This Silverlight Class Library project that holds some of the custom controls I use in the project. Silverlight.Core This project holds some of the game logic and the model classes. Silverlight.Web This project is the start up project that contains the application's entry page.

The Intro menu consists of a table containing all of the 8 groups which played in the 2010 FIFA World Cup.

The idea is that you pick up a national team and start playing with that team. Then you will have to follow exactly the same games as they were scheduled in the 2010 World Cup.

For the implementation of this teams table, I didn't use much of XAML. I did it mostly programmatically. What you see in the image below is made up of `Grid`, `TextBlock`, and `Image` elements. I know I might have used a `ListBox` element with a custom template, but... I wanted more freedom than that. By constructing the visual elements programmatically, I feel that I can have much more control over animations, transforms, etc.

The following function `GenerateGroups` creates all the 32 teams divided into the 8 groups:

```void GenerateGroups()
{
for(int i = 0; i < 8; i++)
{
Border brd = new Border();
brd.Margin = new Thickness(2);
brd.SetValue(Grid.ColumnProperty, i % 4);
brd.SetValue(Grid.RowProperty, i / 4);

lgb.StartPoint = new Point(0, 0);
lgb.EndPoint = new Point(1, 1);
{ Offset = 0.0, Color = Color.FromArgb(255, 0, 0, 0)});
{ Offset = 0.5, Color = Color.FromArgb(255, 30, 30, 30)});
{ Offset = 1.0, Color = Color.FromArgb(255, 40, 40, 40)});
brd.Background = lgb;

lgbEven.StartPoint = new Point(0, 0);
lgbEven.EndPoint = new Point(1, 1);
{ Offset = 0.0, Color = Color.FromArgb(255, 0, 0, 0) });
{ Offset = 0.5, Color = Color.FromArgb(255, 30, 30, 30) });
{ Offset = 1.0, Color = Color.FromArgb(255, 80, 80, 80) });

Grid grdGroup = new Grid();
grdGroup.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(28) });
grdGroup.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
grdGroup.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
grdGroup.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(18) });
grdGroup.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(18) });
grdGroup.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(18) });
grdGroup.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(18) });

TextBlock txtGroupID = new TextBlock()
{
Text = ((char)(i + 65)).ToString(),
Foreground = new SolidColorBrush(Colors.White),
FontSize = 18,
FontWeight = FontWeights.Bold
};
txtGroupID.SetValue(Grid.ColumnProperty, 0);
txtGroupID.SetValue(Grid.RowProperty, 0);
txtGroupID.SetValue(Grid.RowSpanProperty, 4);
txtGroupID.SetValue(VerticalAlignmentProperty, VerticalAlignment.Center);
txtGroupID.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Center);

for (int j = 0; j < 4; j++)
{
Grid grdTeam = new Grid();
grdTeam.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
grdTeam.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
grdTeam.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(25) });
grdTeam.SetValue(Grid.ColumnProperty, 1);
grdTeam.SetValue(Grid.ColumnSpanProperty, 2);
grdTeam.SetValue(Grid.RowProperty, j);
grdTeam.HorizontalAlignment = HorizontalAlignment.Stretch;
grdTeam.VerticalAlignment = VerticalAlignment.Center;
grdTeam.Width = 120;

Team team =
GameHelper.Instance.TeamsDictionary[GameHelper.Instance.TeamCodes[i * 4 + j]];
Image img = new Image()
{
Source = new BitmapImage(new Uri(string.Format(
@"http://www.fifa.com/imgml/flags/reflected/m/{0}.png",
team.TeamID.ToLower()), UriKind.Absolute)),

Width = 28.5,
Height = 25.0,
VerticalAlignment = VerticalAlignment.Center
};
img.SetValue(Grid.ColumnProperty, 0);
img.SetValue(Grid.RowProperty, j);
img.VerticalAlignment = VerticalAlignment.Top;
img.HorizontalAlignment = HorizontalAlignment.Stretch;
img.Clip = new RectangleGeometry() { Rect =
new Rect(new Point(0, 0), new Point(28.5, 14)) };
img.Tag = team.TeamID;
TranslateTransform tf = new TranslateTransform()
{
X = 0,
Y = 6
};
img.RenderTransform = tf;

TextBlock txt = new TextBlock()
{
Text = team.TeamName,
Foreground = new SolidColorBrush(Colors.White)
};
txt.SetValue(Grid.ColumnProperty, 1);
txt.SetValue(Grid.RowProperty, j);
txt.VerticalAlignment = VerticalAlignment.Center;
txt.HorizontalAlignment = HorizontalAlignment.Stretch;
txt.Tag = team.TeamID;

grdTeam.Tag = team.TeamID;
grdTeam.MouseEnter += new MouseEventHandler(team_MouseEnter);
grdTeam.MouseLeave += new MouseEventHandler(team_MouseLeave);
grdTeam.MouseLeftButtonUp +=
new MouseButtonEventHandler(team_MouseLeftButtonUp);

}

brd.Child = grdGroup;

}
}```
Figure 3: The GenerateGroups() function in the IntroMenu.xaml.cs file

## Soccerlight Table

If you have chosen England as your team in the Intro menu, you would next be redirected to the following view, which is, of course, the first game of England in the World Cup (England vs. USA, 06/12, in Rustenburg).

Notice that both teams start with the traditional 3-5-2 formation, being 3 fullbacks, 5 midfielders, and 2 forwards. Although this is the default formation for all teams in the game, it wouldn't be so hard to select another formation for the selected teams, since the formation is simply an array of integers:

```public Team()
{
Formation = new int[] {1, 3, 5, 2};
}```
Figure 4: Team class constructor, showing how the 3-5-2 formation is set up for every team.

Notice that the array in the code snippet above starts with 1. This is so because we have to take the goalkeeper into consideration.

Figure 5: Soccerlight table, showing the 3-5-2 formations of England vs. USA

Notice in the listing below that the field lines and circles are not really images, but instead are made up of `Border` and `Ellipse` elements. Notice also that at the four corners, there are quarter-of-circles, which can easily be created by clipping the ordinary circles (see the `Ellipse.Clip` tags below) using `RectangleGeometry` to show only the quarter you want.

```<Grid x:Name="LayoutRoot"
MouseLeftButtonUp="LayoutRoot_MouseLeftButtonUp"
VerticalAlignment="Center" ...
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="colLeftEscapeArea" Width="53"/>
<ColumnDefinition x:Name="colLeftPosts" Width="53"/>
<ColumnDefinition x:Name="colLeftGoalArea" Width="70"/>
<ColumnDefinition x:Name="colLeftPenaltyArea" Width="280"/>
<ColumnDefinition x:Name="colHalfWay" Width="280"/>
<ColumnDefinition x:Name="colRightPenaltyArea" Width="70"/>
<ColumnDefinition x:Name="colRightGoalArea" Width="53"/>
<ColumnDefinition x:Name="colRightPosts" Width="53"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="rowTopEscapeArea" Height="50"/>
<RowDefinition x:Name="rowTopFieldLine" Height="108"/>
<RowDefinition x:Name="rowTopPenaltyArea" Height="67"/>
<RowDefinition x:Name="rowTopGoalArea" Height="153"/>
<RowDefinition x:Name="rowBottomGoalArea" Height="67"/>
<RowDefinition x:Name="rowBottomPenaltyArea" Height="108"/>
<RowDefinition x:Name="rowBottomFieldLine" Height="50"/>
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="0"
Grid.ColumnSpan="8" Grid.RowSpan="1"
Background="DarkGreen" ...
<Border Grid.Column="0" Grid.Row="1"
Grid.ColumnSpan="1" Grid.RowSpan="5" Background="DarkGreen" ...
<Border Grid.Column="1" Grid.Row="1"
Grid.ColumnSpan="3" Grid.RowSpan="5" BorderBrush="White" ...
<Border Grid.Column="4" Grid.Row="1"
Grid.ColumnSpan="3" Grid.RowSpan="5" BorderBrush="White" ...
<Border Grid.Column="1" Grid.Row="3"
Grid.ColumnSpan="1" Grid.RowSpan="1" BorderBrush="White" ...
<Border Grid.Column="6" Grid.Row="3"
Grid.ColumnSpan="1" Grid.RowSpan="1" BorderBrush="White" ...
<Border Grid.Column="1" Grid.Row="2"
Grid.ColumnSpan="2" Grid.RowSpan="3" BorderBrush="White" ...
<Border Grid.Column="1" Grid.Row="2"
Grid.ColumnSpan="2" Grid.RowSpan="3" BorderBrush="White" ...
<Border Grid.Column="5" Grid.Row="2"
Grid.ColumnSpan="2" Grid.RowSpan="3" BorderBrush="White" ...
<Border Grid.Column="7" Grid.Row="1"
Grid.ColumnSpan="1" Grid.RowSpan="5" Background="DarkGreen" ...
<Border Grid.Column="0" Grid.Row="6"
Grid.ColumnSpan="8" Grid.RowSpan="1" Background="DarkGreen" ...
<StackPanel Grid.Column="1" Grid.Row="1"
Grid.ColumnSpan="6" Grid.RowSpan="5" Margin="8, 8, 0, 0" ...
<Image Source="../Images/Soccerlight.png" Stretch="UniformToFill">
<Image.RenderTransform>
<ScaleTransform ScaleX="0.25" ScaleY="0.25"/>
</Image.RenderTransform>
</Image>
</StackPanel>
<Grid Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="6" Grid.RowSpan="5" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="92"/>
<ColumnDefinition Width="115"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="15"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="115"/>
<ColumnDefinition Width="92"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
<RowDefinition Height="15"/>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Ellipse Grid.Column="0" Grid.Row="0" StrokeThickness="2" Stroke="White">
<Ellipse.Clip>
<RectangleGeometry Rect="15,15,30,30"/>
</Ellipse.Clip>
<Ellipse.RenderTransform>
<TranslateTransform X="-15" Y="-15"/>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Grid.Column="10" Grid.Row="0" StrokeThickness="2" Stroke="White">
<Ellipse.Clip>
<RectangleGeometry Rect="0,15,15,15"/>
</Ellipse.Clip>
<Ellipse.RenderTransform>
<TranslateTransform X="15" Y="-15"/>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Grid.Column="0" Grid.Row="6" StrokeThickness="2" Stroke="White">
<Ellipse.Clip>
<RectangleGeometry Rect="15,0,15,15"/>
</Ellipse.Clip>
<Ellipse.RenderTransform>
<TranslateTransform X="-15" Y="15"/>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Grid.Column="10" Grid.Row="6" StrokeThickness="2" Stroke="White">
<Ellipse.Clip>
<RectangleGeometry Rect="0,0,15,15"/>
</Ellipse.Clip>
<Ellipse.RenderTransform>
<TranslateTransform X="15" Y="15"/>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Grid.Column="4" Grid.Row="2" Grid.ColumnSpan="3" Grid.RowSpan="3"
StrokeThickness="2" Stroke="White"/>
<Ellipse Grid.Column="5" Grid.Row="3" Fill="White"/>
<Ellipse Grid.Column="2" Grid.Row="2" Grid.ColumnSpan="1" Grid.RowSpan="3"
StrokeThickness="2" Stroke="White">
<Ellipse.Clip>
<RectangleGeometry Rect="57.5,0,115,115"/>
</Ellipse.Clip>
<Ellipse.RenderTransform>
<TranslateTransform X="-57.5" Y="0"/>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse Grid.Column="8" Grid.Row="2" Grid.ColumnSpan="1"
Grid.RowSpan="3" StrokeThickness="2" Stroke="White">
<Ellipse.Clip>
<RectangleGeometry Rect="0,0,57.5,115"/>
</Ellipse.Clip>
<Ellipse.RenderTransform>
<TranslateTransform X="57.5" Y="0"/>
</Ellipse.RenderTransform>
</Ellipse>
</Grid>
<Canvas x:Name="rootCanvas"/>
<Border Grid.Column="0" Grid.Row="3"
Grid.ColumnSpan="1" Grid.RowSpan="1" BorderBrush="White" ...
<Grid>
<Grid.Background>
<ImageBrush ImageSource="../Images/goalnet.png" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
</Border>
<Border Grid.Column="7" Grid.Row="3"
Grid.ColumnSpan="1" Grid.RowSpan="1" BorderBrush="White" ...
<Grid>
<Grid.Background>
<ImageBrush ImageSource="../Images/goalnet.png" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
</Border>
<Border x:Name="brdBallStrengthContainer"
Grid.Column="8" Grid.Row="4" Grid.ColumnSpan="1" ...
<Grid>
<Border.Background>
</Border.Background>
</Border>
<Image x:Name="imgBallStrength" Source="../Images/Jabulani.png"
VerticalAlignment="Top" Margin="0,32,0,0">
<Image.RenderTransform>
<RotateTransform x:Name="rtBallStrength"
CenterX="11.5" CenterY="11.5" Angle="30">
</RotateTransform>
</Image.RenderTransform>
</Image>
</Grid>
</Border>
MaxHeight="180" Grid.Column="1" Grid.Row="0"...
<Grid.Clip>
<RectangleGeometry Rect="0,0,800,180"/>
</Grid.Clip>
<TextBlock Foreground="White" FontSize="120"
Text="GOALLLLLL!!!" TextAlignment="Center" Margin="0">
<TextBlock.RenderTransform>
<TranslateTransform x:Name="lettersXTranslate" X="0"/>
</TextBlock.RenderTransform>
</TextBlock>
<Grid x:Name="grdBrightness" Background="Black" Opacity="1.00"/>
</Grid>
<Grid.RenderTransform>
<ScaleTransform ScaleX="0.868" ScaleY="0.8700"/>
</Grid.RenderTransform>
</Grid>```

## Score Control

The score control shows the elapsed time, the team nicknames, a blinking ball indicating the playing team, and... the scores.

The elapsed time is controlled by a `DispatcherTimer` object, which triggers a `Tick` event every second. This is propagated to the score control to increase the total elapsed time.

In real soccer games, there are two halves of 45 minutes each, separated by a 15-minute break. In Soccerlight, however, the game is over when the timer reaches 30 minutes.

The blinking ball is a useful indicator to show which team is playing at a given moment.

Figure 6: The score control

## The Goals

Each goal is delimited by three borders: two at both sides, and one at the back of the goal. If the ball strikes these borders, it will bounce as if it was hitting a wall. Besides, at both sides in front of the goal, there are goalposts, which behave like real cylindrical goalposts, making the ball bounce as if it was hitting a circular object.

Besides, the goal has a transparent goal net, which gives the game a cool and realistic look and feel.

The rule is simple as that: whenever the ball enters the goal, the application updates the score control to increment the score of the attacking team.

Figure 7: The goal: notice the borders, the goal posts, and the detailed goal net

## Jabulani

Figure 8: The Jabulani ball

As some of the readers may know, Jabulani is the innovative official ball in the FIFA World Cup, so I decided to use it too in Soccerlight World Cup.

Some players have complained about Jabulani in FIFA Cup, because they have reported "strange" behavior and unpredicted direction changing, while other players have declared their love for the ball. (On the other side, no Soccerlight player has complained about the ball yet...)

In Soccerlight, the physics calculations involving the ball are no different from those involving the players (except for the the fact that players have greater diameters and greater friction coefficients). In fact, both ball and players inherit from the same base class, `Discoid`:

```public class Ball : Discoid
{
public class Player : Discoid
{```

## Players

Each team has a set of 11 players. In the real world, each player may have different roles, but in Soccerlight, they are treated in the same manner. The only difference between a striker and a goalkeeper, for example, is the fact that the goalkeeper is closer to the goal and the striker's initial position is closer to the opponent's goal. Maybe in future versions I will define different skills, such as, for example, a skilled striker might have more precision when shooting to goal than other average players.

Figure 9: Players caught in action: say "cheese"...

## Player Info Bar

Whenever you select a player, the application will show a Player Info Bar. This bar contains basic info about the player: the number, the name, and the picture.

Each Soccerlight player has a number, a name, and a picture. Numbers and names are hard-coded in the application, but the pictures are taken from the FIFA website, as shown in the code snippet below:

```imgPlayer.ImageSource = new BitmapImage(new Uri(string.Format(
"http://pt.fifa.com/imgml/tournament/worldcup2010/players/xl/{0}.png",
teamPlayer.ID), UriKind.Absolute));```

The listing below is responsible for showing the Player Info Bar:

```<Grid x:Name="grdPlayerInfo" HorizontalAlignment="Center"
VerticalAlignment="Bottom" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="8"/>
<ColumnDefinition Width="400"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
Width="75" Height="100"
Background="#C0000000">
<Border.RenderTransform>
<TransformGroup>
<TranslateTransform X="4" Y="4"/>
</TransformGroup>
</Border.RenderTransform>
</Border>
Width="75" Height="100">
<Border.Background>
</Border.Background>
<Border.RenderTransform>
<TransformGroup>
<TranslateTransform X="4" Y="4"/>
</TransformGroup>
</Border.RenderTransform>
</Border>
Width="75" Height="100">
<Border.Background>
<ImageBrush x:Name="imgPlayer"/>
</Border.Background>
</Border>
<StackPanel Grid.Column="2" VerticalAlignment="Center" Margin="0,0,0,64">
<Border.Background>
</Border.Background>
<Border.RenderTransform>
<SkewTransform AngleX="-10"/>
</Border.RenderTransform>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="numPlayer" Text="" Foreground="Black"
FontSize="22" FontWeight="Bold" Margin="32,0,0,0"/>
<TextBlock Text=" - " Foreground="Black" FontSize="22"
FontWeight="Bold"/>
<TextBlock x:Name="txtPlayerName" Text="" Foreground="Black"
FontSize="22" FontWeight="Bold" Margin="0,0,0,0"/>
</StackPanel>
</Border>
</StackPanel>
</Grid>```

Figure 10: Player Info Bar

## Strength Control Bar

The Strength Control Bar is the means that you have to calibrate your shot strength. The higher you put the Jabulani ball in the bar, the stronger you shoot the ball.

Figure 11: Strength Control Bar

The strength is redefined whenever the user clicks in the Strength Control Bar. This is done by the following code:

```private void LayoutRoot_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Point point = e.GetPosition(rootCanvas);

if ((point.X > strengthPointNW.X) &&
(point.X < strengthPointSE.X) &&
(point.Y > strengthPointNW.Y) &&
(point.Y < strengthPointSE.Y))
{
e.Handled = true;
double relativeY = strengthPointSE.Y - point.Y;
currentGame.Team1BallStrength = ((strengthPointSE.Y - point.Y) /
(strengthPointSE.Y - strengthPointNW.Y)) * 100.0;

imgBallStrength.Margin = new Thickness(0, point.Y -
strengthPointNW.Y - imgBallStrength.ActualHeight / 2.0, 0, 0);
brdStrength.Margin = new Thickness(8, point.Y -
strengthPointNW.Y + imgBallStrength.ActualHeight / 2.0, 8, 8);
}```

The role of the Stadium Screen is just to show that a team has scored the goal. Simple as that.

The Stadium Screen has three different animations. First, there is the `translateAnimation`, which translates the "GOOAL" string from right to left. Then there is the `lettersOpacityAnimation` that fades in and fades out the letters of the screen. And finally, there is the `screenOpacityAnimation`, responsible for fading out the whole Stadium Screen element:

```sbStadiumScreen = new Storyboard()
{
Duration = new Duration(new TimeSpan(0, 0, 0, 10))
};

DoubleAnimation translateAnimation = new DoubleAnimation()
{
From = 800,
To = 0,
Duration = new Duration(new TimeSpan(0, 0, 0, 3))
};

Storyboard.SetTarget(translateAnimation, lettersXTranslate);
Storyboard.SetTargetProperty(translateAnimation, new PropertyPath("X"));

DoubleAnimation lettersOpacityAnimation = new DoubleAnimation()
{
From = 0.8,
To = 1.0,
Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500)),
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever
};

Storyboard.SetTarget(lettersOpacityAnimation, grdBrightness);
Storyboard.SetTargetProperty(lettersOpacityAnimation, new PropertyPath("Opacity"));

DoubleAnimation screenOpacityAnimation = new DoubleAnimation()
{
From = 1.0,
To = 0.0,
BeginTime = new TimeSpan(0, 0, 0, 0),
Duration = new Duration(new TimeSpan(0, 0, 0, 4))
};

Storyboard.SetTargetProperty(screenOpacityAnimation, new PropertyPath("Opacity"));```

## Wish List and Known Issues

Some issues with the game, and some desirable improvements which I'm willing to be correcting/implementing in future releases:

• The game still doesn't handle fouls. At first, this seems easy to implement, but depending on where the foul occurred, after the foul, you might have to rearrange the players so that they don't collide with each other, etc.
• There are still no games for the knockout stage. Maybe I'll generate random results for the other matches, and if your team keeps winning, you'll advance from the round of 16 to the quarter-of-finals, semi-finals, and finally to the final match.
• It would be very cool to implement an online, service-based, human-to-human version of the game. A WCF Service will do, I think.

## Final Considerations

If you reached this line, I'd like to thank you for your patience. Please tell me what you liked or disliked in the application. Criticism and suggestions are welcome, and I'm willing to improve this article and application based on your feedback.

## History

• 2010-06-29: First version.

Software Developer
Brazil
Marcelo Ricardo de Oliveira is a senior software developer who lives with his lovely wife Luciana and his little buddy and stepson Kauê in Guarulhos, Brazil, is co-founder of the Brazilian TV Guide TV Map and currently works for ILang Educação.

He is often working with serious, enterprise projects, although in spare time he's trying to write fun Code Project articles involving WPF, Silverlight, XNA, HTML5 canvas, Windows Phone app development, game development and music.

Published Windows Phone apps:

Awards:

CodeProject MVP 2012
CodeProject MVP 2011

Best Web Dev article of March 2013
Best Web Dev article of August 2012
Best Web Dev article of May 2012
Best Mobile article of January 2012
Best Mobile article of December 2011
Best Mobile article of October 2011
Best Web Dev article of September 2011
Best Web Dev article of August 2011
HTML5 / CSS3 Competition - Second Prize
Best ASP.NET article of June 2011
Best ASP.NET article of May 2011
Best ASP.NET article of April 2011
Best C# article of November 2010
Best overall article of November 2010
Best C# article of October 2010
Best C# article of September 2010
Best overall article of September 2010
Best overall article of February 2010
Best C# article of November 2009

 First PrevNext
 html5 version kiquenet.com 4-Sep-13 9:55
 Re: html5 version Marcelo Ricardo de Oliveira 4-Sep-13 11:29
 Re: html5 version kiquenet.com 7-Sep-13 3:20
 My vote of 5 prelate 25-May-13 11:46
 Re: My vote of 5 Marcelo Ricardo de Oliveira 27-May-13 13:28
 My vote of 5 soulprovidergr 18-Sep-12 23:24
 My vote of 5 Pravin Patil, Mumbai 15-Jul-12 22:40
 My vote of 5 kiquenet.com 5-Jun-12 11:40
 turtle baazka 9-Mar-12 18:15
 My vote of 5 gif2020 13-Sep-11 23:32
 My vote of 5 RaviRanjankr 1-Jan-11 1:08
 Re: My vote of 5 Marcelo Ricardo de Oliveira 1-Jan-11 6:19
 Great Job Bassam Abdul-Baki 22-Nov-10 2:54
 Re: Great Job Marcelo Ricardo de Oliveira 3-Dec-10 7:52
 Thanks & bugs & advice hollysong 29-Sep-10 0:38
 Re: Thanks & bugs & advice Marcelo Ricardo de Oliveira 30-Sep-10 0:59
 Little bug _ZIgi 14-Sep-10 5:48
 App is great, but where is a problem to launch cause Convert.ToDateTime("06/22/2010") gaves an exception, if in current culture (for example it's mine "Ru-ru") month digit placed before day digit(so date above becomes 6'th day of 22'nd month)
 Re: Little bug Marcelo Ricardo de Oliveira 26-Sep-10 12:35
 My vote of 5 thatraja 2-Sep-10 4:01
 Re: My vote of 5 Marcelo Ricardo de Oliveira 27-Sep-10 4:24
 My vote of 5 César de Souza 20-Aug-10 7:46
 Re: My vote of 5 Marcelo Ricardo de Oliveira 26-Aug-10 4:05
 My vote of 5 Abhinav S 17-Jul-10 7:15
 Re: My vote of 5 Marcelo Ricardo de Oliveira 17-Jul-10 11:55
 My vote of 5 Petr Pechovic 13-Jul-10 21:02
 Re: My vote of 5 Marcelo Ricardo de Oliveira 14-Jul-10 3:19
 Re: My vote of 5 Petr Pechovic 14-Jul-10 4:32
 Re: My vote of 5 Marcelo Ricardo de Oliveira 14-Jul-10 7:06
 My vote of 5 linuxjr 12-Jul-10 11:59
 Re: My vote of 5 Marcelo Ricardo de Oliveira 12-Jul-10 13:38
 Muito bom, parabéns!! RICARDO MARCONE 12-Jul-10 4:19
 Re: Muito bom, parabéns!! Marcelo Ricardo de Oliveira 12-Jul-10 7:36
 My vote of 5 defwebserver 12-Jul-10 4:14
 Re: My vote of 5 Marcelo Ricardo de Oliveira 12-Jul-10 7:34
 My vote of 5 jujusharp 12-Jul-10 3:45
 Re: My vote of 5 Marcelo Ricardo de Oliveira 12-Jul-10 7:31
 My vote of 5 Raul Mainardi Neto 12-Jul-10 2:53
 Re: My vote of 5 Marcelo Ricardo de Oliveira 12-Jul-10 3:12
 Re: My vote of 5 Raul Mainardi Neto 12-Jul-10 3:52
 Well done Jordy "Kaiwa" Ruiter 8-Jul-10 22:54
 Re: Well done Marcelo Ricardo de Oliveira 9-Jul-10 8:02
 Nice one Sacha Barber 8-Jul-10 22:52
 Re: Nice one Marcelo Ricardo de Oliveira 9-Jul-10 7:59
 Wicked stuff Alan Beasley 8-Jul-10 22:06
 Re: Wicked stuff Marcelo Ricardo de Oliveira 9-Jul-10 7:58
 My vote of 5 IronXAres 7-Jul-10 3:53
 Re: My vote of 5 Marcelo Ricardo de Oliveira 7-Jul-10 4:47
 Meus parabens !! Excelente !!! RicardoPDV 5-Jul-10 12:17
 Re: Meus parabens !! Excelente !!! Marcelo Ricardo de Oliveira 5-Jul-10 15:27
 Nice Nematjon Rahmanov 2-Jul-10 3:38
 Last Visit: 31-Dec-99 18:00     Last Update: 16-Apr-14 23:20 Refresh 12 Next »