/// <summary> /// Grabs a block from the currently selected stack. /// </summary> /// <param name="stack"></param> private void Grab() { // We only care if we can grab something if (currentStack == null || !CanGrab()) { return; } // Move everything up in the stack. Block topBlock = currentStack.TopBlock; for (int i = Constants.MaximumGrabCount - 1; i > 0; i--) { grabStack[i] = grabStack[i - 1]; } // Grab the top block and change its position grabStack[0] = topBlock; topBlock.IsMoving = false; topBlock.Vector = 0; topBlock.Mass = 0; // Remove the stack for processing currentStack.Remove(topBlock); // Fire the sound event BlockStackEventArgs args = new BlockStackEventArgs(); args.Stack = currentStack; args.Block = topBlock; Game.Sound.BlockGrabbed(this, args); // Save the last grab stack lastGrabStack = currentStack; }
/// <summary> /// Internal function to determine if the target is valid or /// not. /// </summary> private bool IsInvalidTarget(BlockStack srcStack, BlockStack destStack) { // Remove ourselves to take ourselves out of the calculation srcStack.Remove(this); try { // Make sure the destination is a ground block or an // immobile one, but nothing else Block dest = destStack.TopBlock; if (!Board.IsGroundBlock(dest) && !Board.IsImmobileBlock(dest)) { // Neither ground or immobile return(true); } // We need the distance to be 1 or less float dist = Math.Abs(srcStack.TopPosition - destStack.TopPosition); if (dist > 1) { // Too much to jump return(true); } // It is good return(false); } finally { // Put ourselves back srcStack.Add(this); } }
/// <summary> /// This event is used to handle jumping from one block to /// another. /// </summary> private void OnDirectionChanged( object sender, BlockStackEventArgs args) { // At the apex, we change our direction by moving to the // next stack as appropriate. Start by ignoring direction // 0 since that is an inplace jumping. if (direction == 0) { return; } // Get the destination stack Board board = Game.State.Board; BlockStack srcStack = board[X, Y]; BlockStack destStack = null; if (direction == 1) { destStack = board[X, Y - 1]; } else if (direction == 2) { destStack = board[X + 1, Y]; } else if (direction == 3) { destStack = board[X, Y + 1]; } else if (direction == 4) { destStack = board[X - 1, Y]; } // Make sure we are still a valid destination if (IsInvalidTarget(srcStack, destStack)) { // We want to reverse the direction, but stay in the // same stack because our destination became // invalid. This works because the code will show them // "bouncing" back. if (direction == 1) { direction = 3; } else if (direction == 2) { direction = 4; } else if (direction == 3) { direction = 1; } else if (direction == 4) { direction = 2; } // We are done srcStack.Add(this); return; } // Move this block to the next one srcStack.Remove(this); destStack.Add(this); // Change our coordinates if (direction == 1) { BottomPosition -= 4; Y--; } else if (direction == 2) { OffsetX -= 101; X++; } else if (direction == 3) { BottomPosition += 1; Y++; } else if (direction == 4) { OffsetX += 101; X--; } }
/// <summary> /// This function causes the prayer to jump and potentially /// move around the board. /// </summary> public void Jump() { // Reset the time timeUntilBounce = Entropy.NextDouble( Constants.MinimumCharacterBounce, Constants.MaximumCharacterBounce); // We want the characters to bounce around a bit, so // we randomly pick a direction to jump into. We get a // random number between 0 and 4: // 0 no change // 1 north // 2 east // 3 south // 4 west // Actually, 0 happens because of fallback direction = Entropy.Next(4) + 1; // East/West only // TODO Fix if (direction == 1 || direction == 3) { direction++; } // If we haven't been accepted, we don't move around if (!IsAccepted) { direction = 0; } // Do sanity checking on the bounds of the stage. If // we are on the end and we would have jumped off, set // the direction to "none" Board board = Game.State.Board; if (direction == 1 && Y == 0) { direction = 0; } else if (direction == 2 && X == board.Columns - 1) { direction = 0; } else if (direction == 3 && Y == board.Rows - 1) { direction = 0; } else if (direction == 4 && X == 0) { direction = 0; } // If we still non-zero, then get the appropriate // stacks BlockStack myStack = board[X, Y]; BlockStack destStack = myStack; if (direction > 0) { // Get the proper stack and make sure it is a // valid target if (direction == 1) { destStack = board[X, Y - 1]; } else if (direction == 2) { destStack = board[X + 1, Y]; } else if (direction == 3) { destStack = board[X, Y + 1]; } else if (direction == 4) { destStack = board[X - 1, Y]; } // We don't jump if the destination block isn't a // ground or immobile block. We also don't jump if // the difference in height is more than one. if (IsInvalidTarget(myStack, destStack)) { direction = 0; destStack = myStack; } } // Figure out the vector, we need a higher one if we // are jumping north and/or if the destination block // is higher. myStack.Remove(this); float myTop = myStack.TopPosition; float destTop = destStack.TopPosition; float vector = Constants.PrayerBounceVector; myStack.Add(this); if (direction == 1) { vector += Constants.PrayerBounceNorthVector; } if (destTop > myTop) { vector += Constants.PrayerBounceUpVector; } // Add a positive vector Vector += vector; }
/// <summary> /// Removes a bug from the list and triggers the events. /// </summary> public void Remove() { BlockStack.Remove(this); Game.State.Bugs.Remove(this); // TODO Trigger sound }
/// <summary> /// Internal function to determine if the target is valid or /// not. /// </summary> private bool IsInvalidTarget(BlockStack srcStack, BlockStack destStack) { // Remove ourselves to take ourselves out of the calculation srcStack.Remove(this); try { // Make sure the destination is a ground block or an // immobile one, but nothing else Block dest = destStack.TopBlock; if (!Board.IsGroundBlock(dest) && !Board.IsImmobileBlock(dest)) { // Neither ground or immobile return true; } // We need the distance to be 1 or less float dist = Math.Abs(srcStack.TopPosition - destStack.TopPosition); if (dist > 1) { // Too much to jump return true; } // It is good return false; } finally { // Put ourselves back srcStack.Add(this); } }