A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System.Linq;
5using NUnit.Framework;
6using osu.Framework.Graphics;
7using osu.Framework.Graphics.Containers;
8using osu.Framework.Graphics.Lines;
9using osu.Framework.Graphics.Shapes;
10using osu.Framework.Graphics.Sprites;
11using osu.Framework.Input.Events;
12using osuTK;
13using osuTK.Graphics;
14
15namespace osu.Framework.Tests.Visual.Input
16{
17 public class TestScenePathInput : FrameworkTestScene
18 {
19 private const float path_width = 50;
20 private const float path_radius = path_width / 2;
21
22 private Path path;
23 private TestPoint testPoint;
24 private SpriteText text;
25
26 [Test]
27 public void Setup() => Schedule(() =>
28 {
29 Children = new Drawable[]
30 {
31 path = new HoverablePath(),
32 testPoint = new TestPoint(),
33 text = new SpriteText { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre }
34 };
35 });
36
37 [Test]
38 public void TestHorizontalPath()
39 {
40 addPath("Horizontal path", new Vector2(100), new Vector2(300, 100));
41 // Left out
42 test(new Vector2(40, 100), false);
43 // Left in
44 test(new Vector2(80, 100), true);
45 // Cap out
46 test(new Vector2(60), false);
47 // Cap in
48 test(new Vector2(70), true);
49 //Right out
50 test(new Vector2(360, 100), false);
51 // Centre
52 test(new Vector2(200, 100), true);
53 // Top out
54 test(new Vector2(190, 40), false);
55 // Top in
56 test(new Vector2(190, 60), true);
57 }
58
59 [Test]
60 public void TestDiagonalPath()
61 {
62 addPath("Diagonal path", new Vector2(300), new Vector2(100));
63 // Top-left out
64 test(new Vector2(50), false);
65 // Top-left in
66 test(new Vector2(80), true);
67 // Left out
68 test(new Vector2(145, 235), false);
69 // Left in
70 test(new Vector2(170, 235), true);
71 // Cap out
72 test(new Vector2(355, 300), false);
73 // Cap in
74 test(new Vector2(340, 300), true);
75 }
76
77 [Test]
78 public void TestVShaped()
79 {
80 addPath("V-shaped", new Vector2(100), new Vector2(300), new Vector2(500, 100));
81 // Intersection out
82 test(new Vector2(300, 225), false);
83 // Intersection in
84 test(new Vector2(300, 240), true);
85 // Bottom cap out
86 test(new Vector2(300, 355), false);
87 // Bottom cap in
88 test(new Vector2(300, 340), true);
89 }
90
91 [Test]
92 public void TestOverlapping()
93 {
94 addPath("Overlapping", new Vector2(100), new Vector2(600), new Vector2(800, 300), new Vector2(100, 400));
95 // Left intersection out
96 test(new Vector2(250, 325), false);
97 // Left intersection in
98 test(new Vector2(260, 325), true);
99 // Top intersection out
100 test(new Vector2(380, 300), false);
101 // Top intersection in
102 test(new Vector2(380, 320), true);
103 // Triangle left intersection out
104 test(new Vector2(475, 400), false);
105 // Triangle left intersection in
106 test(new Vector2(460, 400), true);
107 // Triangle right intersection out
108 test(new Vector2(690, 370), false);
109 // Triangle right intersection in
110 test(new Vector2(700, 370), true);
111 // Triangle bottom intersection out
112 test(new Vector2(590, 515), false);
113 // Triangle bottom intersection in
114 test(new Vector2(590, 525), true);
115 // Centre intersection in
116 test(new Vector2(370, 360), true);
117 }
118
119 protected override bool OnMouseMove(MouseMoveEvent e)
120 {
121 text.Text = path.ToLocalSpace(e.ScreenSpaceMousePosition).ToString();
122 return base.OnMouseMove(e);
123 }
124
125 private void addPath(string name, params Vector2[] vertices) => AddStep(name, () =>
126 {
127 path.PathRadius = path_width;
128 path.Vertices = vertices.ToList();
129 });
130
131 private void test(Vector2 position, bool shouldReceivePositionalInput)
132 {
133 AddAssert($"Test @ {position} = {shouldReceivePositionalInput}", () =>
134 {
135 testPoint.Position = position;
136 return path.ReceivePositionalInputAt(path.ToScreenSpace(position)) == shouldReceivePositionalInput;
137 });
138 }
139
140 private class TestPoint : CircularContainer
141 {
142 public TestPoint()
143 {
144 Origin = Anchor.Centre;
145
146 Size = new Vector2(5);
147 Colour = Color4.Red;
148 Masking = true;
149
150 InternalChild = new Box { RelativeSizeAxes = Axes.Both };
151 }
152 }
153
154 private class HoverablePath : Path
155 {
156 protected override bool OnHover(HoverEvent e)
157 {
158 Colour = Color4.Green;
159 return true;
160 }
161
162 protected override void OnHoverLost(HoverLostEvent e)
163 {
164 Colour = Color4.White;
165 }
166 }
167 }
168}