Exemplo n.º 1
0
            public override void Draw(IDrawDevice device)
            {
                if (gameobj == null)
                {
                    return;
                }

                float timeMult = Time.TimeMult;

                for (int j = 0; j < circleEffectData.Length; j++)
                {
                    ref CircleEffect circle = ref circleEffectData[j];
                    if (circle.Alpha <= 0f)
                    {
                        continue;
                    }

                    int segmentNum = MathF.Clamp(MathF.RoundToInt(MathF.Pow(circle.Radius, 0.65f) * 2.5f), 4, 32);

                    float angle = 0.0f;
                    for (int i = 0; i < segmentNum; i++)
                    {
                        vertices[i].Pos.X = circle.Pos.X + (float)Math.Sin(angle) * circle.Radius;
                        vertices[i].Pos.Y = circle.Pos.Y - (float)Math.Cos(angle) * circle.Radius;
                        vertices[i].Pos.Z = circle.Pos.Z - 10f;
                        vertices[i].Color = new ColorRgba(1f, circle.Alpha);
                        angle            += (MathF.TwoPi / segmentNum);
                    }

                    device.AddVertices(material, VertexMode.LineLoop, vertices, 0, segmentNum);

                    circle.Radius -= timeMult * 0.8f;
                    circle.Alpha  -= timeMult * 0.03f;
                }
Exemplo n.º 2
0
        public override void OnPaint(Canvas canvas, Rect view)
        {
            IDrawDevice device = canvas.DrawDevice;

            Vector2 center = device.TargetSize * 0.5f;

            const float topLine    = 96f;
            float       bottomLine = device.TargetSize.Y - 42;

            api.DrawMaterial("MenuDim", center.X, (topLine + bottomLine) * 0.5f, Alignment.Center, ColorRgba.White, 55f, (bottomLine - topLine) * 0.063f, new Rect(0f, 0.3f, 1f, 0.4f));

            int charOffset = 0;

            if (levelList.Count > 0)
            {
                const float itemSpacing = 17f;

                float topItem       = topLine - 4f;
                float bottomItem    = bottomLine - 10f;
                float contentHeight = bottomItem - topItem;

                float maxVisibleItemsFloat = (contentHeight / itemSpacing);
                maxVisibleItems = (int)maxVisibleItemsFloat;

                float currentItem = topItem + itemSpacing + (maxVisibleItemsFloat - maxVisibleItems) * 0.5f * itemSpacing;


                // ToDo: ...
                float column2 = device.TargetSize.X * 0.55f;
                float sx      = column2 * 1.52f;
                float column1 = column2 * 0.36f + view.X;
                column2 *= 1.1f;

                for (int i = 0; i < maxVisibleItems; i++)
                {
                    int idx = i + scrollOffset;
                    if (idx >= levelList.Count)
                    {
                        break;
                    }

                    if (selectedIndex == idx)
                    {
                        charOffset = 0;

                        float xMultiplier = levelList[idx].DisplayName.Length * 0.5f;
                        float easing      = Ease.OutElastic(animation);
                        float x           = column1 + xMultiplier - easing * xMultiplier;
                        float size        = 0.7f + easing * 0.12f;

                        // Column 2
                        api.DrawStringShadow(ref charOffset, levelList[idx].LevelName, column2, currentItem, Alignment.Left,
                                             new ColorRgba(0.48f, 0.5f), 0.8f, 0.4f, 1f, 1f, 8f, charSpacing: 0.88f);

                        // Column 1
                        api.DrawStringShadow(ref charOffset, levelList[idx].DisplayName, x, currentItem, Alignment.Left,
                                             null, size, 0.4f, 1f, 1f, 8f, charSpacing: 0.88f);

                        // Column 0
                        api.DrawStringShadow(ref charOffset, levelList[idx].Icon, column1 - 16f, currentItem, Alignment.Right,
                                             new ColorRgba(0.48f, 0.5f), size, 0.4f, 1f, 1f, 8f, charSpacing: 0.68f);
                    }
                    else
                    {
                        // Column 2
                        api.DrawString(ref charOffset, levelList[idx].LevelName, column2, currentItem, Alignment.Left,
                                       ColorRgba.TransparentBlack, 0.7f);

                        // Column 1
                        api.DrawString(ref charOffset, levelList[idx].DisplayName, column1, currentItem, Alignment.Left,
                                       ColorRgba.TransparentBlack, 0.7f);

                        // Column 0
                        api.DrawString(ref charOffset, levelList[idx].Icon, column1 - 16f, currentItem, Alignment.Right,
                                       ColorRgba.TransparentBlack, 0.7f, charSpacing: 0.7f);
                    }

                    currentItem += itemSpacing;
                }

                // Scrollbar
                if (levelList.Count > maxVisibleItems)
                {
                    const float sw = 3f;
                    float       sy = ((float)scrollOffset / levelList.Count) * 18f * maxVisibleItems + topLine;
                    float       sh = ((float)maxVisibleItems / levelList.Count) * 16f * maxVisibleItems;

                    BatchInfo mat1 = device.RentMaterial();
                    mat1.Technique = DrawTechnique.Alpha;
                    mat1.MainColor = new ColorRgba(0f, 0f, 0f, 0.28f);
                    canvas.State.SetMaterial(mat1);
                    canvas.FillRect(sx + 1f, sy + 1f, sw, sh);

                    BatchInfo mat2 = device.RentMaterial();
                    mat2.Technique = DrawTechnique.Alpha;
                    mat2.MainColor = new ColorRgba(0.8f, 0.8f, 0.8f, 0.5f);
                    canvas.State.SetMaterial(mat2);
                    canvas.FillRect(sx, sy, sw, sh);
                }

                // Loading
                if (isLoadingAnimation > 0f)
                {
                    if (!isLoading)
                    {
                        isLoadingAnimation -= Time.TimeMult * 0.03f;
                    }
                    else
                    {
                        isLoadingAnimation = 1f;
                    }

                    float loadingX = center.X - 50f;
                    float loadingY = center.Y;

                    float startAngle = (float)(Time.GameTimer.TotalSeconds * 6.0f);

                    float time    = (float)(Time.GameTimer.TotalSeconds * 1.3f) % 2f;
                    bool  reverse = (time >= 1f);
                    if (reverse)
                    {
                        time -= 1f;
                    }
                    float timeCubed = MathF.Pow(time, 3);
                    float timeQuad  = MathF.Pow(time, 4);
                    float timeQuint = MathF.Pow(time, 5);

                    float endAngle;
                    if (reverse)
                    {
                        endAngle = startAngle + MathF.TwoPi * (1 - ((6 * timeQuint) + (-15 * timeQuad) + (10 * timeCubed)));
                    }
                    else
                    {
                        endAngle = startAngle + MathF.TwoPi * ((6 * timeQuint) + (-15 * timeQuad) + (10 * timeCubed));
                    }

                    const float r1 = 7f;
                    const float r2 = r1 - 0.4f;
                    const float r3 = r2 - 0.4f;
                    const float r4 = r3 - 0.4f;

                    api.DrawMaterial("MenuDim", loadingX + 50f, loadingY, Alignment.Center, new ColorRgba(1f, 0.7f * isLoadingAnimation), 40f, 10f);

                    BatchInfo mat1 = device.RentMaterial();
                    mat1.Technique = DrawTechnique.Alpha;
                    mat1.MainColor = new ColorRgba(0f, 0.2f * isLoadingAnimation);
                    canvas.State.SetMaterial(mat1);
                    canvas.DrawCircleSegment(loadingX + 1.6f, loadingY + 1.6f, r1, startAngle, endAngle);
                    canvas.DrawCircleSegment(loadingX + 1.6f, loadingY + 1.6f, r2, startAngle, endAngle);
                    canvas.DrawCircleSegment(loadingX + 1.6f, loadingY + 1.6f, r3, startAngle, endAngle);
                    canvas.DrawCircleSegment(loadingX + 1.6f, loadingY + 1.6f, r4, startAngle, endAngle);

                    BatchInfo mat2 = device.RentMaterial();
                    mat2.Technique = DrawTechnique.Alpha;
                    mat2.MainColor = new ColorRgba(0.95f, 0.8f * isLoadingAnimation);
                    canvas.State.SetMaterial(mat2);
                    canvas.DrawCircleSegment(loadingX, loadingY, r1, startAngle, endAngle);
                    canvas.DrawCircleSegment(loadingX, loadingY, r2, startAngle, endAngle);
                    canvas.DrawCircleSegment(loadingX, loadingY, r3, startAngle, endAngle);
                    canvas.DrawCircleSegment(loadingX, loadingY, r4, startAngle, endAngle);

                    api.DrawStringShadow(ref charOffset, "loading".T(), loadingX + r1 + 10f, loadingY + 2f, Alignment.Left,
                                         new ColorRgba(0.48f, 0.5f * isLoadingAnimation), 0.8f, 0.4f, 0.6f, 0.6f, 8f, charSpacing: 0.88f);
                }
            }
            else
            {
                api.DrawStringShadow(ref charOffset, "menu/play custom/single/empty".T(), center.X, center.Y, Alignment.Center,
                                     new ColorRgba(0.62f, 0.44f, 0.34f, 0.5f), 0.9f, 0.4f, 0.6f, 0.6f, 8f, charSpacing: 0.88f);
            }

            api.DrawMaterial("MenuLine", 0, center.X, topLine, Alignment.Center, ColorRgba.White, 1.6f);
            api.DrawMaterial("MenuLine", 1, center.X, bottomLine, Alignment.Center, ColorRgba.White, 1.6f);
        }
Exemplo n.º 3
0
        protected override void OnFixedUpdate(float timeMult)
        {
            collisions.Clear();

            api.FindCollisionActorsByAABB(this, AABBInner, ResolveCollisions);

            Vector3 pos = Transform.Pos;

            bool found = false;

            foreach (ActorBase collision in collisions)
            {
                // ToDo: This code only works with one player
                Player player = collision as Player;
                if (player != null)
                {
                    if (player != lastPlayer)
                    {
                        if (player.Speed.Y < -0.5f)
                        {
                            continue;
                        }

                        lastPlayer = player;
                    }

                    found = true;
                    Vector3 coords = player.Transform.Pos;
                    int     length = bridgePieces.Count;

                    // This marks which bridge piece is under the player and should be positioned
                    // lower than any other piece of the bridge.
                    float lowest = (coords.X - pos.X) / (bridgeWidth * 16f) * length;

                    // This marks the maximum drop in height.
                    // At the middle of the bridge, this is purely the height factor,
                    // which is simply (16 - bridge toughness) multiplied by the length of the bridge.
                    // At other points, the height is scaled by an (arbitrarily chosen) power that
                    // gives a nice curve.
                    // Additionally, the drop is reduced based on the player position so that the
                    // bridge seems to bend somewhat realistically instead of snapping from one position
                    // to another.
                    float drop = Math.Max(0, Math.Min(coords.Y - pos.Y + 32, (1f - MathF.Pow(Math.Abs(2f * lowest / length - 1f), 0.8f)) * heightFactor));

                    pos.Y = Math.Min(originalY + drop, Math.Max(originalY, coords.Y));

                    Transform.Pos = pos;

                    // Update the position of each bridge piece.
                    for (int j = 0; j < length; ++j)
                    {
                        Piece piece = bridgePieces[j];
                        coords = piece.Transform.Pos;

                        if (lowest > 0 && lowest < length)
                        {
                            float dropPiece;
                            if (j <= lowest)
                            {
                                dropPiece = MathF.Pow(j / lowest, 0.6f) * drop;

                                piece.Transform.Angle = dropPiece * 0.006f;
                            }
                            else
                            {
                                dropPiece = MathF.Pow((length - 1 - j) / (length - 1 - lowest), 0.6f) * drop;

                                piece.Transform.Angle = -dropPiece * 0.006f;
                            }
                            coords.Y = originalY + dropPiece;
                        }
                        else
                        {
                            coords.Y = originalY;

                            piece.Transform.Angle = 0f;
                        }

                        piece.Transform.Pos = coords;
                    }
                }
            }

            if (!found)
            {
                // The player was not touching the bridge, so reset all pieces to the default height.
                for (int j = 0; j < bridgePieces.Count; ++j)
                {
                    Vector3 coords = bridgePieces[j].Transform.Pos;
                    coords.Y = originalY;
                    bridgePieces[j].Transform.Pos   = coords;
                    bridgePieces[j].Transform.Angle = 0f;
                }

                pos.Y         = originalY;
                Transform.Pos = pos;

                lastPlayer = null;
            }
        }