// Calculates perpendicular bubbles public static DataPoint[] DetermineSplits(DataBubble bubble, DataPoint lineStart, DataPoint lineEnd) { BubbleType type = bubble.TypeOfBubble(); if (type == BubbleType.Large) { float yDiff = lineEnd.Y - lineStart.Y; float xDiff = lineEnd.X - lineStart.X; // Normally, a slope is y/x. Perpendicular is -x/y. float mPerp = -(xDiff / yDiff); // We need to figure out the angle to calculate the X offset required for getting us to this radius via the function y = mPerp(X). // v Angle C // /| // / | // side b -> / | <- Side a // (radius) / | // / | // / _| // angle A -> .____|_| <- Angle B (90 deg) // ^ side c float B = Mathf.Deg2Rad * 90f; float A = Mathf.Atan(mPerp); float C = (Mathf.Deg2Rad * 180) - A - B; float b = bubble.RawRadius(); float a = b * Mathf.Sin(A) / Mathf.Sin(B); // This is the Y offset float c = b * Mathf.Sin(C) / Mathf.Sin(B); // This is the X offset DataPoint start = bubble.GetPosition(); DataPoint b1 = new DataPoint(start.X + c, start.Y + a); DataPoint b2 = new DataPoint(start.X - c, start.Y - a); return(new DataPoint[] { b1, b2 }); } return(null); }
public VisualBubble CreateBubble(DataBubble data) { BubbleType type = data.TypeOfBubble(); string name = $"bubble {data.TypeOfBubble()}"; GameObject toSpawn = bubbleStandard; if (type == BubbleType.Large) { toSpawn = bubbleLarge; } GameObject bubble = Instantiate(toSpawn, this.transform); VisualRemoveBubbleOnMenu vrbm = bubble.GetComponent <VisualRemoveBubbleOnMenu>(); if (vrbm != null) { vrbm.events = events; } bubble.SetActive(true); bubble.name = name; bubble.transform.position = data.GetPosition(); return(new VisualBubble(bubble, data.GetPosition(), data.AdjustedRadius())); }
// Returns how much the score changed by private DataEarnedScore CollectBubblesAsNecessary(bool impactsScore = true) { List <DataPoint> locs = new List <DataPoint>(); List <int> collectedIndexes = new List <int>(); // Collect collisions for (int i = bubbles.Count - 1; i >= 0; --i) { DataBubble bubble = bubbles[i]; // Determine if we're hitting float triggerRadius = bubble.AdjustedRadius(); bool isHit = Utils.IsLineTouchingCircle(lastLineStart, lastLineEnd, bubble.GetPosition(), triggerRadius, bubbleRadiusStandard); if (isHit) { collectedIndexes.Add(i); locs.Add(bubble.GetPosition()); } } // Score updating int hit = collectedIndexes.Count; int scoreBase = GameCore.pointsPerBubble * hit; int scoreBonus = 0; if (hit > 0) { ++linesDrawn; } if (hit > bonusThreshold) { int bonusHits = hit - bonusThreshold; scoreBonus = bonusHits * bonusHits * pointsPerBonusBubble; } DataEarnedScore dataEarnedScore = new DataEarnedScore(scoreBase, scoreBonus, locs); if (pointsPerBubble != 0) { DataGeneral gen = data.GetDataGeneral(); gen.score = gen.score + dataEarnedScore.total; if (impactsScore) { data.SetDataGeneral(gen); } } // Clear colleted bubbles. The indexes are from back to front, so the removal is safe. foreach (int index in collectedIndexes) { DataBubble bubble = bubbles[index]; events.OnBubbleDestroyed?.Invoke(bubble.GetPosition()); bubbles.RemoveAt(index); DataPoint[] newBubbles = DetermineSplits(bubble, lastLineStart, lastLineEnd); if (newBubbles != null) { foreach (DataPoint point in newBubbles) { DataBubble newBubble = new DataBubble(point, new DataPoint(0, 0), speed: 0, BubbleType.Standard); bubbles.Add(newBubble); } } } return(dataEarnedScore); }