programming4us
programming4us
MULTIMEDIA

Animations in Silverlight

7/25/2010 5:08:41 PM
I_section3_d1e4826.html
Animations are usually just a cheap visual effect that is based on an element's properties being changed. So, for instance, if an element moves from the top-left to the bottom-right corner of the canvas, its Canvas.Left and Canvas.Top properties are changed a few times per second. If an element fades in from out of nowhere, its Opacity value is animated, from 100% to 0%. So, theoretically, you could rely solely on C# and its access to Silverlight elements' properties to create animations. Of course, it is much more convenient to use the built-in animation support. Setting up an animation requires quite a number of steps, but the result can be very rewarding.

1. Setting Up an Animation

Creating an animation requires several steps and a couple of lines of markup, so IntelliSense is really handy here. For example, to smoothly move an element to another position you need to animate the element. For reasons that will become clear in a minute, you should name that element:

<TextBlock FontFamily="Arial" FontSize="56" Canvas.Left="25" Canvas.Top="40"
Foreground="Black" Text="Silverlight" x:Name="MyTextBlock">
...
</TextBlock>

Within this element, define a trigger using a <TextBlock.Triggers> element (if you were to animate a rectangle, you would use <Rectangle.Triggers>, etc.). An actual trigger (represented by <EventTrigger>) is activated when an event is fired. This event is provided in the RoutedEvent attribute of <EventTrigger>. Currently, Silverlight supports only one event, Element.Loaded, where Element is the name of the object that contains the trigger (here it is TextBlock):
<TextBlock FontFamily="Arial" FontSize="56" Canvas.Left="25" Canvas.Top="40" 
Foreground="Black" Text="Silverlight" x:Name="MyTextBlock">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
...
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

Within the event trigger, a storyboard is created. <BeginStoryboard> and <Storyboard> are the two necessary elements. A storyboard is a set of one or more animations. You can try to compare what a storyboard does for animations to what the <TransformGroup> element does to transformations, which is to group several of them together. An animation can consist of several individual animations, but more on that in a minute.
<TextBlock FontFamily="Arial" FontSize="56" Canvas.Left="25" Canvas.Top="40" 
Foreground="Black" Text="Silverlight" x:Name="MyTextBlock">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard>
<Storyboard>
...
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

Silverlight supports several animations, and we will cover all of them in the next section. To complete the current example, let's introduce the most common animation: . This animation "animates" a value from a start value to an end value—for instance, from 1 to 10. Every animation runs a certain amount of time. Within that interval, the associated animation value is gradually changed, from the start value to the end value. When the value goes from 1 to 10, these values might be 1, 1.1, 1.2, and so on until 10, depending on the duration of the animation. If the value that is animated is the x coordinate of the element to be animated, this creates the visual effect of the element smoothly moving from one point to another.

When using an animation, you will usually need several of these properties:

AutoReverse

Reverses the animation if it has ended (i.e., moves the element back to where it started)

Duration

The duration of an animation, using the syntax hh:mm:ss (hours, minutes, seconds)

From

The start value for the animation

To

The end value for the animation

By

A relative value indicating by how much to change the animation (an alternative approach for using To)

RepeatBehavior

What to do if the animation has ended; you can provide a (total) duration, a number of times to repeat, or mark it Forever if the animation should repeat endlessly

Storyboard.TargetName

The name of the element that needs to be animated (therefore, we needed to assign a name)

Storyboard.TargetProperty

The property of the element that needs to be animated

NOTE

The value of Storyboard.TargetProperty is the name of the property that receives the animated values. If the property includes a dot (such as in Canvas.Left and Canvas.Top), you need to enclose the complete property name in parentheses—for example, (Canvas.Left) and (Canvas.Top).

Adding a concludes the code, which is shown in Example 1. Both the rectangle and the text are moved 300 pixels to the right, using the default animation duration (here it is one second). Visual Studio 2008 may complain that it does not know and , but it works nevertheless, as Figure 1 shows.

Example 1. Using , the XAML file (Page.xaml, project DoubleAnimation)

<UserControl x:Class="DoubleAnimation.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="600" Height="400">
<Grid x:Name="LayoutRoot" Background="White">
<Canvas>

<Rectangle Width="300" Height="150" Stroke="Orange" StrokeThickness="15"
x:Name="MyRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
From="0" To="300.456"
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="(Canvas.Left)" />

