Skip to content

Commit

Permalink
⚙️Add sample project (#251)
Browse files Browse the repository at this point in the history
* Start work for issue #250

* chore: add sample project
  • Loading branch information
CalvinWilkinson authored May 17, 2024
1 parent ba0d4fc commit c648156
Show file tree
Hide file tree
Showing 6 changed files with 287 additions and 0 deletions.
9 changes: 9 additions & 0 deletions SampleProjects/SampleProjects.sln
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rectangles", "Guides\Rectan
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lines", "Guides\Lines\Lines.csproj", "{C2C7C7A6-3A8A-4F30-A517-18D7748259C3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CirclePrison", "Samples\CirclePrison\CirclePrison.csproj", "{9196847B-8558-4935-82EE-69AE1F0C3BB3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{BFFC67C9-73D5-45F1-B05E-8DA2E0DA9011}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -88,6 +92,10 @@ Global
{C2C7C7A6-3A8A-4F30-A517-18D7748259C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2C7C7A6-3A8A-4F30-A517-18D7748259C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2C7C7A6-3A8A-4F30-A517-18D7748259C3}.Release|Any CPU.Build.0 = Release|Any CPU
{9196847B-8558-4935-82EE-69AE1F0C3BB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9196847B-8558-4935-82EE-69AE1F0C3BB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9196847B-8558-4935-82EE-69AE1F0C3BB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9196847B-8558-4935-82EE-69AE1F0C3BB3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{1352A677-C91D-41AF-B8DC-DB01B714B25D} = {02B09EF2-D131-4628-BAD5-602A3BD9188E}
Expand All @@ -103,5 +111,6 @@ Global
{1B3DDC8F-C486-4818-AC13-23176B4B45E4} = {02B09EF2-D131-4628-BAD5-602A3BD9188E}
{78C04572-404C-4787-8189-CDFDE862376C} = {02B09EF2-D131-4628-BAD5-602A3BD9188E}
{C2C7C7A6-3A8A-4F30-A517-18D7748259C3} = {02B09EF2-D131-4628-BAD5-602A3BD9188E}
{9196847B-8558-4935-82EE-69AE1F0C3BB3} = {BFFC67C9-73D5-45F1-B05E-8DA2E0DA9011}
EndGlobalSection
EndGlobal
30 changes: 30 additions & 0 deletions SampleProjects/Samples/CirclePrison/CirclePrison.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="KinsonDigital.Velaptor" Version="1.0.0-preview.36" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<None Remove="stylecop.json" />
<AdditionalFiles Include="stylecop.json" />
<None Update="Content\Audio\bounce.ogg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Binary file not shown.
226 changes: 226 additions & 0 deletions SampleProjects/Samples/CirclePrison/Game.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
// <copyright file="Game.cs" company="KinsonDigital">
// Copyright (c) KinsonDigital. All rights reserved.
// </copyright>

namespace CirclePrison;

using System.Drawing;
using System.Numerics;
using Velaptor;
using Velaptor.Batching;
using Velaptor.Content;
using Velaptor.ExtensionMethods;
using Velaptor.Factories;
using Velaptor.Graphics;
using Velaptor.Graphics.Renderers;
using Velaptor.Input;
using Velaptor.UI;

/// <summary>
/// The main game class.
/// </summary>
public class Game : Window
{
private readonly IBatcher batcher;
private readonly IShapeRenderer shapeRenderer;
private readonly ILineRenderer lineRenderer;
private readonly ILoader<IAudio> audioLoader;
private readonly IAppInput<MouseState> mouse;
private readonly Random random = new ();
private CircleShape prisoner;
private CircleShape prison;
private Vector2 velocity;
private IAudio? audio;
private float startingVel;
private bool shouldSpeedUpPrisonerVel = true;
private Line line;
private Vector2 prisonOrigin;

/// <summary>
/// Initializes a new instance of the <see cref="Game"/> class.
/// </summary>
public Game()
{
Title = "Circle Prison";
Width = 800;
Height = 800;

this.batcher = RendererFactory.CreateBatcher();
this.shapeRenderer = RendererFactory.CreateShapeRenderer();
this.lineRenderer = RendererFactory.CreateLineRenderer();

this.audioLoader = ContentLoaderFactory.CreateAudioLoader();

this.mouse = HardwareFactory.GetMouse();
}

/// <summary>
/// Loads game content.
/// </summary>
protected override void OnLoad()
{
this.prisonOrigin = new Vector2(400, 400);

this.prison = new CircleShape
{
Color = Color.Cyan,
Position = this.prisonOrigin,
Diameter = 400,
IsSolid = false,
BorderThickness = 2,
};

this.prisoner = new CircleShape
{
Radius = 12,
Color = Color.MediumPurple,
};

this.line = new Line
{
Color = Color.Yellow,
Thickness = 2,
};

// Generate a random angle
var angle = (float)(this.random.NextDouble() * 2 * Math.PI);

// Generate a random distance from the center of the prison ball
var distance = (float)(this.random.NextDouble() * this.prison.Radius);

// Calculate the x and y coordinates of the starting position
var x = (this.prison.Position.X + distance) * MathF.Cos(angle);
var y = (this.prison.Position.Y + distance) * MathF.Sin(angle);

this.prisoner.Position = new Vector2(x, y);

this.audio = this.audioLoader.Load("bounce", AudioBuffer.Full);

if (this.audio.IsPlaying)
{
this.audio.Stop();
}

this.audio.Play();

var randomSign = this.random.Next(0, 2) == 0 ? -1 : 1;
var randomX = this.random.Next(50, 60) * randomSign;

randomSign = this.random.Next(0, 2) == 0 ? -1 : 1;
var randomY = this.random.Next(50, 60) * randomSign;

this.velocity = new Vector2(randomX, randomY);

this.startingVel = 10;

base.OnLoad();
}

/// <summary>
/// Updates the application. Executes one time for every iteration of the game loop
/// and always BEFORE the <see cref="Window.OnDraw"/> method.
/// </summary>
/// <param name="frameTime">The amount of time that has passed for the current frame.</param>
protected override void OnUpdate(FrameTime frameTime)
{
var deltaVelocity = this.velocity * (float)frameTime.ElapsedTime.TotalSeconds;
this.prisoner.Position += deltaVelocity;

ProcessMouse();
ProcessCollision();

this.line.P1 = this.prisoner.Position;
this.line.P2 = this.prison.Position;

base.OnUpdate(frameTime);
}

/// <summary>
/// Draws to the screen. Executes one time for every iteration of the game loop
/// and always AFTER the <see cref="OnUpdate"/> method has finished.
/// </summary>
/// <param name="frameTime">The amount of time that has passed for the current frame.</param>
protected override void OnDraw(FrameTime frameTime)
{
this.batcher.Begin();

this.shapeRenderer.Render(this.prison);
this.lineRenderer.Render(this.line, 10);
this.shapeRenderer.Render(this.prisoner, 20);

this.batcher.End();

base.OnDraw(frameTime);
}

/// <summary>
/// Process mouset input.
/// </summary>
private void ProcessMouse()
{
var currentMouseState = this.mouse.GetState();

var mousePos = currentMouseState.GetPosition();

this.prison.Position = new Vector2(mousePos.X, mousePos.Y);
}

/// <summary>
/// Prociess collisions.
/// </summary>
private void ProcessCollision()
{
ArgumentNullException.ThrowIfNull(this.audio);

var distance = Vector2.Distance(this.prison.Position, this.prisoner.Position);
var boundary = this.prison.Radius - this.prisoner.Radius;

if (distance < boundary)
{
return;
}

if (this.audio.IsPlaying)
{
this.audio.Stop();
}

this.audio.Play();

// Swap colors between the prison wall and the line
(this.prison.Color, this.line.Color) = (this.line.Color, this.prison.Color);

var normal = Vector2.Normalize(this.prisoner.Position - this.prison.Position);

// Reflect the velocity along the normal vector
this.velocity = Vector2.Reflect(this.velocity, normal);

// Add a small offset to the prisoner's position to ensure it's outside the boundary on the next frame update
this.prisoner.Position = this.prison.Position + (normal * (this.prison.Radius - this.prisoner.Radius));

var minVelocity = Math.Abs(Math.Min(this.velocity.X, this.velocity.Y));
var maxVelocity = Math.Abs(Math.Max(this.velocity.X, this.velocity.Y));

if (maxVelocity >= 2000)
{
this.shouldSpeedUpPrisonerVel = false;
}
else if (minVelocity <= this.startingVel)
{
this.shouldSpeedUpPrisonerVel = true;
}

const float velChangeAmount = 50f;

if (this.shouldSpeedUpPrisonerVel)
{
this.velocity.X = this.velocity.X < 0 ? this.velocity.X - velChangeAmount : this.velocity.X + velChangeAmount;
this.velocity.Y = this.velocity.Y < 0 ? this.velocity.Y - velChangeAmount : this.velocity.Y + velChangeAmount;
}
else
{
this.velocity.X = this.velocity.X < 0 ? this.velocity.X + velChangeAmount : this.velocity.X - velChangeAmount;
this.velocity.Y = this.velocity.Y < 0 ? this.velocity.Y + velChangeAmount : this.velocity.Y - velChangeAmount;
}
}
}
8 changes: 8 additions & 0 deletions SampleProjects/Samples/CirclePrison/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// <copyright file="Program.cs" company="KinsonDigital">
// Copyright (c) KinsonDigital. All rights reserved.
// </copyright>

using CirclePrison;

var game = new Game();
game.Show();
14 changes: 14 additions & 0 deletions SampleProjects/Samples/CirclePrison/stylecop.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
// ACTION REQUIRED: This file was automatically added to your project, but it
// will not take effect until additional steps are taken to enable it. See the
// following page for additional information:
//
// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md

"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"companyName": "KinsonDigital"
}
}
}

0 comments on commit c648156

Please sign in to comment.