Beispiel #1
0
 public Playfield()
 {
     AddInternal(HitObjects = new HitObjectContainer
     {
         RelativeSizeAxes = Axes.Both,
     });
 }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
 public HitObjectArea(HitObjectContainer hitObjectContainer)
 {
     InternalChildren = new[]
     {
         hitObjectContainer,
     };
 }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        /// <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
     };
 }
Beispiel #9
0
        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;
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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;
        }
Beispiel #12
0
        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);
        }
Beispiel #14
0
 public ColumnHitObjectArea(HitObjectContainer hitObjectContainer)
 {
     InternalChildren = new[]
     {
         hitTarget = new DefaultHitTarget
         {
             RelativeSizeAxes = Axes.X,
         },
         hitObjectContainer
     };
 }
Beispiel #15
0
        public Playfield()
        {
            AddInternal(content = new ScaledContainer()
            {
                RelativeSizeAxes = Axes.Both,
            });

            Add(HitObjects = new HitObjectContainer
            {
                RelativeSizeAxes = Axes.Both,
            });
        }
Beispiel #16
0
 public Beatmap(
     BeatmapSettings settings,
     Texture2D backgroundTexture,
     Music music,
     TimingPointContainer timingPoints,
     HitObjectContainer hitObjects)
 {
     Settings          = settings;
     BackgroundTexture = backgroundTexture;
     Music             = music;
     TimingPoints      = timingPoints;
     HitObjects        = hitObjects;
 }
Beispiel #17
0
 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
         }
     };
 }
Beispiel #18
0
 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));
        }
Beispiel #20
0
        /// <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));
        }
Beispiel #21
0
        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;
                }));
            }
        }
Beispiel #22
0
        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,
            };
        }
Beispiel #23
0
        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,
            });
        }
Beispiel #24
0
        /// <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,
            });
        }
Beispiel #25
0
 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
     };
 }
Beispiel #26
0
        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);
        }
Beispiel #27
0
        /// <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,
            };
        }
Beispiel #29
0
 public OrderedHitPolicy(HitObjectContainer hitObjectContainer)
 {
     this.hitObjectContainer = hitObjectContainer;
 }
 public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObjectContainer.ReceivePositionalInputAt(screenSpacePos);