//removes nodes from the snake public void shrinkSnake(int amount, GraphicsManager.Direction direction) { for (int i = 0; i < amount; i++) { if (positions.Count > 0 && positions.Count > Variables.minLength) { positions.RemoveAt(positions.Count - 1); snakeBody.RemoveAt(snakeBody.Count - 1); snakeBoxes.RemoveAt(snakeBoxes.Count - 1); directions.RemoveAt(directions.Count - 1); snakeBody[snakeBody.Count - 1] = GraphicsManager.Instance.getSnakeTexture(direction, GraphicsManager.SnakePart.tail); } } }
public void UpdateSnakePositions(KeyboardState kstate, GameTime gameTime, GraphicsDeviceManager graphics, bool doesIntersect, bool powerUp, bool powerDown) { //redraw all collision boxes UpdateSnakeBoxes(); //check pick up collisions if (powerUp) { if (Variables.fxOn && Variables.audioOn) { AudioManager.Instance.playPowerUp(); } powerUpSnake(); } if (powerDown) { if (Variables.fxOn && Variables.audioOn) { AudioManager.Instance.playPowerDown(); } powerDownSnake(); } noKeyPressed = true; bool allowTail = true; bool allowHead = true; bool shrinkMode = false; if (kstate.IsKeyDown(Keys.LeftShift)) { shrinkMode = true; noKeyPressed = false; } else if (kstate.IsKeyDown(Keys.W) || kstate.IsKeyDown(Keys.S) || kstate.IsKeyDown(Keys.A) || kstate.IsKeyDown(Keys.D)) { tailMoving = false; noKeyPressed = false; } if (noKeyPressed == true) { return; } if (positions.Count == Variables.maxLength) { allowHead = false; allowTail = false; } //if player is holding shift, shrink a node every n frames if (shrinkMode) { if (framesPassedTail < Variables.shrinkEveryNFrames) { framesPassedTail++; return; } else { framesPassedTail = 0; shrinkSnake(1, direction); if (Variables.audioOn && Variables.fxOn) { AudioManager.Instance.shrink.Play(); } return; } } //dont change any positions if the snake isnt moving if (!noKeyPressed) { if ((tailMoving && allowTail) || (!tailMoving && allowHead)) { //are we moving the head or the tail now? var head = positions[0]; var lastPreviousPosition = head; var lastPreviousDirection = direction; //move head or tail first if (!tailMoving) { //apply movement if (kstate.IsKeyDown(Keys.W)) { head.Y -= snakeSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; direction = GraphicsManager.Direction.up; noKeyPressed = false; } else if (kstate.IsKeyDown(Keys.S)) { head.Y += snakeSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; direction = GraphicsManager.Direction.down; noKeyPressed = false; } else if (kstate.IsKeyDown(Keys.A)) { head.X -= snakeSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; direction = GraphicsManager.Direction.left; } else if (kstate.IsKeyDown(Keys.D)) { head.X += snakeSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; direction = GraphicsManager.Direction.right; noKeyPressed = false; } } //record the head's movement previousPositions.Insert(0, lastPreviousPosition); previousDirections.Insert(0, lastPreviousDirection); //this stops the snake from moving out of the screen :) head.X = Math.Min(Math.Max(GraphicsManager.Instance.headUp.Width / 2, head.X), graphics.PreferredBackBufferWidth - GraphicsManager.Instance.headUp.Width / 2); head.Y = Math.Min(Math.Max(GraphicsManager.Instance.headUp.Height / 2, head.Y), graphics.PreferredBackBufferHeight - GraphicsManager.Instance.headUp.Height / 2); //check collision, if this move is allowed, store the position - if not, stay where we are! //now that we dont use obstacles anymore this if statement is obsolete if (doesIntersect) { snakeSpeed = snakeSpeed / Variables.slowdown; Console.WriteLine("Speed: " + snakeSpeed); if (direction == GraphicsManager.Direction.up) { head.Y += Variables.collisionModifier * snakeSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; } else if (direction == GraphicsManager.Direction.down) { head.Y -= Variables.collisionModifier * snakeSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; } else if (direction == GraphicsManager.Direction.left) { head.X += Variables.collisionModifier * snakeSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; } else if (direction == GraphicsManager.Direction.right) { head.X -= Variables.collisionModifier * snakeSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; } } //if the snake has slowed down, it gradually gets back to its max speed if (snakeSpeed < Variables.maxSpeed) { snakeSpeed++; } //save the new head and direction variables positions[0] = head; directions[0] = direction; ////set the correct orientation asset snakeBody[0] = GraphicsManager.Instance.getSnakeTexture(directions[0], GraphicsManager.SnakePart.head); snakeBody[snakeBody.Count - 1] = GraphicsManager.Instance.getSnakeTexture(directions[directions.Count - 1], GraphicsManager.SnakePart.tail); // loop through list, set positions for all nodes while incrementing positions for (int i = 1; i < positions.Count; i++) { //set position Vector2 temp = positions[i]; if (previousPositions.Count != 0 && previousPositions.Count > i * Variables.spacing) { temp = previousPositions.ToArray()[i * Variables.spacing]; } //store back in list positions[i] = temp; //update texture if (previousDirections.Count != 0 && previousDirections.Count > i * Variables.spacing) { if (i != positions.Count - 1) { snakeBody[i] = GraphicsManager.Instance.getSnakeTexture(previousDirections.ToArray()[i * Variables.spacing], GraphicsManager.SnakePart.body); } else if (i == positions.Count - 1) { snakeBody[i] = GraphicsManager.Instance.getSnakeTexture(previousDirections.ToArray()[i * Variables.spacing], GraphicsManager.SnakePart.tail); } directions[i] = previousDirections.ToArray()[i * Variables.spacing]; } } //if the snake is not at max length, add a new node every n frames if (framesPassedHead < Variables.growEveryNFrames) { framesPassedHead++; } else { framesPassedHead = 0; if (previousPositions.Count > Variables.spacing * positions.Count && positions.Count < Variables.maxLength) { Vector2 position = positions[positions.Count - 1]; growSnake(position); snakeLength++; if (Variables.audioOn && Variables.fxOn) { AudioManager.Instance.grow.Play(); } } } } //save the keyboard state so we can tell if keys can being held down etc previousKB = kstate; } }