private void UpdateInvaders(UpdateParams uparams) { for (int i = mInvaders.Count - 1; i > -1; --i) { Invader entity = mInvaders[i]; entity.Update(uparams.Elapsed); if (entity.State != InvaderState.Alive) { mInvaders.RemoveAt(i); if (entity.State == InvaderState.MadeIt) { Player.InvaderGotThrough(entity); if (!Player.IsAlive) { GameOver = true; i = -1; } } else { Player.CollectSpoils(entity); } } } }
private void ProcessInput(UpdateParams uparams) { // if the user selects a group of cells if (uparams.Input.SelectObject) { // process the selection click OnSelectClick(uparams); } bool selectedPieceValid = mSelectedPiece != null && mSelectedPiece.Selected; if (uparams.Input.SellRequested && selectedPieceValid) { mSelectedPiece.Sell(); } if (uparams.Input.UpgradeRequested && selectedPieceValid) { mSelectedPiece.Upgrade(); } if (uparams.Input.ClearSelections) { lstPieces.SelectedIndex = -1; ClearSelection(); } if (uparams.Input.EctoplasTransmaterPort) { Player.TimeUntilInvadersArrive = TimeSpan.Zero; } }
private void OnSelectClick(UpdateParams uparams) { // ignore this function if the buttons have the mouse if (btnSell.MouseCaptured || btnUpgrade.MouseCaptured) { return; } // always clear the current selection ClearSelection(); // if the user has no selection, then select the piece if (lstPieces.SelectedIndex == -1) { // the piece is invalid. Find the piece that they clicked on. bool found = false; for (int i = 0; !found && i < mPieces.Count; ++i) { Piece piece = mPieces[i]; GsRectangle box = new GsRectangle(piece.Position + uparams.Offset, piece.Size); if (box.Contains(uparams.Input.CursorPosition)) { // set selection found = true; SetSelection(piece); } } } }
private Invader RetrieveCurrentSelectedInvader(UpdateParams uparams) { Invader retval = mSelectedInvader; if (retval != null && retval.State != InvaderState.Alive) { retval = null; } if (uparams.Input.SelectObject) { // if they click, then reset the selection retval = null; for (int i = mInvaders.Count - 1; i > -1; --i) { Invader invader = mInvaders[i]; if (invader.State == InvaderState.Alive) { GsRectangle box = invader.GetBoundingBox(uparams.Offset); if (box.Contains(uparams.Input.CursorPosition)) { retval = invader; i = -1; } } } } mSelectedInvader = retval; return(retval); }
private void UpdateSelection(UpdateParams uparams) { // the user has something selected in the list. Our goal is to show the user the // available places where their selection can be set. // update the current piece selection UpdatePiecePlacement(uparams); // update the flashing cells UpdateFlashingCells(uparams); }
private Piece RetrieveCurrentHoveredPiece(UpdateParams uparams) { Piece piece = null; if (lstPieces.HoverIndex > -1) { // set the hovered piece piece = lstPieces.Items[lstPieces.HoverIndex].Value as Piece; } return(piece); }
private void UpdateSelectionList(UpdateParams uparams) { // show the list and see if we can select a piece lstPieces.Visible = true; foreach (ListBoxItem item in lstPieces.Items) { Piece piece = item.Value as Piece; if (piece != null) { // this item can only be selected if the player has enough cash for it item.CanSelect = Player.EnoughCashFor(piece); } } }
private void UpdateSelectedPieceRadius(UpdateParams uparams) { Piece piece = RetrieveCurrentSelectedPiece(uparams); currentArea = GsRectangle.Empty; bool validPiece = (piece != null) && (piece.State == PieceState.Idle); if (validPiece && !piece.Size.IsEmpty) { float dx = piece.Width * .5f; float dy = piece.Height * .5f; currentArea = new GsRectangle(piece.X + dx, piece.Y + dy, piece.Radius, piece.Radius); } }
private void UpdateFlashingCells(UpdateParams uparams) { List <GridCell> keys = cellsToFlash.Keys.ToList(); foreach (GridCell cell in keys) { double amount = cellsToFlash[cell]; amount -= uparams.Elapsed.TotalSeconds; cellsToFlash[cell] = amount; if (amount <= 0) { // remove the cell so it doesn't get drawn OR updated cellsToFlash.Remove(cell); } } }
private void UpdateDescriptionText(UpdateParams uparams) { Piece piece = RetrieveCurrentInformationPiece(uparams); Invader invader = RetrieveCurrentSelectedInvader(uparams); txtDescription.Visible = false; btnSell.Visible = (piece != null & mSelectedPiece != null && mSelectedPiece.Equals(piece)); btnUpgrade.Visible = btnSell.Visible; btnUpgrade.Enabled = btnSell.Visible && piece.CanUpgrade; if (piece != null || invader != null) { txtDescription.Visible = true; ITextDisplay provider = (piece != null ? (ITextDisplay)piece : (ITextDisplay)invader); DisplayDescriptionForTextProvider(provider); DisplayCaptionForTextProvider(provider); } }
public void Update(GuiInputState state, TimeSpan span) { // update the visible pieces so they get updated right away UpdateVisiblePieces(); // immediately add the waves of invaders (if necessary) AddInvaders(); // update the gui mGui.Update(state, span); // construct new updata parameters for the functions UpdateParams uparams = new UpdateParams(span, InputProvider.GetState(), MiddleOffset + Position); // update the list UpdateSelectionList(uparams); // update the selection the user has made UpdateSelection(uparams); // process any requests from the user for a piece ProcessInput(uparams); // update the description text that is displayed UpdateDescriptionText(uparams); // update the radius around the selected piece UpdateSelectedPieceRadius(uparams); // update all pieces UpdatePieces(uparams); // update all invaliders UpdateInvaders(uparams); // update the piece targets UpdatePieceTargets(uparams); // update all projectiles UpdateProjectiles(uparams); // finally, update the time Player.TimeUntilInvadersArrive -= span; }
private Piece RetrieveCurrentSelectedPiece(UpdateParams uparams) { Piece piece = null; bool validSelection = lstPieces.SelectedIndex > -1 || mSelectedPiece != null; if (validSelection) { piece = mSelectedPiece; if (piece == null) { piece = lstPieces.Items[lstPieces.SelectedIndex].Value as Piece; if (mSelection != null) { piece.Bounds = mSelection.Bounds; } } } return(piece); }
private void UpdateProjectiles(UpdateParams uparams) { float dx = CellWidth * 2f; float dy = CellHeight * 2f; GsRectangle viewport = new GsRectangle(X - dx, Y - dy, Width + dx, Height + dy); for (int i = mProjectiles.Count - 1; i > -1; --i) { // get the projectile Projectile projectile = mProjectiles[i]; // update the projectile data projectile.Update(uparams.Elapsed); // get the polygon data GsPolygon polygon = projectile.GetHull(uparams.Offset); // if the projectile is still alive, check to see if it went out of bounds if (projectile.IsAlive) { bool projectileIntersectsWithBounds = viewport.IntersectsWith(projectile.Bounds); bool projectileInsideBounds = viewport.Contains(projectile.Bounds); projectile.IsAlive = projectile.StayAlive || (projectileInsideBounds || projectileIntersectsWithBounds); } // if the projectile is still alive, check to see if it hit anything if (projectile.IsAlive) { CheckCollisions(projectile, polygon, uparams); } // if the projectile is dead, then remove it from the list if (!projectile.IsAlive) { mProjectiles.RemoveAt(i); OnProjectileRemoved(projectile); } } }
private Piece RetrieveCurrentInformationPiece(UpdateParams uparams) { Piece retval = null; // The hovered piece information is NOT saved, so we only care about which // piece is being hovered over before displaying text. Note that the hovered piece will // take precendence over the selected invader. If an invader is selected, // and we hover over a piece, then the piece will display it's information. // once the player hovers out of the piece, the selected invader's information // will come back. Also note that the hovered piece takes precedence over the currently selected // piece. // get the piece that's currently being hovered over retval = RetrieveCurrentHoveredPiece(uparams); if (retval == null) { // if it's null, then get the selected piece retval = RetrieveCurrentSelectedPiece(uparams); } // return whichever piece. If this is null, it means no piece is hovered or selected return(retval); }
private void UpdatePieces(UpdateParams uparams) { bool resolve = false; for (int i = mPieces.Count - 1; i > -1; --i) { Piece piece = mPieces[i]; piece.Update(uparams.Elapsed); if (piece.State == PieceState.Sold) { // remove the piece mPieces.RemoveAt(i); // if the currently selected piece is this piece, then set it to null if (piece.Equals(mSelectedPiece)) { mSelectedPiece = null; } // if we remove a piece the grid needs to be re-solved resolve = true; } Projectile[] projectiles = piece.PopProjectiles(); if (piece.State == PieceState.Idle) { mProjectiles.AddRange(projectiles); } } if (resolve) { SolveGrid(); } }
private void UpdatePiecePlacement(UpdateParams uparams) { // set the chunk to null mSelection.Chunk = null; // don't place any towers if no towers are selected if (lstPieces.SelectedIndex == -1) { // end any edits that are in place mSelection.EndPlaceEdits(); return; } // get the mouse point GsVector mousePt = uparams.Input.CursorPosition - uparams.Offset; // get the current chunk Piece piece = lstPieces.Items[lstPieces.SelectedIndex].Value as Piece; int cellsNeeded = (int)piece.Grouping; float width = CellWidth * cellsNeeded; float height = CellHeight * cellsNeeded; // compute the data needed GsVector offset = GsVector.Zero; GsRectangle cursorBox = Calculator.CreateBoxAroundPoint(mousePt, offset, width, height); GridCell[] cells = GetCellsWithCenterContainedIn(Grid, cursorBox, offset); if (cells.Length > 0) { GsRectangle bounds = ComputeBounds(cells, CellWidth, CellHeight); mSelection.Chunk = new GridCellChunk { Bounds = bounds, Cells = cells, Valid = (cells.Length == (cellsNeeded * cellsNeeded)) && Array.TrueForAll <GridCell>(cells, GridCell.CellIsAvailable), }; } // set the bounds of the selection to be the bounds of the chunk mSelection.Bounds = GsRectangle.Empty; if (mSelection.Chunk != null) { mSelection.Bounds = mSelection.Chunk.Bounds; } // if the mouse is down and we haven't added any chunks, then make this the starting chunk if (uparams.Input.SelectPressed) { // if we don't have a starting chunk, then start it if (mSelection.StartingChunk == null) { mSelection.StartingChunk = mSelection.Chunk; } // clear the bounds mSelection.Bounds = GsRectangle.Empty; // get the starting chunk for easy access GridCellChunk startingChunk = mSelection.StartingChunk; // if the starting chunk is null, or invalid, then don't do this if (startingChunk != null && startingChunk.Valid) { // basically, we need to determine how many chunks to add to the chunks currently being // edited. We can do this by first determining where the cursor box is. If it is below us // (meaning the top of the cursor box is greater than the bottom of the starting chunk // box), then we just need to count and see how many cells away the [0,0] cell from the cursor // box is away from the starting chunk box. So, "int countNeeded = cellsAwayFromStartingBox - // (cellsAwayFromStartingBox % cellsNeeded". This will tell us how many cells we should collect // in each direction (horz and vert). Then, we divide that number by cellsNeeded to get the number // of chunks. Then, we simply assemble the chunks and add them to a collection. The same logic is // done if the cursor box is horizontally away. // clear away the chunks being edited mSelection.ClearEdits(); // figure out if the cursor is in the vert plane, or the horz plane var rect = startingChunk.Bounds; var center = rect.Location; center.X += rect.Width / 2; center.Y += rect.Height / 2; float dy = mousePt.Y - center.Y; float dx = mousePt.X - center.X; float aDy = Math.Abs(dy); float aDx = Math.Abs(dx); if (aDy > aDx) { // the difference in the y direction is greater. If dy > 0, this means that the cursor is BELOW the starting chunk. // If dy < 0, this means that the cursor is ABOVE the starting chunk. If dy == 0, then we don't care if (dy != 0) { AddChunksVert(offset, mousePt, cellsNeeded, dy < 0); } } else { // the difference in the x direction is greater. If dx > 0, this means that the cursor is RIGHT of the starting chunk. // If dx < 0, this means that the cursor is LEFT of the starting chunk. Again, dx == 0, we don't care if (dx != 0) { AddChunksHorz(offset, mousePt, cellsNeeded, dx < 0); } } // make sure that the chunk we're drawing is the starting chunk mSelection.Chunk = startingChunk; } } else { // if we have a starting chunk if (mSelection.StartingChunk != null) { // add all the towers foreach (GridCellChunk editedChunk in mSelection.Edits) { // see if we have enough funds bool enoughFunds = Player.EnoughCashFor(piece); // create a default invalid message string invalidMessage = enoughFunds ? "Cell(s) not available" : "Not enough funds"; // update the validity of the chunk editedChunk.Valid &= enoughFunds; // if the chunk is valid, then attempt to place it. if (editedChunk.Valid) { // build the piece in the location Piece tower = piece.BuildFromChunk(gridBounds, editedChunk); mPieces.Add(tower); // if we can't get through if (!AssertCanGetThrough(tower)) { // remove the piece int last = mPieces.Count - 1; tower.SellInstant(); mPieces.RemoveAt(last); // re-solve the grid SolveGrid(); // the piece is no longer valid editedChunk.Valid = false; // blocking invalidMessage = "Blocking Invaders"; } } if (!editedChunk.Valid) { // add a quick message //MessageComponent.AddMessage(invalidMessage, // Position + new GsVector((Width / 2f), (Height / 2f)), // 800, // true); // a chunk can be invalid if all the cells don't have towers. // Find any cells that have towers, and flash them red foreach (GridCell cell in editedChunk.Cells) { if (cell.IsWalkable) { // we use a dictionary so we don't add the same cell twice. We also // reset the time that the cell is flashing. cellsToFlash[cell] = SecondsToFlashCell; } } } } } mSelection.EndPlaceEdits(); } }
private void UpdatePieceTargets(UpdateParams uparams) { var offset = MiddleOffset + Position; mPieces.ForEach(piece => piece.ChooseTarget(mInvaders, offset)); }
private void CheckCollisions(Projectile projectile, GsPolygon projectilePolygon, UpdateParams uparams) { // if the projectile parent is null, then don't worry about it if (projectile.Parent == null) { return; } // cycle through all of the entities for (int i = mInvaders.Count - 1; i > -1; --i) { // get the entity Invader invader = mInvaders[i]; // if this invader isn't the type of invader that the projectile can hit, then keep going if (!projectile.CanHit(invader)) { continue; } // get the entity polygon GsPolygon entityPolygon = invader.GetHull(uparams.Offset); // let the entity and polygon know they were attacked if (entityPolygon.IntersectsWith(projectilePolygon)) { // let the projectile know it collided projectile.OnCollidedWithInvader(invader); // let the entity know it was attacked invader.OnAttackedByProjectile(projectile); } } }