-
Notifications
You must be signed in to change notification settings - Fork 415
Setting up your first project
This tutorial is designed to get you started with a new project using osu-framework. It is not meant to be a guide for contribution to the osu-framework project.
You can find this code and more to help you get started in SampleGame
and SampleGame.Desktop
- Create a new WinExe project.
Simply set the ouput type in your .csproj file to <OutputType>WinExe</OutputType>
, or change your existing output type to WinExe. If you're using Visual Studio or Rider, set the project type to "Windows Application"
- Install the nuget package from https://www.nuget.org/packages/ppy.osu.Framework/.
- Create a new game class that derives osu.Framework.Game.
The following code creates a cube with a rigid body container.
namespace AwesomeGame
{
public class AwesomeGame : Game
{
RigidBodySimulation sim;
[BackgroundDependencyLoader]
private void load()
{
Child = sim = new RigidBodySimulation { RelativeSizeAxes = Axes.Both };
RigidBodyContainer<Drawable> rbc = new RigidBodyContainer<Drawable>
{
Child = new Box
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(150, 150),
Colour = Color4.Tomato,
},
Position = new Vector2(500, 500),
Size = new Vector2(200, 200),
Rotation = 45,
Colour = Color4.Tomato,
Masking = true,
};
sim.Add(rbc);
}
}
}
- In your main() method, create a new instance of your game.
[STAThread]
public static void Main()
{
using (Game game = new AwesomeGame())
using (GameHost host = Host.GetSuitableHost(@"awesome-game"))
host.Run(game);
}
The BackgroundDependencyLoader attribute denotes a method to be the load method of a Drawable. You can specify a type in the method parameters to attempt to grab an object of that type that has been cached.
osu-framework has a visual testing framework that is meant to help provide tests that can be verified both visually and systematically via NUnit. To start using visual tests, you will need to create a TestBrowser and add it to your game. In order for your test browser to discover tests, you will need to specify a namespace in which for the browser to look in when constructing it.
namespace AwesomeGame.VisualTests
{
public class AwesomeGameTestRunner : AwesomeGame
{
[BackgroundDependencyLoader]
private void load()
{
Child = new DrawSizePreservingFillContainer
{
Children = new Drawable[]
{
new TestBrowser("AwesomeGame"), //Specify the namespace to discover tests from
new CursorContainer(),
},
};
}
public override void SetHost(GameHost host)
{
base.SetHost(host);
host.Window.CursorState |= CursorState.Hidden;
}
}
}
Note that in order for you to be able to run the visual tests, you will have to switch your game instance to the visual tests. To do that, you can either create your visual tests in a separate project and run them as a build configuration, or simply apply build configuration pre-processor checks in your entry point to run the appropriate game.
For example, if I have the VisualTests build configuration, rider will automatically create the pre-processor flag VISUALTESTS, which allows us to use #if VISUALTESTS
to check the current build configuration.
namespace Gale
{
class Program
{
[STAThread]
public static void Main()
{
#if VISUALTESTS
using (Game game = new VisualTestRunner())
#else
using (Game game = new GaleGame())
#endif
using (GameHost host = Host.GetSuitableHost(@"Gale"))
host.Run(game);
}
}
}
Now that our test browser is discovering tests from the specified namespace, we can start adding tests! To do so, create a new class that derives TestCase with the TestFixture attribute. From here, we can add steps to this test of various types:
- AddStep creates a step that runs a method. Completes successfully if no exceptions are caught.
- AddRepeatStep creates a step that runs a method a specified amount of times. Completes successfully if no exceptions are caught.
- AddToggleStep toggles a flag.
- AddUntilStep adds a step that attempts to run until a condition becomes true, or fails when it times out.
- AddWaitStep adds a step that waits a specified amount of time before continuing to the next step.
- AddSliderStep adds a step that creates a slider-bar that adjusts a set value.
- AddAssert creates a step that fails if the specified value does not return true.
The following code adds a simple cube to the visual test browser that we created above. The cube has a rigid body attached, and should drop to the bottom of the screen when created. From here, we can choose to check the behavior of the cube by asserting that the cube eventually reaches the bottom via AddAssert.
namespace AwesomeGame.VisualTests
{
[TestFixture]
public class RigidCubeTest : TestCase
{
private RigidBodySimulation sim;
[Test]
public void AwesomeTestName()
{
AddStep("Drop a cube", DropCube);
}
private void DropCube()
{
Child = sim = new RigidBodySimulation { RelativeSizeAxes = Axes.Both };
RigidBodyContainer<Drawable> rbc = new RigidBodyContainer<Drawable>
{
Child = new Box
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(150, 150),
Colour = Color4.Tomato,
},
Position = new Vector2(500, 500),
Size = new Vector2(200, 200),
Rotation = 45,
Colour = Color4.Tomato,
Masking = true,
};
sim.Add(rbc);
}
}
}
The Setup NUnit attribute marks a method as a setup method that runs as a step before every group of tests in a test method. The steps created by this attribute get added to the visual test browser as well.
For information on how to load your own resources such as textures and audio, please read Setting Up Compiled Resource Stores.
For more information regarding dependency injection via the BackgroundDependencyLoader attribute, please read Dependency Injection
For additional reading on visual tests, please refer to Dynamic Compilation and Visual Testing
- Create your first project
- Learning framework key bindings
- Adding resource stores
- Adding custom key bindings
- Adding custom fonts