/// <summary> /// Inserts a new row at the bottom. This also moves all rows up. /// The row placed is always safe row wise which means that they will not /// clear itself partially once placed. Optionally the same can be enabled /// for rows which is used to fill the initial space. /// </summary> public void InsertNewRow(bool safeColumns) { Color4 lastColor; int consecutiveBlocks = 0; MoveRowsUp(); for (int column = 0; column < Columns; column++) { GameBlock newBlock = GetRandomBlock(); while ((newBlock.Color == lastColor && consecutiveBlocks >= 1) || (safeColumns && !this[column, 1].Empty && newBlock.Color == this[column, 1].Block.Color)) { newBlock = GetRandomBlock(); } if (newBlock.Color == lastColor) { consecutiveBlocks++; } else { lastColor = newBlock.Color; consecutiveBlocks = 0; } this[column, 0].Block = newBlock; } // no point in clearing if safe columns are in use. We never generate a // pattern in rows that could be cleared anyways, and if safe columns are // enabled we also won't create patterns that can be cleared the other // way round. if (!safeColumns) { TryClear(); } }
public GameBlockAnimation(GameBlock block, GamePane pane, int column, int row) { this.block = block; this.pane = pane; this.column = column; this.row = row; }
public GameBlockExplosionAnimation(GameBlock block, GamePane pane, int column, int row) : base(block, pane, column, row) { scale = 1.0f; rotation = 0.0f; alpha = 1.0f; yOff = 0.0f; }
/// <summary> /// Clears the block and makes it explode. /// </summary> public void Explode() { if (Empty) { return; } pane.AddAnimation(new GameBlockExplosionAnimation(block, pane, column, row)); block = null; }
/// <summary> /// Clears the block and makes it dissolve. /// </summary> public void Clear() { if (Empty) { return; } pane.AddAnimation(new GameBlockDissolveAnimation(block, pane, column, row)); block = null; }
/// <summary> /// Internal helper for swapping. /// </summary> private GameBlockState SwapContentsWith(GameBlockState other) { GameBlockState clone = (GameBlockState)MemberwiseClone(); block = other.block; other.block = clone.block; jiggle = other.jiggle; other.jiggle = clone.jiggle; return(clone); }
public GameBlockState(GamePane pane, int column, int row, float jiggle) { this.block = null; this.pane = pane; this.column = column; this.row = row; this.jiggle = jiggle; this.animationStep = -1.0f; this.animationSpeedFactor = 1.0f; }
/// <summary> /// Drops a new hard line onto the game field and applies gravity. /// </summary> public void DropHardLine() { int topRow = Rows - 1; GameBlock hardBlock = hardBlocks[rnd.Next() % hardBlocks.Length]; for (int column = 0; column < Columns; column++) { this[column, topRow].Block = hardBlock; } TryClear(); }
public GamePane(GameSession session, GameBlock[] regularBlocks, GameBlock[] hardBlocks, float posX, float posY) { this.session = session; this.regularBlocks = regularBlocks; this.hardBlocks = hardBlocks; this.rnd = new Random(session.Game.Random.Next()); grid = new GameBlockState[Columns, Rows]; position = new Vector2(posX, posY); jitter = 0.0f; scrollY = 0.0f; scrollSpeed = DefaultScrollSpeed; cursorColumn = 0; cursorRow = 1; cursorTexture = regularBlocks[0].Texture; activeAnimations = new HashSet<GameBlockAnimation>(); for (int column = 0; column < Columns; column++) for (int row = 0; row < Rows; row++) grid[column, row] = new GameBlockState(this, column, row, (float)rnd.NextDouble()); PopulateWithRandomBlocks(7); }
public GameBlockDissolveAnimation(GameBlock block, GamePane pane, int column, int row) : base(block, pane, column, row) { this.scale = 1.0f; this.rotation = 0.0f; }
/// <summary> /// Explodes this hard block and replaces it with a new soft block. /// </summary> public void MakeSoftBlock() { Debug.Assert(Hard, "can only make hard blocks soft"); pane.AddAnimation(new GameBlockExplosionAnimation(block, pane, Column, Row)); block = pane.GetRandomBlock(); }
/// <summary> /// Internal helper for swapping. /// </summary> private GameBlockState SwapContentsWith(GameBlockState other) { GameBlockState clone = (GameBlockState)MemberwiseClone(); block = other.block; other.block = clone.block; jiggle = other.jiggle; other.jiggle = clone.jiggle; return clone; }
/// <summary> /// Clears the block and makes it explode. /// </summary> public void Explode() { if (Empty) return; pane.AddAnimation(new GameBlockExplosionAnimation(block, pane, column, row)); block = null; }
/// <summary> /// Clears the block and makes it dissolve. /// </summary> public void Clear() { if (Empty) return; pane.AddAnimation(new GameBlockDissolveAnimation(block, pane, column, row)); block = null; }