</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
<TextBlock FontFamily="Arial" FontSize="56" Canvas.Left="25" Canvas.Top="40"
Foreground="Black" Text="Silverlight" x:Name="MyTextBlock">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
From="25" To="325.456"
Storyboard.TargetName="MyTextBlock"
Storyboard.TargetProperty="(Canvas.Left)" />

</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

</Canvas>
</Grid>
</UserControl>

Figure 1. The elements are animated to the right (although you can't see this in print)


If you set up an animation that way, it will start immediately after the trigger has been activated. Silverlight allows you to change this behavior. Every animation also supports the BeginTime attribute, where you define the time (again using the hh:mm:ss syntax) when the animation starts. The code from Example 2 combines two elements: the first one moves the element to the right, and the second one moves it to the bottom. The second animation starts after three seconds, which happens to be the exact time when the first animation has ended. Figure 2 shows the second phase of the storyboard: the element is moving down.

Example 2. Combining animations and starting them later, the XAML file (Page.xaml, project DoubleAnimations)

<UserControl x:Class="DoubleAnimations.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="600" Height="400">
<Grid x:Name="LayoutRoot" Background="White">
<Canvas>

<Rectangle Width="300" Height="150" Stroke="Orange" StrokeThickness="15"
x:Name="MyRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
From="0" To="300.456" Duration="0:0:3"
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="(Canvas.Left)" />
<DoubleAnimation
From="0" To="150" BeginTime="0:0:3" Duration="0:0:3"
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="(Canvas.Top)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
<TextBlock FontFamily="Arial" FontSize="56" Canvas.Left="25" Canvas.Top="40"
Foreground="Black" Text="Silverlight" x:Name="MyTextBlock">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
From="25" To="325.456" Duration="0:0:3"
Storyboard.TargetName="MyTextBlock"
Storyboard.TargetProperty="(Canvas.Left)" />
<DoubleAnimation
From="40" To="190" BeginTime="0:0:3" Duration="0:0:3"
Storyboard.TargetName="MyTextBlock"
Storyboard.TargetProperty="(Canvas.Top)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

</Canvas>
</Grid>
</UserControl>

Figure 2. The elements first move to the right, then to the bottom


NOTE

If you omit the BeginTime attribute in Example 2, both animations run at the same time, making the elements move diagonally.

2. Animation Types

Apart from , Silverlight also comes with support for two additional animations with a more specific purpose:

  • ColorAnimation (animates a color value—e.g., Orange)

  • PointAnimation (animates a point—e.g., 0,0)

Animating a color works wherever you have a Color property. That means you cannot animate, say, the Stroke property. However, you can use a SolidColorBrush and animate the Color property there.

The rest is easy. Use the element, set a From and a To color, and Silverlight takes care of the rest, as Example 3 shows (see Figure 3 for the browser output).

Example 3. Animating a color, the XAML file (Page.xaml, project ColorAnimation)

<UserControl x:Class="ColorAnimation.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="600" Height="400">
<Grid x:Name="LayoutRoot" Background="White">
<Canvas>
<Rectangle Width="300" Height="150" StrokeThickness="15" x:Name="MyRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
From="Green" To="Orange" Duration="0:0:5"
Storyboard.TargetName="MyBrush"
Storyboard.TargetProperty="Color" />

</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
<Rectangle.Stroke>
<SolidColorBrush x:Name="MyBrush" />
</Rectangle.Stroke>
</Rectangle>
<TextBlock FontFamily="Arial" FontSize="56" Canvas.Left="25" Canvas.Top="40"
Foreground="Black" Text="Silverlight" />
</Canvas>
</Grid>
</UserControl>

Figure 3. The stroke of the rectangle changes from green to orange


NOTE

A point animation (<PointAnimation> in Silverlight's XAML) animates a point from a start point to an end point (or by a certain distance in the coordinate system using By). To use it, you need to animate a property that requires a point as a value. One example for that is the <LinearGradientBrush>: its StartPoint and EndPoint attributes are both points. So, let's assume we have such a brush:

<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" x:Name="MyGradient">
<GradientStop Color="Red" Offset="0.0" />
<GradientStop Color="Green" Offset="0.5" />
<GradientStop Color="Blue" Offset="1.0" />
</LinearGradientBrush>

To animate this brush's StartPoint property, a <PointAnimation> element such as the following would do:

<PointAnimation
From="0,0" To="1,0" Duration="0:0:4"
Storyboard.TargetName="MyGradient"
Storyboard.TargetProperty="StartPoint" />

The code in Example 4 combines two animations: the start point of the gradient is moved from the top-left to the top-right corner and the end point of the gradient is moved from the bottom-left to the bottom-right corner. Figure 4 shows the Silverlight application in the browser during this animation: the gradient is moving.

Example 4. Animating a point, the XAML file (Page.xaml, project PointAnimation)

<UserControl x:Class="PointAnimation.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="600" Height="400">
<Grid x:Name="LayoutRoot" Background="White">
<Canvas>

<Rectangle Width="300" Height="150" StrokeThickness="15" x:Name="MyRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<PointAnimation
From="0,0" To="1,0" Duration="0:0:4"
Storyboard.TargetName="MyGradient"
Storyboard.TargetProperty="StartPoint" />
<PointAnimation
From="1,1" To="0,1" Duration="0:0:4"
Storyboard.TargetName="MyGradient"
Storyboard.TargetProperty="EndPoint" />

</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
<Rectangle.Stroke>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" x:Name="MyGradient">
<GradientStop Color="Red" Offset="0.0" />
<GradientStop Color="Green" Offset="0.5" />
<GradientStop Color="Blue" Offset="1.0" />
</LinearGradientBrush>
</Rectangle.Stroke>
</Rectangle>
<TextBlock FontFamily="Arial" FontSize="56" Canvas.Left="25" Canvas.Top="40"
Foreground="Black" Text="Silverlight" />

</Canvas>
</Grid>
</UserControl>

Figure 4. The gradient in the rectangle's stroke is changing


3. Keyframe Animations

All of the animations so far were quite flexible in terms of the beginning and end times, but there was one severe restriction: every animation only took care of exactly one value that was animated. A bit more complex, but also a bit more flexible, are so-called keyframe animations. The term keyframe is used heavily in Adobe Flash and identifies a frame during the course of a Flash movie where a certain state in the application must be reached (e.g., objects need to have specific positions). Silverlight uses keyframes only as part of special animations, but the approach is comparable: when a keyframe is reached, a certain object value must be met.

All three animation types we know so far (>, , and ) can also be used with keyframes. Then the names of the elements change (to , , and ). Within each element, you provide the number of keyframes. Every keyframe needs at least two values, or attributes:

KeyTime

The time when the keyframe will come into effect

Value

The value that needs to be reached at the given time

When you have one keyframe after two seconds (providing a value of 10), and another one after four seconds (providing a value of 20), the value that you assign in these two frames will be animated between them. How this value is animated from 10 to 20 will be defined by the second keyframe. There are different ways to interpolate the value, and the second keyframe needs to confirm which of these methods is used. Silverlight currently supports three methods:


Linear

The value is linearly interpolated.


Discrete

There are no values between the start and end values; when the next keyframe is reached, the new value will be assigned.


Spline

The values will be animated along a cubic Bézier curve (the two control points are then provided in the KeySpline attribute.

Every keyframe can come in different flavors: different type of value that is animated (Double, Color, Point) and a different type of interpolation method (Linear, Discrete, Spline). The name of the keyframe element in XAML is the concatenation of interpolation type, value type, and KeyFrame. Therefore, a keyframe that uses a spline interpolation of colors would be represented by the element.

Apart from that, keyframe animations just work as animations without keyframes. So, without further ado, have a look at Example 5 where the rectangle and the text block are moved around the canvas. The animations for the x and the y coordinate consist of four subanimations each. We are using a splined animation each time. Figure 5 shows the application in the animations.

Example 7-11. Animating using keyframes, the XAML file (Page.xaml, project KeyFrameAnimation)

<UserControl x:Class="KeyFrameAnimation.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="600" Height="400">
<Grid x:Name="LayoutRoot" Background="White">
<Canvas>

<Rectangle Width="300" Height="150" Stroke="Orange" StrokeThickness="15"
x:Name="MyRectangle">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="(Canvas.Left)"
Duration="0:0:8">
<SplineDoubleKeyFrame Value="300" KeyTime="0:0:2"
KeySpline="0.25,0.75 0.75,0.25" />
<SplineDoubleKeyFrame Value="100" KeyTime="0:0:4"
KeySpline="0.75,0.25 0.25,0.75" />
<SplineDoubleKeyFrame Value="50" KeyTime="0:0:6"
KeySpline="0.25,0.75 0.75,0.25" />
<SplineDoubleKeyFrame Value="200" KeyTime="0:0:8"
KeySpline="0.75,0.25 0.25,0.75" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="(Canvas.Top)"
Duration="0:0:8">
<SplineDoubleKeyFrame Value="50" KeyTime="0:0:2"
KeySpline="0.25,0.75 0.75,0.25" />
<SplineDoubleKeyFrame Value="250" KeyTime="0:0:4"
KeySpline="0.75,0.25 0.25,0.75" />
<SplineDoubleKeyFrame Value="50" KeyTime="0:0:6"
KeySpline="0.25,0.75 0.75,0.25" />
<SplineDoubleKeyFrame Value="100" KeyTime="0:0:8"
KeySpline="0.75,0.25 0.25,0.75" />
</DoubleAnimationUsingKeyFrames>

</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
<Canvas Canvas.Left="25" Canvas.Top="40">
<TextBlock FontFamily="Arial" FontSize="56" Foreground="Black"
Text="Silverlight" x:Name="MyTextBlock">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="MyTextBlock"
Storyboard.TargetProperty="(Canvas.Left)"
Duration="0:0:8">
<SplineDoubleKeyFrame Value="300" KeyTime="0:0:2"
KeySpline="0.25,0.75 0.75,0.25" />
<SplineDoubleKeyFrame Value="100" KeyTime="0:0:4"
KeySpline="0.75,0.25 0.25,0.75" />
<SplineDoubleKeyFrame Value="50" KeyTime="0:0:6"
KeySpline="0.25,0.75 0.75,0.25" />
<SplineDoubleKeyFrame Value="200" KeyTime="0:0:8"
KeySpline="0.75,0.25 0.25,0.75" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="MyTextBlock"
Storyboard.TargetProperty="(Canvas.Top)"
Duration="0:0:8">
<SplineDoubleKeyFrame Value="50" KeyTime="0:0:2"
KeySpline="0.25,0.75 0.75,0.25" />
<SplineDoubleKeyFrame Value="250" KeyTime="0:0:4"
KeySpline="0.75,0.25 0.25,0.75" />
<SplineDoubleKeyFrame Value="50" KeyTime="0:0:6"
KeySpline="0.25,0.75 0.75,0.25" />
<SplineDoubleKeyFrame Value="100" KeyTime="0:0:8"
KeySpline="0.75,0.25 0.25,0.75" />
</DoubleAnimationUsingKeyFrames>

</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</Canvas>

</Canvas>
</Grid>
</UserControl>

Figure 5. The elements move around the canvas, along Bézier curves


4. Coding Animation

The final example in this chapter will show you how animations are exposed in C# code. This allows you to control animations from script code and will also provide a means to overcome the limitation of animations always starting when the XAML files were loaded. The example will start the animation when the mouse hovers over the elements on the canvas, pause it when the mouse leaves the canvas, and resume it again when the mouse pointer is back.

Since we need C# code in the example, we will use a XAML code-behind C# file. The Visual Studio project template has already created the file Page.xaml.cs for us. We have looked at these .xaml.cs files before , but just to make sure, have a look at Example 6, where you'll see the file as it comes with the template.

Example 6. Scripting animations, the original C# file (Page.xaml.cs, project AnimationResources)

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace AnimationResources
{
public partial class Page : UserControl
{
public Page()
{
// Required to initialize variables
InitializeComponent();
}
}
}




  
    
  
  
    
   

As you can see, the two animations change the x coordinate of a rectangle (MyRectangle) and a text block (MyTextBlock).

You can take the process of separating a storyboard from the animated element using <Canvas.Resources> one step further by omitting the Storyboard.TargetName property and setting it dynamically from C#. However, you can do that only if the animation has not yet started

Example 7 shows the complete XAML markup. Note that there are two mouse event handlers in the <Canvas> element, but no triggers on the page.
Example 7. Scripting animations, the XAML file (Page.xaml, project AnimationResources)

<UserControl x:Class="AnimationResources.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="600" Height="400">
<Grid x:Name="LayoutRoot" Background="White">
<Canvas MouseEnter="beginAnimation" MouseLeave="pauseAnimation">
<Canvas.Resources>
<Storyboard x:Name="MyRectangleStoryboard">
<DoubleAnimation
From="0" To="300.456"
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="(Canvas.Left)"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
<Storyboard x:Name="MyTextBlockStoryboard">
<DoubleAnimation
From="0" To="300.456"
Storyboard.TargetName="MyTextBlock"
Storyboard.TargetProperty="(Canvas.Left)"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</Canvas.Resources>
<Rectangle Width="300" Height="150" Stroke="Orange" StrokeThickness="15"
x:Name="MyRectangle"/>
<Canvas Canvas.Left="25" Canvas.Top="40">
<TextBlock FontFamily="Arial" FontSize="56" Foreground="Black"
Text="Silverlight" x:Name="MyTextBlock"/>
</Canvas>
</Canvas>
</Grid>
</UserControl>

Accessing such a storyboard is easy. Just use the well-known FindName() method and provide the name of the <Storyboard> element, or alternatively access the storyboards by their names. You can then control the animations using these five methods:

Begin()

Starts an animation at the beginning

Pause()

Pauses an animation

Resume()

Resumes a paused animation

Stop()

Stops an animation

Seek(offset)

Jumps to a given position (using the hh:mm:ss syntax) in the animation

We now need to work on the event handlers. When the mouse leaves the canvas, we pause the animations using the pause() method. Here is the code:

private void pauseAnimation(object sender, MouseEventArgs e)
{
MyRectangleStoryboard.Pause();
MyTextBlockStoryboard.Pause();
}

Starting the animations is a bit more complicated because the Begin() method starts an animation (or a storyboard, to be exact) at the very beginning, but does not resume paused animations at their current position. On the other hand, the Resume() method resumes a paused animation, but does not start a stopped one. Therefore, the C# property hasBegun needs to remember whether the animation has already been started. Once an animation has been started, it will not be stopped (only eventually paused), since RepeatBehavior has been set to Forever. This allows us to implement the MouseHover event handler. Example 8 shows the complete code.

Example 8. Scripting animations, the XAML C# file (Page.xaml.cs, project AnimationResources)

using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Animation;

namespace AnimationResources
{
public partial class Page : UserControl
{
private bool hasBegun = false;

public Page()
{
// Required to initialize variables
InitializeComponent();
}

private void beginAnimation(object sender, MouseEventArgs e)
{
if (hasBegun)
{
MyRectangleStoryboard.Resume();
MyTextBlockStoryboard.Resume();
}
else
{
MyRectangleStoryboard.Begin();
MyTextBlockStoryboard.Begin();
hasBegun = true;
}
}

private void pauseAnimation(object sender, MouseEventArgs e)
{
MyRectangleStoryboard.Pause();
MyTextBlockStoryboard.Pause();
}
}
}


Figure 8 shows the application in action (but you'll get the real experience when you try the code on your own). When the mouse hovers over the canvas, the animation starts. If you move the mouse pointer off the canvas, the animation stops, but if the mouse pointer returns, the animation continues at the same position at which it previously stopped.

Figure 8. The mouse controls the animation


Transformations and animations are quite different concepts, but both can achieve impressive effects with little effort. With bigger projects, you will probably resort to Microsoft Expression Blend 2 to get these effects up and running, but this chapter also showed you how to use code to provide additional functionality.

Other  
 
PS4 game trailer XBox One game trailer
WiiU game trailer 3ds game trailer
Top 10 Video Game
-   Minecraft Mods - MAD PACK #10 'NETHER DOOM!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
-   Minecraft Mods - MAD PACK #9 'KING SLIME!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
-   Minecraft Mods - MAD PACK #2 'LAVA LOBBERS!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
-   Minecraft Mods - MAD PACK #3 'OBSIDIAN LONGSWORD!' with Vikkstar & Pete (Minecraft Mod - Mad Pack 2)
-   Total War: Warhammer [PC] Demigryph Trailer
-   Minecraft | MINIONS MOVIE MOD! (Despicable Me, Minions Movie)
-   Minecraft | Crazy Craft 3.0 - Ep 3! "TITANS ATTACK"
-   Minecraft | Crazy Craft 3.0 - Ep 2! "THIEVING FROM THE CRAZIES"
-   Minecraft | MORPH HIDE AND SEEK - Minions Despicable Me Mod
-   Minecraft | Dream Craft - Star Wars Modded Survival Ep 92 "IS JOE DEAD?!"
-   Minecraft | Dream Craft - Star Wars Modded Survival Ep 93 "JEDI STRIKE BACK"
-   Minecraft | Dream Craft - Star Wars Modded Survival Ep 94 "TATOOINE PLANET DESTRUCTION"
-   Minecraft | Dream Craft - Star Wars Modded Survival Ep 95 "TATOOINE CAPTIVES"
-   Hitman [PS4/XOne/PC] Alpha Gameplay Trailer
-   Satellite Reign [PC] Release Date Trailer
Video
programming4us
 
 
programming4us