A game framework written with osu! in mind.
at master 205 lines 7.0 kB view raw
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 osu.Framework.Allocation; 6using osu.Framework.Audio; 7using osu.Framework.Audio.Sample; 8using osu.Framework.Extensions.IEnumerableExtensions; 9using osu.Framework.Graphics; 10using osu.Framework.Graphics.Audio; 11using osu.Framework.Graphics.Containers; 12using osu.Framework.Graphics.Shapes; 13using osu.Framework.Input.Events; 14using osuTK; 15using osuTK.Graphics; 16 17namespace osu.Framework.Tests.Visual.Audio 18{ 19 public class TestSceneSamples : FrameworkTestScene 20 { 21 private readonly AudioContainer samples; 22 private readonly TrackingLine tracking; 23 24 private const int beats = 8; 25 private const int notes = 16; 26 27 public TestSceneSamples() 28 { 29 Children = new Drawable[] 30 { 31 new Container 32 { 33 Anchor = Anchor.Centre, 34 Origin = Anchor.Centre, 35 RelativeSizeAxes = Axes.Both, 36 Size = new Vector2(0.95f), 37 FillMode = FillMode.Fit, 38 Children = new Drawable[] 39 { 40 new Box 41 { 42 Colour = Color4.Blue, 43 RelativeSizeAxes = Axes.Both, 44 }, 45 new Grid(beats - 1, notes), 46 samples = new AudioContainer 47 { 48 RelativeSizeAxes = Axes.Both, 49 RelativeChildSize = new Vector2(beats - 1, notes), 50 Children = new Drawable[] 51 { 52 new DraggableSample(0, 0), 53 new DraggableSample(1, 2), 54 new DraggableSample(2, 4), 55 new DraggableSample(3, 5), 56 new DraggableSample(4, 8), 57 new DraggableSample(5, 11), 58 new DraggableSample(6, 14), 59 new DraggableSample(7, 16), 60 tracking = new TrackingLine() 61 } 62 }, 63 } 64 }, 65 }; 66 67 AddStep("reduce volume", () => samples.VolumeTo(samples.Volume.Value - 0.5f, 1000, Easing.OutQuint)); 68 AddStep("increase volume", () => samples.VolumeTo(samples.Volume.Value + 0.5f, 1000, Easing.OutQuint)); 69 70 AddStep("reduce frequency", () => samples.FrequencyTo(samples.Frequency.Value - 0.1f, 1000, Easing.OutQuint)); 71 AddStep("increase frequency", () => samples.FrequencyTo(samples.Frequency.Value + 0.1f, 1000, Easing.OutQuint)); 72 73 AddStep("left balance", () => samples.BalanceTo(samples.Balance.Value - 1, 1000, Easing.OutQuint)); 74 AddStep("right balance", () => samples.BalanceTo(samples.Balance.Value + 1, 1000, Easing.OutQuint)); 75 } 76 77 protected override void Update() 78 { 79 base.Update(); 80 81 if (tracking.X > beats) 82 { 83 tracking.X = 0; 84 samples.OfType<DraggableSample>().ForEach(s => s.Reset()); 85 } 86 else 87 { 88 tracking.X += (float)Clock.ElapsedFrameTime / 500; 89 samples.OfType<DraggableSample>().Where(s => !s.Played && s.X <= tracking.X).ForEach(s => s.Play()); 90 } 91 } 92 93 private class TrackingLine : CompositeDrawable 94 { 95 public TrackingLine() 96 { 97 RelativePositionAxes = Axes.Both; 98 RelativeSizeAxes = Axes.Y; 99 Size = new Vector2(4, notes); 100 Colour = Color4.SkyBlue; 101 102 Blending = BlendingParameters.Additive; 103 104 InternalChildren = new Drawable[] 105 { 106 new Box 107 { 108 Colour = Color4.White, 109 RelativeSizeAxes = Axes.Both, 110 }, 111 }; 112 } 113 } 114 115 public class Grid : CompositeDrawable 116 { 117 public Grid(int beats, int notes) 118 { 119 RelativeSizeAxes = Axes.Both; 120 121 for (int i = 0; i <= beats; i++) 122 { 123 AddInternal(new Box 124 { 125 RelativePositionAxes = Axes.Both, 126 RelativeSizeAxes = Axes.Y, 127 Width = 1, 128 Colour = Color4.White, 129 X = (float)i / beats 130 }); 131 } 132 133 for (int i = 0; i <= notes; i++) 134 { 135 AddInternal(new Box 136 { 137 RelativePositionAxes = Axes.Both, 138 RelativeSizeAxes = Axes.X, 139 Height = 1, 140 Colour = Color4.White, 141 Y = (float)i / notes 142 }); 143 } 144 } 145 } 146 147 private class DraggableSample : CompositeDrawable 148 { 149 public DraggableSample(int beat, int pitch) 150 { 151 RelativePositionAxes = Axes.Both; 152 153 Position = new Vector2(beat, pitch); 154 Size = new Vector2(16); 155 156 Origin = Anchor.Centre; 157 158 InternalChildren = new Drawable[] 159 { 160 circle = new Circle 161 { 162 Colour = Color4.Yellow, 163 RelativeSizeAxes = Axes.Both, 164 Anchor = Anchor.Centre, 165 Origin = Anchor.Centre, 166 }, 167 }; 168 } 169 170 public bool Played { get; private set; } 171 172 [BackgroundDependencyLoader] 173 private void load(ISampleStore samples) 174 { 175 AddInternal(sample = new DrawableSample(samples.Get("long.mp3"))); 176 } 177 178 private DrawableSample sample; 179 180 private readonly Circle circle; 181 182 protected override bool OnDragStart(DragStartEvent e) => true; 183 184 protected override void OnDrag(DragEvent e) 185 { 186 Y = (int)(e.MousePosition.Y / (Parent.DrawHeight / notes)); 187 } 188 189 public void Reset() 190 { 191 Played = false; 192 } 193 194 public void Play() 195 { 196 Played = true; 197 circle.ScaleTo(1.8f).ScaleTo(1, 600, Easing.OutQuint); 198 199 var channel = sample.GetChannel(); 200 channel.Frequency.Value = 1 + Y / notes; 201 channel.Play(); 202 } 203 } 204 } 205}