public Playfield() { AddInternal(HitObjects = new HitObjectContainer { RelativeSizeAxes = Axes.Both, }); }
private void load() { var droppedObjectContainer = new DroppedObjectContainer(); Catcher = new Catcher(droppedObjectContainer, difficulty) { X = CENTER_X }; AddRangeInternal(new[] { droppedObjectContainer, Catcher.CreateProxiedContent(), HitObjectContainer.CreateProxy(), // This ordering (`CatcherArea` before `HitObjectContainer`) is important to // make sure the up-to-date catcher position is used for the catcher catching logic of hit objects. CatcherArea = new CatcherArea { Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, Catcher = Catcher, }, HitObjectContainer, }); RegisterPool <Droplet, DrawableDroplet>(50); RegisterPool <TinyDroplet, DrawableTinyDroplet>(50); RegisterPool <Fruit, DrawableFruit>(100); RegisterPool <Banana, DrawableBanana>(100); RegisterPool <JuiceStream, DrawableJuiceStream>(10); RegisterPool <BananaShower, DrawableBananaShower>(2); }
/// <summary> /// Adds a DrawableHitObject to this Playfield. /// </summary> /// <param name="hitObject">The DrawableHitObject to add.</param> public override void Add(DrawableHitObject hitObject) { hitObject.AccentColour.Value = AccentColour; hitObject.OnNewResult += OnNewResult; HitObjectContainer.Add(hitObject); }
public HitObjectArea(HitObjectContainer hitObjectContainer) { InternalChildren = new[] { hitObjectContainer, }; }
public override bool HandleMovement(MoveSelectionEvent <HitObject> moveEvent) { var blueprint = moveEvent.Blueprint; Vector2 originalPosition = HitObjectContainer.ToLocalSpace(blueprint.ScreenSpaceSelectionPoint); Vector2 targetPosition = HitObjectContainer.ToLocalSpace(blueprint.ScreenSpaceSelectionPoint + moveEvent.ScreenSpaceDelta); float deltaX = targetPosition.X - originalPosition.X; deltaX = limitMovement(deltaX, SelectedItems); if (deltaX == 0) { // Even if there is no positional change, there may be a time change. return(true); } EditorBeatmap.PerformOnSelection(h => { if (!(h is CatchHitObject catchObject)) { return; } catchObject.OriginalX += deltaX; // Move the nested hit objects to give an instant result before nested objects are recreated. foreach (var nested in catchObject.NestedHitObjects.OfType <CatchHitObject>()) { nested.OriginalX += deltaX; } }); return(true); }
public override bool HandleMovement(MoveSelectionEvent <HitObject> moveEvent) { var blueprint = moveEvent.Blueprint; Vector2 originalPosition = HitObjectContainer.ToLocalSpace(blueprint.ScreenSpaceSelectionPoint); Vector2 targetPosition = HitObjectContainer.ToLocalSpace(blueprint.ScreenSpaceSelectionPoint + moveEvent.ScreenSpaceDelta); float deltaX = targetPosition.X - originalPosition.X; EditorBeatmap.PerformOnSelection(h => { if (!(h is CatchHitObject hitObject)) { return; } if (hitObject is BananaShower) { return; } // TODO: confine in bounds hitObject.OriginalXBindable.Value += deltaX; // Move the nested hit objects to give an instant result before nested objects are recreated. foreach (var nested in hitObject.NestedHitObjects.OfType <CatchHitObject>()) { nested.OriginalXBindable.Value += deltaX; } }); return(true); }
/// <summary> /// A container for keeping track of DrawableHitObjects. /// </summary> /// <param name="customWidth">Whether we want our internal coordinate system to be scaled to a specified width.</param> protected Playfield(float?customWidth = null) { AlwaysReceiveInput = true; // Default height since we force relative size axes Size = Vector2.One; AddInternal(ScaledContent = new ScaledContainer { CustomWidth = customWidth, RelativeSizeAxes = Axes.Both, Children = new[] { content = new Container { RelativeSizeAxes = Axes.Both, } } }); HitObjects = new HitObjectContainer <DrawableHitObject <TObject, TJudgement> > { RelativeSizeAxes = Axes.Both, }; }
public HitObjectArea(HitObjectContainer hitObjectContainer) { InternalChild = new Container { RelativeSizeAxes = Axes.Both, Child = HitObjectContainer = hitObjectContainer }; }
protected override void Update() { base.Update(); head.Y = HitObjectContainer.PositionAtTime(HitObject.Head.StartTime, HitObject.StartTime); tail.Y = HitObjectContainer.PositionAtTime(HitObject.Tail.StartTime, HitObject.StartTime); Height = HitObjectContainer.LengthAtTime(HitObject.StartTime, HitObject.EndTime) + tail.DrawHeight; }
public HitObjectContainer ReadHitObjects(string beatmapName, BeatmapSettings beatmapSettings) { HitObjectContainer hitObjectContainer = new HitObjectContainer(beatmapSettings.Difficulty.KeyAmount); LogHelper.Log($"BeatmapReader: Reading Beatmap Hit Objects '{beatmapName}'"); string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ProcessorSettings.BeatmapsFolder, beatmapName, ProcessorSettings.HitObjectsFolder, beatmapSettings.HitObjectsFilename + "_" + beatmapSettings.Metadata.Version); if (!File.Exists(path)) { throw new FileNotFoundException("hitobjects file not found"); } Console.WriteLine(path); // Reading HitObjects file, which contains all the objects used in the beatmap // HitObjects file uses this format: "Column Position" for a Click, and "Column Position EndPosition" for a Hold using (StreamReader sr = new StreamReader(path)) { LogHelper.Log($"BeatmapReader: Found Beatmap Hit Objects file '{beatmapSettings.HitObjectsFilename}'"); string full = sr.ReadToEnd(); string[] lines = full.Split('\n'); foreach (var line in lines) { // If the line is empty or contains only whitespaces, skip it if (string.IsNullOrWhiteSpace(line)) { continue; } // Split the line, remove all whitespaces string[] tokens = Array.ConvertAll(line.Split(' '), p => p.Trim()); // If length is 3, the object is a 'Hold', else it's 'Click' HitObject ho; if (tokens.Length == 2) { ho = new NoteClick(int.Parse(tokens[0]), int.Parse(tokens[1])); } else if (tokens.Length == 3) { ho = new NoteHold(int.Parse(tokens[0]), int.Parse(tokens[1]), int.Parse(tokens[2])); } else { throw new Exception("Unknown note type"); } hitObjectContainer.Add(ho); } } LogHelper.Log($"BeatmapReader: Successfully Read Beatmap Hit Objects. Total Hit Objects count: {hitObjectContainer.Count}"); return(hitObjectContainer); }
public HitObject(HitObjectContainer container, TextureStore textureStore, IBindable <float> trackPosition, float hitTime, int index, NoteType hitObjectType) : base(textureStore, "Circle") { m_container = container; m_trackPosition.BindDataFrom(trackPosition); m_hitTime = hitTime; Index = index; m_hitObjectType = hitObjectType; Color = m_hitObjectType == NoteType.Don ? Color.Red : Color.Blue; }
private RectangleF getBoundingBox() { float left = HitObject.OriginalX + minNestedX; float right = HitObject.OriginalX + maxNestedX; float top = HitObjectContainer.PositionAtTime(HitObject.EndTime); float bottom = HitObjectContainer.PositionAtTime(HitObject.StartTime); float objectRadius = CatchHitObject.OBJECT_RADIUS * HitObject.Scale; return(new RectangleF(left, top, right - left, bottom - top).Inflate(objectRadius)); }
/// <summary> /// Adds a DrawableHitObject to this Playfield. /// </summary> /// <param name="hitObject">The DrawableHitObject to add.</param> public override void Add(DrawableHitObject hitObject) { hitObject.AccentColour.Value = AccentColour; hitObject.OnNewResult += OnNewResult; DrawableManiaHitObject maniaObject = (DrawableManiaHitObject)hitObject; maniaObject.CheckHittable = hitPolicy.IsHittable; HitObjectContainer.Add(hitObject); }
public ColumnHitObjectArea(HitObjectContainer hitObjectContainer) { InternalChildren = new[] { hitTarget = new DefaultHitTarget { RelativeSizeAxes = Axes.X, }, hitObjectContainer }; }
public Playfield() { AddInternal(content = new ScaledContainer() { RelativeSizeAxes = Axes.Both, }); Add(HitObjects = new HitObjectContainer { RelativeSizeAxes = Axes.Both, }); }
public Beatmap( BeatmapSettings settings, Texture2D backgroundTexture, Music music, TimingPointContainer timingPoints, HitObjectContainer hitObjects) { Settings = settings; BackgroundTexture = backgroundTexture; Music = music; TimingPoints = timingPoints; HitObjects = hitObjects; }
public ColumnHitObjectArea(HitObjectContainer hitObjectContainer) { InternalChildren = new[] { hitTarget = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget()) { RelativeSizeAxes = Axes.X, }, hitObjectContainer, Explosions = new Container <HitExplosion> { RelativeSizeAxes = Axes.Both } }; }
public ColumnHitObjectArea(int columnIndex, HitObjectContainer hitObjectContainer) : base(hitObjectContainer) { AddRangeInternal(new[] { hitTarget = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitTarget, columnIndex), _ => new DefaultHitTarget()) { RelativeSizeAxes = Axes.X, Depth = 1 }, Explosions = new Container { RelativeSizeAxes = Axes.Both, Depth = -1, } }); }
public void TestFruitPlacementPosition() { const double time = 300; const float x = CatchPlayfield.CENTER_X; AddMoveStep(time, x); AddClickStep(MouseButton.Left); AddAssert("outline position is correct", () => { var outline = FruitOutlines.Single(); return(Precision.AlmostEquals(outline.X, x) && Precision.AlmostEquals(outline.Y, HitObjectContainer.PositionAtTime(time))); }); AddAssert("fruit time is correct", () => Precision.AlmostEquals(LastObject.StartTimeBindable.Value, time)); AddAssert("fruit position is correct", () => Precision.AlmostEquals(LastObject.X, x)); }
/// <summary> /// Given a position in screen space, return the time within this column. /// </summary> public double TimeAtScreenSpacePosition(Vector2 screenSpacePosition) { // convert to local space of column so we can snap and fetch correct location. Vector2 localPosition = HitObjectContainer.ToLocalSpace(screenSpacePosition); switch (ScrollingInfo.Direction.Value) { case ScrollingDirection.Down: // as above localPosition.Y = HitObjectContainer.DrawHeight - localPosition.Y; break; } // offset for the fact that blueprints are centered, as above. localPosition.Y -= DefaultNotePiece.NOTE_HEIGHT / 2; return(ScrollingInfo.Algorithm.TimeAt(localPosition.Y, Time.Current, ScrollingInfo.TimeRange.Value, HitObjectContainer.DrawHeight)); }
public virtual void ApplyToDrawableRuleset(DrawableRuleset <ManiaHitObject> drawableRuleset) { ManiaPlayfield maniaPlayfield = (ManiaPlayfield)drawableRuleset.Playfield; foreach (Column column in maniaPlayfield.Stages.SelectMany(stage => stage.Columns)) { HitObjectContainer hoc = column.HitObjectArea.HitObjectContainer; Container hocParent = (Container)hoc.Parent; hocParent.Remove(hoc); hocParent.Add(new PlayfieldCoveringWrapper(hoc).With(c => { c.RelativeSizeAxes = Axes.Both; c.Direction = ExpandDirection; c.Coverage = 0.5f; })); } }
public CatchPlayfield(BeatmapDifficulty difficulty) { CatcherArea = new CatcherArea(difficulty) { Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, }; InternalChildren = new[] { droppedObjectContainer = new DroppedObjectContainer(), CatcherArea.MovableCatcher.CreateProxiedContent(), HitObjectContainer.CreateProxy(), // This ordering (`CatcherArea` before `HitObjectContainer`) is important to // make sure the up-to-date catcher position is used for the catcher catching logic of hit objects. CatcherArea, HitObjectContainer, }; }
public Playfield() { AddInternal(scaledContent = new ScaledContainer { RelativeSizeAxes = Axes.Both, Children = new[] { Content = new Container { RelativeSizeAxes = Axes.Both, } } }); Add(HitObjects = new HitObjectContainer <DrawableHitObject <T> > { RelativeSizeAxes = Axes.Both, }); }
/// <summary> /// A container for keeping track of DrawableHitObjects. /// </summary> /// <param name="customWidth">Whether we want our internal coordinate system to be scaled to a specified width.</param> protected Playfield(float?customWidth = null) { AddInternal(ScaledContent = new ScaledContainer { CustomWidth = customWidth, RelativeSizeAxes = Axes.Both, Children = new[] { content = new Container { RelativeSizeAxes = Axes.Both, } } }); Add(HitObjects = new HitObjectContainer <DrawableHitObject <T> > { RelativeSizeAxes = Axes.Both, }); }
public ColumnHitObjectArea(HitObjectContainer hitObjectContainer) { InternalChildren = new[] { hitTargetBar = new Box { RelativeSizeAxes = Axes.X, Height = hit_target_height, Colour = Color4.Black }, hitTargetLine = new Container { RelativeSizeAxes = Axes.X, Height = hit_target_bar_height, Masking = true, Child = new Box { RelativeSizeAxes = Axes.Both } }, hitObjectContainer }; }
public override void Load(TaikoGameBase game, Screen screen, IDrawable parent) { Contain(track.Value = new Track("Honesty.mp3")); Bass.GlobalStreamVolume = 1000; Add(hitObjectContainer = new HitObjectContainer(this, TextureStore) { MinimumSize = new Vector2(-1, 150), Size = DrawingSize.XMax | DrawingSize.YMin, ScalingMethod = ScalingMethod.DontKeepRatio, Offset = new Vector2(100, 100), DebugObject = true, }); hitObjectContainer.Track.BindDataFrom(track); int offset = 269; hitObjectContainer.AddNoteRange(new Note[] { new Note(5343 + offset, NoteType.Don), new Note(5424 + offset, NoteType.Don), new Note(5505 + offset, NoteType.Don), new Note(5829 + offset, NoteType.Katsu), new Note(6153 + offset, NoteType.Don), new Note(6477 + offset, NoteType.Don), new Note(6801 + offset, NoteType.Don), new Note(7126 + offset, NoteType.Katsu), new Note(7612 + offset, NoteType.Don), new Note(7937 + offset, NoteType.Don), new Note(8423 + offset, NoteType.Don), }); Add(positionText = new Text(Fonts.MenuFont, "0")); base.Load(game, screen, parent); }
/// <summary> /// Given a time, return the screen space position within this column. /// </summary> public Vector2 ScreenSpacePositionAtTime(double time) { var pos = ScrollingInfo.Algorithm.PositionAt(time, Time.Current, ScrollingInfo.TimeRange.Value, HitObjectContainer.DrawHeight); switch (ScrollingInfo.Direction.Value) { case ScrollingDirection.Down: // We're dealing with screen coordinates in which the position decreases towards the centre of the screen resulting in an increase in start time. // The scrolling algorithm instead assumes a top anchor meaning an increase in time corresponds to an increase in position, // so when scrolling downwards the coordinates need to be flipped. pos = HitObjectContainer.DrawHeight - pos; // Blueprints are centred on the mouse position, such that the hitobject position is anchored at the top or bottom of the blueprint depending on the scroll direction. pos -= DefaultNotePiece.NOTE_HEIGHT / 2; break; case ScrollingDirection.Up: pos += DefaultNotePiece.NOTE_HEIGHT / 2; break; } return(HitObjectContainer.ToScreenSpace(new Vector2(HitObjectContainer.DrawWidth / 2, pos))); }
public CatchPlayfield(BeatmapDifficulty difficulty, Func <CatchHitObject, DrawableHitObject <CatchHitObject> > createDrawableRepresentation) { var droppedObjectContainer = new Container <CaughtObject> { RelativeSizeAxes = Axes.Both, }; CatcherArea = new CatcherArea(droppedObjectContainer, difficulty) { Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, }; InternalChildren = new[] { droppedObjectContainer, CatcherArea.MovableCatcher.CreateProxiedContent(), HitObjectContainer.CreateProxy(), // This ordering (`CatcherArea` before `HitObjectContainer`) is important to // make sure the up-to-date catcher position is used for the catcher catching logic of hit objects. CatcherArea, HitObjectContainer, }; }
public OrderedHitPolicy(HitObjectContainer hitObjectContainer) { this.hitObjectContainer = hitObjectContainer; }
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObjectContainer.ReceivePositionalInputAt(screenSpacePos);