protected override void UpdateScreen(GameTime gameTime, DisplayOrientation screenOrientation) { //the food meter is constantly decreasing, even when not moving. It decreases faster when moving. //level.Play(); if (!gameOver) { //death timer if (timerStarted) { deathTimer.Tick(true); } else { deathTimer.SetTimer(0, 0, DOOM_TIME); } //start playing music if (MediaPlayer.GameHasControl && !musicIsPlaying) { MediaPlayer.Play(gameMusic); MediaPlayer.IsRepeating = true; musicIsPlaying = true; } //check for player effects player.ReduceTimer(); if (player.EffectEnded) { player.SetMod(0); } //display food value number if (foodValueDisplayed) { foodValuePos.Y -= 1; float distance = (foodValuePos.Y - player.Position().Y) * (foodValuePos.Y - player.Position().Y); if (distance > 3000) { foodValueDisplayed = false; } } if (levelUpDisplayed) { levelUpMsgPos.Y -= 1; float dist = (levelUpMsgPos.Y - player.Position().Y) * (levelUpMsgPos.Y - player.Position().Y); if (dist > 6000) { levelUpDisplayed = false; } } if (foodList.Count != DROP_LIMIT) { dropTimer += 0.1f; int foodX = foodPos.Next(Screen.ScreenWidth - 30); if (dropTimer > MAX_TIMER) { dropTimer = 0; foodItem = foodManager.GenerateFood(new Vector2(foodX, -50)); foodList.Add(foodItem); } } if (BackButtonPressed()) { //reset game Reset(); //stop music if (MediaPlayer.GameHasControl) { MediaPlayer.Stop(); } } //jump button action if (input.IsPressed(jumpButtonPressed) && !playerIsJumping) { playerIsJumping = true; vy -= JUMP_VEL; } //foodItem.ActivateSpecial(player); if (input.IsPressed(screenTapped)) { //set the tapped location. The tapped location uses a circle to indicate where the creature is moving. tapLocation.X = input.CurrentGesturePosition(screenTapped).X; tapLocation.Y = input.CurrentGesturePosition(screenTapped).Y; friction = 1; playerIsMoving = true; } //update player position float playerX = player.Position().X; if (playerIsMoving) { //increase food meter burn rate foodMeter.SetCurrentRate(1.0f); friction = 1; float distance = (tapLocation.X - playerX) * (tapLocation.X - playerX); //(x2 - x1)^2 //move player to touch location. if (playerX <= tapLocation.X) { if (distance > MAX_DISTANCE) { vx = PLAYER_TURBO_SPEED + player.MoveMod(); foodMeter.SetCurrentRate(1.5f); } else { vx = PLAYER_MOVE_SPEED + player.MoveMod(); } } else if (playerX > tapLocation.X) { if (distance > MAX_DISTANCE) { vx = -PLAYER_TURBO_SPEED - player.MoveMod(); foodMeter.SetCurrentRate(1.5f); } else { vx = -PLAYER_MOVE_SPEED - player.MoveMod(); } } //TODO: Figure out how to prevent player from moving in opposite direction when tapping //on same point as player's current position. //slow down player when minimum distance is reached playerIsMoving = (distance <= MIN_DISTANCE) ? false : true; } else { foodMeter.SetCurrentRate(0); friction = FRICTION; } //apply gravity to objects vx *= friction; foodVy = FOOD_DROP_SPEED + GRAVITY; //only apply gravity when airborne if (playerIsJumping) { vy += GRAVITY; } //drop food foreach (Food f in foodList) { float y = f.Position().Y + foodVy; if (y > GROUND_HEIGHT + f.FoodImage().Height) { y = GROUND_HEIGHT + f.FoodImage().Height; f.Countdown(); //decays only when on the ground } f.SetPosition(new Vector2(f.Position().X, y)); if (f.IsDecayed()) //remove item if decayed { trashCan.Add(f); } //collision checking else if (player.Collides(f)) { //play sound soundEffects.PlaySound(@"Sounds/foodpickup"); //destroy food and add its value to the meter foodMeter.IncreaseMeter(f.FoodValue()); foodValueDisplayed = true; foodValuePos = new Vector2(player.Position().X, player.Position().Y - 25); foodValue = f.FoodValue(); effectMsg = f.EffectMessage(); f.ActivateSpecial(player); //use any special abilities on player. lastItemPickup = f.FoodName() + " " + f.FoodValue().ToString() + "pts."; lastItemImg = f.FoodImage(); trashCan.Add(f); //Debug.WriteLine("Collided with food " + foodList.IndexOf(f)); } } playerX += vx; //boundary check if (playerX + playerImg.Width > Screen.ScreenWidth) { playerX = Screen.ScreenWidth - playerImg.Width; } float playerY = player.Position().Y + vy; //check Y if (playerY > GROUND_HEIGHT) { playerY = GROUND_HEIGHT; vy = 0; playerIsJumping = false; } player.SetPosition(new Vector2(playerX, playerY)); foodMeter.Update(); //check lose conditions if (foodMeter.CapacityExceeded() && !timerStarted) { //start timer timerStarted = true; } if (!foodMeter.CapacityExceeded() && timerStarted) { //this should occur if at some point the player is not over capacity but didn't complete the level //while the death timer was counting down. timerStarted = false; deathTimer.SetTimer(0, 0, DOOM_TIME); } if (foodMeter.IsEmpty() || deathTimer.TimeUp()) //don't let this happen! { deathTimer.SetMilliseconds(0); //this is here so that the player isn't fooled into thinking they had more time remaining. gameOver = true; } //check win condition else if (foodMeter.LevelWon()) { levelUpMsg = "Capacity Clear! Level +1"; //raise level and change the capacity marker. levelNum++; timerStarted = false; deathTimer.SetTimer(0, 0, DOOM_TIME); foodMeter.ResetMeter(); if (foodMeter.MarkerAtMinCapacity()) { //every time the level is beaten with the marker at min capacity, its position is reduced and //the width is reset. This increases the challenge over time, because the player is //more likely to go over capacity and not be able to recover without eating the right food. foodMeter.ResetCapacity(); levelUpMsg += "\nMarker Position Change"; foodMeter.ChangeMarkerPosition(-20); } else { foodMeter.DecreaseCapacity(10); } levelUpDisplayed = true; levelUpMsgPos = new Vector2(200, player.Position().Y - 20); } //garbage cleanup foreach (Food f in trashCan) { foodList.Remove(f); } base.UpdateScreen(gameTime, screenOrientation); } else { Die(); //if we're here, then game is over. Set a timer before being kicked back to title screen. gameOverTimer.Tick(true); if (gameOverTimer.TimeUp()) { if (MediaPlayer.GameHasControl) { MediaPlayer.Stop(); } Reset(); changeScreenDelegate(ScreenState.Title); } } }