//accelerations ------------------------------------------------ public Character Attraction(Poles pole, Character player) { //Constants.ATTRACTION //pulled towards a pole if (player.Charge != 0 && pole.Charge == -(player.Charge)) { // calculate x,y distances between player and pole int xDis = pole.XPos - player.XPos + 70; int yDis = pole.YPos - player.YPos + Constants.TILE_HEIGHT; // find third side of triangle based on calculated distances double tDis = Math.Sqrt(Math.Pow(xDis, 2) + Math.Pow(yDis, 2)); // scale the distances based on the attraction factor double scale = Constants.ATTRACTION / tDis; // use scale and calculated distances to get how much the player accelerates double sX = Math.Abs((scale * xDis)); double sY = Math.Abs((scale * yDis)); // use calulated acceleration to change player's speed if (player.XPos > (pole.XPos + Constants.TILE_WIDTH)) { player.XSpeed -= (int)(sX); } else if ((player.XPos + Constants.TILE_WIDTH) < pole.XPos) { player.XSpeed += (int)(sX); } if (player.YPos > (pole.YPos + Constants.TILE_HEIGHT)) { player.YSpeed -= (int)(sY); } else if ((player.YPos + Constants.TILE_HEIGHT) < pole.YPos) { player.YSpeed += (int)(sY); } } return player; }
public List<Poles> SetPoles() { //AF- Adding positive poles to list for (int i = 0; i < Constants.ARRAYY; i++) { for (int j = 0; j < Constants.ARRAYX; j++) { if (position[i, j] == '+') { Poles p = new Poles(1, j * Constants.GRIDPOSITION, i * Constants.GRIDPOSITION); poles.Add(p); } } } //AF - Add negative Poles for (int i = 0; i < Constants.ARRAYY; i++) { for (int j = 0; j < Constants.ARRAYX; j++) { if (position[i, j] == '-') { Poles p = new Poles(-1, j * Constants.GRIDPOSITION, i * Constants.GRIDPOSITION); poles.Add(p); } } } return poles; }
//Create a method that will make the player orbit clockwise around the pole public void Orbit(Poles pole, Character player) { //Pole rectangle Rectangle poleRect = new Rectangle(pole.XPos, pole.YPos, Constants.TILE_WIDTH, Constants.TILE_HEIGHT); //Player rectangle Rectangle playerRect = new Rectangle(player.XPos, player.YPos, Constants.TILE_WIDTH, Constants.TILE_HEIGHT); //Calculate the center points of pole and player double centerOfPlayerX = (playerRect.Width / 2) + playerRect.X; double centerOfPlayerY = (playerRect.Height / 2) + playerRect.Y; double centerOfPoleX = (poleRect.Width / 2) + poleRect.X; double centerOfPoleY = (poleRect.Height / 2) + poleRect.Y; //Calculate the radius of the rotation if (counter == 0) { //When x and y are positive if (centerOfPlayerY > centerOfPoleY && centerOfPlayerX > centerOfPoleX) { //Use pyrathogram theorem radiusOfRotation = Math.Sqrt((Math.Pow((centerOfPlayerX - centerOfPoleX), 2) + Math.Pow((centerOfPlayerY - centerOfPoleY), 2))); } //When x is positve, but y is negative else if (centerOfPoleY > centerOfPlayerY && centerOfPlayerX > centerOfPoleX) { //Use pyrathogram theorem radiusOfRotation = Math.Sqrt((Math.Pow((centerOfPlayerX - centerOfPoleX), 2) + Math.Pow((centerOfPoleY - centerOfPlayerY), 2))); } //When x and y are negative else if (centerOfPoleY > centerOfPlayerY && centerOfPoleX > centerOfPlayerX) { //Use pyrathogram theorem radiusOfRotation = Math.Sqrt((Math.Pow((centerOfPoleX - centerOfPlayerX), 2) + Math.Pow((centerOfPoleY - centerOfPlayerY), 2))); } //When x is negative but y is positive else if (centerOfPlayerY > centerOfPoleY && centerOfPoleX > centerOfPlayerX) { //Use pyrathogram theorem radiusOfRotation = Math.Sqrt((Math.Pow((centerOfPoleX - centerOfPlayerX), 2) + Math.Pow((centerOfPlayerY - centerOfPoleY), 2))); } //Account for 90, 180, 270, 360 angle degrees //If 90 degrees else if (centerOfPlayerX == centerOfPoleX && centerOfPlayerY < centerOfPoleY) { //Use pyrathogram theorem radiusOfRotation = Math.Sqrt((Math.Pow((centerOfPoleX), 2) + Math.Pow((centerOfPoleY - centerOfPlayerY), 2))); } //If 180 degrees else if (centerOfPlayerY == centerOfPoleY && centerOfPlayerX < centerOfPoleX) { //Use pyrathogram theorem radiusOfRotation = Math.Sqrt((Math.Pow((centerOfPoleX - centerOfPlayerX), 2) + Math.Pow((centerOfPoleY), 2))); } //If 270 degrees else if (centerOfPlayerX == centerOfPoleX && centerOfPlayerY > centerOfPoleY) { //Use pyrathogram theorem radiusOfRotation = Math.Sqrt((Math.Pow((centerOfPoleX), 2) + Math.Pow((centerOfPlayerY - centerOfPoleY), 2))); } //If 360 degrees else if (centerOfPlayerY == centerOfPoleY && centerOfPlayerX > centerOfPoleX) { //Use pyrathogram theorem radiusOfRotation = Math.Sqrt((Math.Pow((centerOfPlayerX - centerOfPoleX), 2) + Math.Pow((centerOfPoleY), 2))); } } //Calculate the player's angle and set it player.Angle = Rotate(pole, player, Constants.ROTATION_SPEED); //Calculate the attractive force between player and pole to find the new x and y coordinates for the player double attractiveForceX = Math.Sin(player.Angle) * radiusOfRotation + centerOfPoleX; double attractiveForceY = Math.Cos(player.Angle) * radiusOfRotation + centerOfPoleY; //Set the new x and y coordinates of the player to the attractive force player.XPos = (int)attractiveForceX - playerRect.Width / 2; player.YPos = (int)attractiveForceY - playerRect.Height / 2; }
//Create a method that will make the player orbit counter clockwise around the pole public double Rotate(Poles pole, Character player, double angleChange) { //Pole rectangle Rectangle poleRect = new Rectangle(pole.XPos, pole.YPos, Constants.TILE_WIDTH, Constants.TILE_HEIGHT); //Player rectangle Rectangle playerRect = new Rectangle(player.XPos, player.YPos, Constants.TILE_WIDTH, Constants.TILE_HEIGHT); //Calculate the center points of pole and player double centerOfPlayerX = (playerRect.Width / 2) + playerRect.X; double centerOfPlayerY = (playerRect.Height / 2) + playerRect.Y; double centerOfPoleX = (poleRect.Width / 2) + poleRect.X; double centerOfPoleY = (poleRect.Height / 2) + poleRect.Y; //Calculate the angle for each quadrant only once if (counter == 0) { //When x and y are positive if (centerOfPlayerY > centerOfPoleY && centerOfPlayerX > centerOfPoleX) { //Calculate angle player.Angle = Math.Atan((centerOfPlayerY - centerOfPoleY) / (centerOfPlayerX - centerOfPoleX)); } //When x is positve, but y is negative else if (centerOfPoleY > centerOfPlayerY && centerOfPlayerX > centerOfPoleX) { player.Angle = Math.Atan((centerOfPoleY - centerOfPlayerY) / (centerOfPlayerX - centerOfPoleX)); } //When x and y are negative else if (centerOfPoleY > centerOfPlayerY && centerOfPoleX > centerOfPlayerX) { player.Angle = Math.Atan((centerOfPoleY - centerOfPlayerY) / (centerOfPoleX - centerOfPlayerX)); } //When x is negative but y is positive else if (centerOfPlayerY > centerOfPoleY && centerOfPoleX > centerOfPlayerX) { player.Angle = Math.Atan((centerOfPlayerY - centerOfPoleY) / (centerOfPoleX - centerOfPlayerX)); } //Account for 90, 180, 270, 360 angle degrees //If 90 degrees else if (centerOfPlayerX == centerOfPoleX && centerOfPlayerY < centerOfPoleY) { player.Angle = 90; } //If 180 degrees else if (centerOfPlayerY == centerOfPoleY && centerOfPlayerX < centerOfPoleX) { player.Angle = 180; } //If 270 degrees else if (centerOfPlayerX == centerOfPoleX && centerOfPlayerY > centerOfPoleY) { player.Angle = 270; } //If 360 degrees else if (centerOfPlayerY == centerOfPoleY && centerOfPlayerX > centerOfPoleX) { player.Angle = 360; } //Incerement counter counter++; } if (counter > 0) { //Increment the angle over time player.Angle += angleChange; //If the angle goes over 360 then mod it to make it zero again if (player.Angle > double.MaxValue - 360000) { player.Angle = player.Angle % double.MaxValue - 360000; } } return player.Angle; }
//Create a method that will repel the character from a pole if they have the same charge public void Repulsion(Poles pole, Character player) { //If the player charge is not neutral and the pole and player charge are the same if (player.Charge != 0 && pole.Charge == player.Charge) { //Change the player's position based on what quadrant they are in //0 or 360 degree if (player.XPos > pole.XPos) { //Increase the player's x speed player.XSpeed += Constants.REPULSION; } //If 180 else if (player.XPos < pole.XPos) { //Decrease the player's x speed player.XSpeed -= Constants.REPULSION; } //If 90 degree if (player.YPos < pole.YPos) { //Decrease the player's y speed player.YSpeed -= Constants.REPULSION; } //If 270 else if (player.YPos > pole.YPos) { //Increase the player's y speed player.YSpeed += Constants.REPULSION; } } }
public bool PoleCollision(Poles pole, Character player) { // check if player is touching a pole Rectangle po = new Rectangle(pole.XPos, pole.YPos, Constants.TILE_WIDTH, Constants.TILE_HEIGHT); Rectangle pl = new Rectangle(player.XPos, player.YPos, Constants.TILE_WIDTH, Constants.TILE_HEIGHT); if (po.Intersects(pl)) { return true; } else { return false; } }
protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); // TODO: Add your update logic here kbState = Keyboard.GetState(); #region Song stuff // play the current song if (playing == false) { currentSong.Play(); songTime = 0; playing = true; } // increment song timer songTime += gameTime.ElapsedGameTime.TotalMilliseconds; // upon completing the song, pick a new one if (songTime >= (currentSong.Duration.TotalMilliseconds - Constants.SONG_OFFSET)) { playing = false; if (currentSong == sounds["long collision"]) { nextSong = ranSong.Next(7); switch (nextSong) { #region switch songs case 0: currentSong = sounds["base"]; break; case 1: currentSong = sounds["base"]; break; case 2: currentSong = sounds["pious"]; break; case 3: currentSong = sounds["rising"]; break; case 4: currentSong = sounds["mta"]; break; case 5: currentSong = sounds["faster"]; break; case 6: currentSong = sounds["alchemist"]; break; #endregion } } else { currentSong = sounds["long collision"]; } } #endregion switch (gameState) { #region Case: Title case GameState.Title: // title splash if (this.SingleKeyPress(Keys.Enter)) { // start the game CheckLevelCount(); currentLevel = 1; gameState = GameState.Map; } break; #endregion #region Case: Map case GameState.Map: // update the level selector levelSelect.Update(kbState, prevKBState); // get changed level info currentLevel = levelSelect.currentLevel; maxLevel = levelSelect.maxLevel; // select a level if (SingleKeyPress(Keys.Enter) && levelSelect.screenState == LevelSelect.ScreenState.Select) { // check if previous level has been cleared, or if is LV1 if (currentLevel == 1 || (currentLevel > 1 && levelSelect.cleared[currentLevel - 1])) { gameState = GameState.Load; } } // return to the title else if (SingleKeyPress(Keys.S)) { levelSelect.screenState = LevelSelect.ScreenState.Select; gameState = GameState.Title; } // view the high scores else if (SingleKeyPress(Keys.Q)) { gameState = GameState.HighScores; } // enter the map editor else if (SingleKeyPress(Keys.Space)) { gameState = GameState.Edit; } break; #endregion #region Case: Load case GameState.Load: // load selected level // make a new loader levelLoader = new LevelLoader(); // load the file levelLoader.Load(currentLevel + ".txt"); // set locations based on file player = levelLoader.SetStart(player); goal = levelLoader.SetFinish(goal); walls = levelLoader.SetWalls(); poles = levelLoader.SetPoles(); balloons = levelLoader.SetBalloons(); //setting the animation variable in the balloons //they get their own animation because they need to act independantly for (int i = 0; i < balloons.Count; i++) { balloons[i].Anim = new Animation(GraphicsDevice, spriteBatch, 5, 100,images["balloon"]); } // reset player player.XSpeed = Constants.START_SPEED; player.YSpeed = Constants.START_SPEED; player.Angle = Constants.START_ANGLE; player.Charge = 0; // start the level gameState = GameState.Level; //reseting the timer totalSecs = 0; totalMins = 0; totalMils = 0; // set random level background int num = ranSong.Next(4); switch (num) { #region switch bkg case 0: if (levelSelect.cleared[currentLevel] == false) { images["active"] = images["r1_dark"]; } else { images["active"] = images["r1_light"]; } break; case 1: if (levelSelect.cleared[currentLevel] == false) { images["active"] = images["r2_dark"]; } else { images["active"] = images["r2_light"]; } break; case 2: if (levelSelect.cleared[currentLevel] == false) { images["active"] = images["r3_dark"]; } else { images["active"] = images["r3_light"]; } break; case 3: if (levelSelect.cleared[currentLevel] == false) { images["active"] = images["r4_dark"]; } else { images["active"] = images["r4_light"]; } break; #endregion } // check for 'boss level' if (currentLevel == 7 && levelSelect.cleared[7] == false) { images["active"] = images["lvl7_dark"]; } else if (currentLevel == 7 && levelSelect.cleared[7]) { images["active"] = images["lvl7_light"]; } break; #endregion #region Case: Pause case GameState.Pause: // pause menu if (this.SingleKeyPress(Keys.Enter)) { // unpause the game gameState = GameState.Level; } else if (this.SingleKeyPress(Keys.A)) { // reset the level (reload) gameState = GameState.Load; } else if (this.SingleKeyPress(Keys.D)) { // return to the map gameState = GameState.Map; } break; #endregion #region Case: Level case GameState.Level: // play the level //setting the old position tail3.prevLocation = new Rectangle((tail2.prevLocation.X + 6), (tail2.prevLocation.Y + 6), 12, 12); tail2.prevLocation = new Rectangle((tail1.prevLocation.X + 12), (tail1.prevLocation.Y + 12), 25, 25); tail1.prevLocation = new Rectangle(player.PrevLocation.X, player.PrevLocation.Y, 50, 50); player.PrevLocation = new Rectangle(player.XPos, player.YPos, 50, 50); // timer stuff totalSecs += gameTime.ElapsedGameTime.TotalSeconds; totalMins += gameTime.ElapsedGameTime.TotalMinutes; totalMils += gameTime.ElapsedGameTime.TotalMilliseconds; #region pause the level if (this.SingleKeyPress(Keys.Enter)) { gameState = GameState.Pause; } #endregion #region check if the player has completed the level else if (playerRect.Intersects(goalRect)) { //adding to the score levelScore = String.Format("{0:0.00}", totalSecs); if (getScore.ScoreList.ContainsKey(currentLevel)) { getScore.ScoreList[currentLevel] = totalSecs - (balloonPop*.5); } else { getScore.ScoreList.Add(currentLevel, totalSecs - (balloonPop*.5)); } //HM: making it pause for a second so people can see the lightbulb glow :) Thread.Sleep(1000); if (currentLevel+1 == maxLevel) { for (int i = 1; i <= getScore.ScoreList.Count(); i++) { endScore += getScore.ScoreList[i]; } totalScore = String.Format("{0:0.00}", endScore); getScore.WriteScores("HighScores.txt"); gameState = GameState.GameFinish; } else { gameState = GameState.LevelComplete; } } #endregion #region orbiting else if (orbitState != OrbitState.None) { #region instances for when player is leaving orbit if (SingleKeyPress(Keys.A) && player.Charge != 1) { player.Charge = 1; orbitState = OrbitState.None; } else if (SingleKeyPress(Keys.S)) { player.Charge = 0; orbitState = OrbitState.None; } else if (SingleKeyPress(Keys.D) && player.Charge != -1) { player.Charge = -1; orbitState = OrbitState.None; } #endregion // otherwise, call the orbit methods & collision/speed limit else { #region Orbit state in which player orbit around the pole both counter clockwise and clockwise switch (orbitState) { case OrbitState.Orbit: switch (player.Charge) { case -1: { //Call orbit method so that player can orbit around positive pole mechanics.Orbit(pos, player); //Increment player position based on the speed calculations from orbit method player.XPos += player.XSpeed; player.YPos += player.YSpeed; break; } case 1: { //Call orbit method so that player can orbit around negative pole mechanics.Orbit(neg, player); //Increment player position based on the speed calculations from orbit method player.XPos += player.XSpeed; player.YPos += player.YSpeed; break; } default: { orbitState = OrbitState.None; break; } } break; default: break; } #endregion #region NEW METHOD FOR WALL COLLISIONS int i = 0; bool wallIsHit = false; while (wallIsHit == false && i < (walls.Count - 1)) { wallIsHit = mechanics.Bounce(walls[i], player); if (wallIsHit) { sounds["collision"].Play(); player = mechanics.WallCollision(player); } i++; } #endregion #region check for max speed if (player.XSpeed > Constants.MAX_SPEED) { player.XSpeed = Constants.MAX_SPEED; } else if (player.XSpeed < -(Constants.MAX_SPEED)) { player.XSpeed = -(Constants.MAX_SPEED); } if (player.YSpeed > Constants.MAX_SPEED) { player.YSpeed = Constants.MAX_SPEED; } else if (player.YSpeed < -(Constants.MAX_SPEED)) { player.YSpeed = -(Constants.MAX_SPEED); } #endregion } } #endregion #region Moving else { #region find nearest pos and neg poles pos = new Poles(0, 0, 0); // closest pos pole neg = new Poles(0, 0, 0); // closest neg plole int dis = 0; // distance between player and current pole int pDis = 0; // distance between player and closest pos pole int nDis = 0; // distance between player and closest neg pole foreach (Poles pole in poles) { // calculate distance between player and current pole dis = (int)(Math.Pow((pole.XPos - player.XPos), 2) + Math.Pow((pole.YPos - player.YPos), 2)); // check if current pos and neg poles have been set if (pos.Charge == 0 && pole.Charge == 1) { // set base comparision for pos pole pos = pole; pDis = dis; } else if (neg.Charge == 0 && pole.Charge == -1) { // set base comparison for neg pole neg = pole; nDis = dis; } // check current pole against current pos and neg switch (pole.Charge) { case 1: if (dis < pDis) { // set new nearest pos pole pos = pole; pDis = dis; } break; case -1: if (dis < nDis) { // set new nearest ned pole neg = pole; nDis = dis; } break; default: break; } } #endregion #region switch the player's charge if (this.SingleKeyPress(Keys.S)) { // change charge to neutral player.Charge = 0; } else if (this.SingleKeyPress(Keys.A)) { // change charge to positive player.Charge = 1; } else if (this.SingleKeyPress(Keys.D)) { // change charge to negative player.Charge = -1; } #endregion #region player acceleration if (player.Charge == 0) { // neutral charge player.YSpeed = mechanics.Gravity(player.YSpeed); } else if (player.Charge == 1) { // positive charge player = mechanics.Attraction(neg, player); // stick to opposite-charge pole if (mechanics.PoleCollision(neg, player)) { //player.XSpeed = 0; //player.YSpeed = 0; //Set orbitState to orbit orbitState = OrbitState.Orbit; } // repulse from same-charge pole else if (mechanics.PoleCollision(pos, player)) { mechanics.Repulsion(pos, player); } } else if (player.Charge == -1) { // negative charge player = mechanics.Attraction(pos, player); // stick to opposite-charge pole if (mechanics.PoleCollision(pos, player)) { //player.XSpeed = 0; //player.YSpeed = 0; //Set orbitState to orbit orbitState = OrbitState.Orbit; } // repulse from same-charge pole else if (mechanics.PoleCollision(neg, player)) { mechanics.Repulsion(neg, player); } } #endregion #region NEW METHOD FOR WALL COLLISIONS int i = 0; bool wallIsHit = false; while (wallIsHit == false && i < (walls.Count - 1)) { wallIsHit = mechanics.Bounce(walls[i], player); if (wallIsHit) { sounds["collision"].Play(); player = mechanics.WallCollision(player); } i++; } #endregion #region check for max speed if (player.XSpeed > Constants.MAX_SPEED) { player.XSpeed = Constants.MAX_SPEED; } else if (player.XSpeed < -(Constants.MAX_SPEED)) { player.XSpeed = -(Constants.MAX_SPEED); } if (player.YSpeed > Constants.MAX_SPEED) { player.YSpeed = Constants.MAX_SPEED; } else if (player.YSpeed < -(Constants.MAX_SPEED)) { player.YSpeed = -(Constants.MAX_SPEED); } #endregion // calculate new position player.XPos += player.XSpeed; player.YPos += player.YSpeed; } #endregion // keep the player on the screen BorderCollision(); break; #endregion #region Case: Level Complete case GameState.LevelComplete: // leave this screen if (SingleKeyPress(Keys.Enter)) { levelSelect.cleared[(currentLevel)] = true; // increment currently selected level, if possible if (currentLevel < (maxLevel - 1)) { currentLevel++; levelSelect.currentLevel = currentLevel; } // return to the map gameState = GameState.Map; } break; #endregion #region Case: Edit case GameState.Edit: // check if the editor is in use if (mapMaker != null) { // return to the map and close the editor if (mapMaker.mapState == MapMaker.MapState.Editing && SingleKeyPress(Keys.Escape)) { mapMaker = null; CheckLevelCount(); levelSelect.CheckCompletedLevels(); gameState = GameState.Map; } // otherwise, update the editor else { mapMaker.Update(kbState, prevKBState); } } // if there is no editor else { mapMaker = new MapMaker(images, text); } break; #endregion #region Case: GameFinish case GameState.GameFinish: if (this.SingleKeyPress(Keys.Enter)) { gameState = GameState.HighScores; } break; #endregion #region Case: HighScore case GameState.HighScores: // Open the high score list getScore.LoadScores("HighScores.txt"); if (SingleKeyPress(Keys.W)) { gameState = GameState.Map; levelSelect.screenState = LevelSelect.ScreenState.Select; } else if (SingleKeyPress(Keys.E)) { gameState = GameState.Map; levelSelect.screenState = LevelSelect.ScreenState.Instructions; } else if (SingleKeyPress(Keys.S)) { gameState = GameState.Title; } break; #endregion } // save the current keyboard state for reference next frame prevKBState = kbState; base.Update(gameTime); }