// Update is called once per frame void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.tag == "LeftWall") { collidedleft = true; collidedright = false; } if (other.gameObject.tag == "RightWall") { collidedright = true; collidedleft = false; } if (other.gameObject.tag == "Finish") { if (!playerController.Dead) { if (PlayerPrefs.GetInt("Sound", 1) == 1) { GameObject.Find("Candy").GetComponent <AudioSource>().Play(); } CandyScript.AddPoint(); gameObject.GetComponent <SpriteRenderer>().sprite = plusone; gameObject.GetComponent <Collider2D>().enabled = false; gameObject.transform.localScale = new Vector3(0.535423f, 0.535423f, 0.535423f); Invoke("MoveObject", 0.3f); } } }
// returns null if the system is considered "stable" // on the other hand, if settling is necessary, returns the // offending script after making one move towards a stable state public CandyScript SettleStep() { KeyValuePair <Vector2Int, Vector2Int> move = FindStablizingMove(); if (move.Key.x == -1) { return(null); } candy_grid[move.Value.x][move.Value.y] = candy_grid[move.Key.x][move.Key.y]; candy_grid[move.Key.x][move.Key.y] = null; CandyScript script = candy_grid[move.Value.x][move.Value.y]; float dx = new int[] { -1, 1 }[move.Value.y - move.Key.y + parity_map[move.Key.x]] *mainRadius; float dy = PolyPieceGenerator.CalculateVStackDistance(6, mainRadius); script.transform.position += new Vector3(dx, -dy, 0); CandyScriptIndex id = candy_indexer[script]; id.row = move.Value.x; id.column = move.Value.y; return(script); }
public int DestructTile(CandyScript script, int count, bool is_super) { switch (state) { case State.IDLE: { destruct_count = count; Debug.Assert(destruct_timer == 0); Debug.Assert(death_row.Count == 0); Debug.Assert(settled_candies.Count == 0); Debug.Assert(dedded.Count == 0); death_row.Add(script); this.is_super = is_super; player.Freeze(); candyManager.Freeze(); candyGen.Freeze(); state = this.is_super ? State.SUPER : State.GLOW; return(1 + candyManager.BFS(new List <CandyScript> { script }, cc => cc.colour == script.colour, -1).Count); } default: { return(0); } } }
public List <CandyScript> BFS(List <CandyScript> initial_queue, System.Func <CandyScript, bool> pred = null, int layers = -1) { HashSet <CandyScript> visited = new HashSet <CandyScript>(initial_queue); Queue <CandyScript> queue = new Queue <CandyScript>(initial_queue); while (queue.Count > 0 && layers != 0) { int layerSize = queue.Count; for (int i = 0; i < layerSize; ++i) { CandyScript cur = queue.Dequeue(); List <CandyScript> neighbours = FetchNeighbours(cur); foreach (CandyScript n in neighbours) { if (!visited.Contains(n) && (pred == null || pred(n))) { visited.Add(n); queue.Enqueue(n); } } } layers -= 1; } foreach (CandyScript c in initial_queue) { visited.Remove(c); } return(new List <CandyScript>(visited)); }
void GenerateRow(int row, float elapsedTimeInPeriod) { List <CandyScript> next_row = new List <CandyScript>(); candy_grid.Add(next_row); int row_index = candy_grid.Count - 1; parity_map.Add(next_row_parity); for (int i = 0; i < next_row_parity + cols; ++i) { GameObject candy = GameObject.Instantiate(candyPrefab); CandyScript script = candy.GetComponent <CandyScript>(); script.manager = this; candy.transform.position = GetGridPosition(row, i, next_row_parity); Vector3 velocity = GetVerticalVelocityByTimePeriod(risePeriod * riseRate); candy.transform.position += velocity * elapsedTimeInPeriod; next_row.Add(script); candy_indexer.Add(script, new CandyScriptIndex(row_index, i)); List <CandyScript> neighbours = FetchNeighbours(script); script.colour = GenerateColour(script, neighbours); ppGen.Generate(candy); } next_row_parity = (1 + next_row_parity) % 2; }
List <CandyScript> FetchNeighbours(CandyScript script) { CandyScriptIndex id = candy_indexer[script]; int x = id.column; int y = id.row; int p = parity_map[y]; List <Vector2Int> neighbour_indices = new List <Vector2Int>(); List <CandyScript> neighbours = new List <CandyScript>(); if (p == 1) { if (id.column != 0) { neighbour_indices.Add(new Vector2Int(x - 1, y)); neighbour_indices.Add(new Vector2Int(x - 1, y + 1)); neighbour_indices.Add(new Vector2Int(x - 1, y - 1)); } if (id.column != cols) { neighbour_indices.Add(new Vector2Int(x + 1, y)); neighbour_indices.Add(new Vector2Int(x, y + 1)); neighbour_indices.Add(new Vector2Int(x, y - 1)); } } else { neighbour_indices.Add(new Vector2Int(x + 1, y + 1)); neighbour_indices.Add(new Vector2Int(x + 1, y - 1)); neighbour_indices.Add(new Vector2Int(x, y + 1)); neighbour_indices.Add(new Vector2Int(x, y - 1)); if (id.column != 0) { neighbour_indices.Add(new Vector2Int(x - 1, y)); } if (id.column != cols - 1) { neighbour_indices.Add(new Vector2Int(x + 1, y)); } } foreach (Vector2Int ni in neighbour_indices) { Vector2Int gc = ConvertToGridIndices(ni); CandyScript neighbour = SafeGridFetch(gc.x, gc.y); if (neighbour != null) { neighbours.Add(neighbour); } } return(neighbours); }
// a candy is stable if either: // - it's on the bottom row // - it has two blocks supporting it // - it is of odd parity and on an edge, with 1 block supporting it bool IsStable(CandyScript c) { CandyScriptIndex id = candy_indexer[c]; return((id.row == candy_grid.Count - 1) || (parity_map[id.row] == 0 && // even parity (SafeGridFetch(id.row + 1, id.column) != null && SafeGridFetch(id.row + 1, id.column + 1) != null)) // has 2 under it || (parity_map[id.row] == 1 && // odd parity (SafeGridFetch(id.row + 1, id.column) != null && SafeGridFetch(id.row + 1, id.column - 1) != null) || // has 2 under it ((id.column == 0 || id.column == cols) && // is an edge piece (SafeGridFetch(id.row + 1, id.column) != null || SafeGridFetch(id.row + 1, id.column - 1) != null)) )); // one supporting piece }
void SuperExplodeTiles() { Debug.Assert(death_row.Count == 1); CandyScript c = death_row[0]; death_row.Clear(); // insta-kill List <CandyScript> flooded = candyManager.BFS(new List <CandyScript> { c }, cc => cc.colour == c.colour, -1); foreach (CandyScript cc in flooded) { cc.isDead = true; } c.isDead = true; SpawnComboText(flooded.Count + 1); }
CandyScript.Colour GenerateColour(CandyScript script, List <CandyScript> neighbours) { Dictionary <CandyScript.Colour, float> matrix = new Dictionary <CandyScript.Colour, float>(); List <CandyScript.Colour> colours = new List <CandyScript.Colour> { CandyScript.Colour.RED, CandyScript.Colour.BLUE, CandyScript.Colour.GREEN }; foreach (CandyScript.Colour colour in colours) { List <CandyScript> matching = new List <CandyScript>(); foreach (CandyScript n in neighbours) { if (n.colour == colour) { matching.Add(n); } } List <CandyScript> res = BFS(matching, c => c.colour == colour); matrix[colour] = Mathf.Pow(chainLengthProbabilityDecay, res.Count); } return(CalculateGeneratedColor(matrix)); }
// Update is called once per frame void Update() { switch (state) { case State.IDLE: { break; } case State.SUPER: { SuperExplodeTiles(); destruct_timer = perChainBlockDestructionTime; state = State.SETTLE; break; } case State.GLOW: { if (destruct_count == 0 || death_row.Count == 0) { destruct_timer = perChainBlockDestructionTime; death_row.Clear(); state = State.WAIT_GLOW; break; } if (destruct_timer <= 0) { --destruct_count; destruct_timer += perChainBlockDestructionTime; GlowNextTiles(); } destruct_timer -= Time.deltaTime; break; } case State.WAIT_GLOW: { bool done_glow = true; foreach (CandyScript c in dedded) { if (c.GetState() == CandyScript.State.GLOW && !c.IsAnimComplete()) { done_glow = false; break; } } if (done_glow) { foreach (CandyScript c in dedded) { c.isDead = true; } SpawnComboText(dedded.Count); dedded.Clear(); state = State.SETTLE; } break; } case State.SETTLE: { if (destruct_timer <= 0) { CandyScript settled = candyManager.SettleStep(); if (settled == null) { destruct_timer = 0; state = State.SUPER_CHAIN; break; } settled.PlaySettleSound(); settled_candies.Add(settled); destruct_timer += perChainBlockDestructionTime; } destruct_timer -= Time.deltaTime; break; } case State.SUPER_CHAIN: { if (is_super) { foreach (CandyScript s in settled_candies) { death_row.Add(s); } destruct_count = 1000; // you're God-like :) is_super = false; state = State.GLOW; } else { player.Unfreeze(); candyManager.Unfreeze(); candyGen.Unfreeze(); state = State.IDLE; } settled_candies.Clear(); break; } } }