private List <CirclePartType> randomPartTypes() { List <CirclePartType> partTypes = new List <CirclePartType>(); CirclePartType[] getCirclePartTypeArray() { CirclePartType[][] validPartTypes = new CirclePartType[][] { new CirclePartType[] { CirclePartType.x8, CirclePartType.x8 }, new CirclePartType[] { CirclePartType.x4 }, new CirclePartType[] { CirclePartType.x16, CirclePartType.x8, CirclePartType.x16 }, new CirclePartType[] { CirclePartType.x8, CirclePartType.x16, CirclePartType.x16 }, new CirclePartType[] { CirclePartType.x16, CirclePartType.x16, CirclePartType.x8 }, new CirclePartType[] { CirclePartType.x16, CirclePartType.x16, CirclePartType.x16, CirclePartType.x16 } }; //// circle part depends on game level //float chanceDelta = 100 / validPartTypes.Length; //int index = Range(0, validPartTypes.Length); //for (int i = 0; i < validPartTypes.Length; i++) { // float chance = chanceDelta; // int difference = index - i; // int differenceAbs = Mathf.Abs(difference); // if (difference > 0) chance = differenceAbs * chanceDelta; // else if (difference < 0) { // chance /= differenceAbs; // // add some delta to give more chance // float difficultyChanceDelta = gameController.score.level / 50f; // chance += Mathf.Clamp(difficultyChanceDelta, 0f, 15f); // (750+ level will give +16%) // } // int randomChance = Range(0, 100); // if (randomChance <= chance) index = i; //} return(validPartTypes.ElementAt(Range(0, validPartTypes.Length))); } for (int i = 0; i < 4; i++) { CirclePartType[] validType = getCirclePartTypeArray(); foreach (CirclePartType partType in validType) { partTypes.Add(partType); } } if (fillAmount == 100f && gameController.score.level > 0 && (gameController.score.level % 2) == 0) { fillAmount = Range(70f, 95f); } percentageCircleFill(ref partTypes, fillAmount); return(partTypes); }
private CirclePart circlePartPrefab(CirclePartType type) { if (type == CirclePartType.x4) { return(x4Prefab); } else if (type == CirclePartType.x8) { return(x8Prefab); } else if (type == CirclePartType.x16) { return(x16Prefab); } return(null); }
private void percentageCircleFill(ref List <CirclePartType> lst, float percentage) { float emptyAmount = 360f - percentage.map(0f, 100f, 0f, 360f); while (emptyAmount >= deltaPartCost) { IEnumerable <CirclePartType> partsToRemove = lst.Where(part => isTruePartType(part) && circlePartCost(part) <= emptyAmount); int partsToRemoveCount = partsToRemove.Count(); if (partsToRemoveCount == 0) { break; } CirclePartType partToRemove = partsToRemove.ElementAt(Range(0, partsToRemoveCount)); int partToRemoveIndex = lst.IndexOf(partToRemove); lst.Remove(partToRemove); // +100 emits fake circle part (get angle but dont create) lst.Insert(partToRemoveIndex, partToRemove + 100); emptyAmount -= circlePartCost(partToRemove); } }
private float circlePartCost(CirclePartType type) => (truePartValue(type) * deltaPartCost) * 2f;
private bool isTruePartType(CirclePartType type) => (int)type < 100;
private int truePartValue(CirclePartType type) => (int)type % 100;
private void prepareCircleParts() { parts.ForEach(part => Destroy(part.gameObject)); parts.Clear(); float angle = 0; List <CirclePartType> partTypes = randomPartTypes(); #region Spikes Difficulty int level = gameController.score.level; int spikesCount = 0; switch (level) { case int lvl when level <= 3: { spikesCount = 0; break; } case int lvl when level > 3 && level < 25: { spikesCount = Range(1, 3 + 1); break; } case int lvl when level >= 25: { spikesCount = Range(2, 4 + 1); break; } case int lvl when level >= 50: { spikesCount = Range(3, 5 + 1); break; } default: break; } int count = partTypes.Count(partType => isTruePartType(partType)); spikesCount = Mathf.Clamp(spikesCount, 0, (int)(count / 2f) - 1); if (count <= 5) { spikesCount = 1; } if (count >= 7) { partsReloadTime = 2.25f; } else { partsReloadTime = 1.5f; } #endregion int spikesSpawned = 0; for (int i = 0; i < partTypes.Count; i++) { CirclePartType partType = partTypes.ElementAt(i); if (i > 0) { CirclePartType previousPartType = partTypes.ElementAt(i - 1); int partTypeValue = truePartValue(partType); int previousPartTypeValue = truePartValue(previousPartType); // get true values of angle cost int difference = Mathf.Abs(partTypeValue - previousPartTypeValue); float differenceAngle = (difference * deltaPartCost); if (partTypeValue < previousPartTypeValue) { differenceAngle = -differenceAngle; } else if (partTypeValue == previousPartTypeValue) { differenceAngle = 0f; } angle += differenceAngle; } float radius = c2d.radius; float x = radius * Mathf.Cos(angle * Mathf.Deg2Rad); float y = radius * Mathf.Sin(angle * Mathf.Deg2Rad); Vector3 point = new Vector3(x, y, 0); CirclePart partPrefab = circlePartPrefab(partType); if (partPrefab != null) { CirclePart part = Instantiate(partPrefab, point, Quaternion.AngleAxis(angle, Vector3.forward)); part.transform.position = part.transform.position + transform.position; bool spawnSpike = false; if (spikesSpawned < spikesCount) { float chance = (i + 1) * (100f / partTypes.Count); if (Range(0f, 100f) <= chance) { spikesSpawned++; spawnSpike = true; } } part.setupCircle(this, spawnSpike ? CirclePart.CirclePartState.Spike : CirclePart.CirclePartState.Default); parts.Add(part); } angle += circlePartCost(partType); } }