//character constructor takes game information public Character(playerType pType, int playerNumber, Rectangle playerRectangle, Texture2D spriteSheet, SoundEffect attackSound, SoundEffect jumpSound) { //setting preliminary values health = 20; spdScale = 4; xSpd = 0.0f; ySpd = 0.0f; dir = 1; attacked = false; isInvulnerable = false; frameWaitSet = false; currentFrameCount = 24; //animation preliminary values imageHeight = 64; imageWidth = 64; imageYOffset = 64; //twelve for fps looks good for now, can be changed later as needed fps = 12; timePerFrame = 1 / fps; //sound this.attackSound = attackSound; this.jumpSound = jumpSound; //set the spritesheet this.spriteSheet = spriteSheet; //set the rectangle this.playerRectangle = playerRectangle; //create the hitbox manager hitBox = new HitboxManager(); //set the player type this.pType = pType; groundY = playerRectangle.Y; //set the preliminary staes pState = playerState.moveState; mState = moveFSM.idle; jState = jumpState.grounded; //set the player number this.playerNumber = playerNumber; }
//update method takes a keyboard state and frame count from the game1 update method public void Update(KeyboardState kbState, int frameCount) { //setting the kbstate and framecount this.frameCount = frameCount; kbState = Keyboard.GetState(); //determine player direction based on the other player's position if (playerRectangle.X < Other.playerRectangle.X) { dir = 1; } if (playerRectangle.X > Other.playerRectangle.X) { dir = -1; } //player state main finite state machine switch (pState) { //move state case playerState.moveState: #region PLAYER 0 MOVEMENT if (playerNumber == 0) { //Movement state fsm switch (mState) { //idle state does nothing and can switch between the move states and jumping state case moveFSM.idle: xSpd = 0; if (kbState.IsKeyDown(Keys.A)) { //switch to left move mState = moveFSM.moveLeft; } else if (kbState.IsKeyDown(Keys.D)) { //switch to right move mState = moveFSM.moveRight; } if (kbState.IsKeyDown(Keys.W)) { //jump if the player is on the ground if (jState == jumpState.grounded) { PlaySound(jumpSound, 1); jState = jumpState.moveJump; } } if (jState != jumpState.moveJump && jState != jumpState.falling) //Attack, but only on the ground { if (kbState.IsKeyDown(Keys.F)) { pState = playerState.attackState; } } break; //move left state case moveFSM.moveLeft: if (kbState.IsKeyDown(Keys.A)) { //move if the key is still held down xSpd = -spdScale; } else if (kbState.IsKeyDown(Keys.D)) { //if the d key is pressed instead, switch to the move right state mState = moveFSM.moveRight; } else { //if nothing is pressed, switch to the idle state mState = moveFSM.idle; } if (kbState.IsKeyDown(Keys.W)) { //jump if the player is on the ground if (jState == jumpState.grounded) { PlaySound(jumpSound, 1); jState = jumpState.moveJump; } } if (jState != jumpState.moveJump && jState != jumpState.falling) { if (kbState.IsKeyDown(Keys.F)) { pState = playerState.attackState; } } if (playerRectangle.X < 20) { xSpd = 0; } break; //move right case moveFSM.moveRight: if (kbState.IsKeyDown(Keys.D)) { //move right if still pressing right xSpd = spdScale; } else if (kbState.IsKeyDown(Keys.A)) { //change to left move state mState = moveFSM.moveLeft; } else { //change to idle state mState = moveFSM.idle; } if (kbState.IsKeyDown(Keys.W)) { //jump if the player is on the ground if (jState == jumpState.grounded) { PlaySound(jumpSound, 1); jState = jumpState.moveJump; } } if (jState != jumpState.moveJump && jState != jumpState.falling) { if (kbState.IsKeyDown(Keys.F)) { pState = playerState.attackState; } } if (playerRectangle.X > 700) { xSpd = 0; } break; } //jump finite state machine switch (jState) { case jumpState.grounded: //the grounded state makes sure the player does not move ySpd = 0; break; case jumpState.moveJump: //the move jump state sets the player's y velocity to 10 ySpd = -10; jState = jumpState.falling; break; case jumpState.falling: //the falling state makes the player slow their jump and then fall if (playerRectangle.Y < groundY) { //if not back to original position, fall ySpd++; } else { //if back to original position, set speed to 0 and set to grounded state ySpd = 0; playerRectangle.Y = groundY; jState = jumpState.grounded; } break; } } #endregion /* * PLAYER 1 MOVEMENT IS THE EXACT SAME AS PLAYER 0, JUST WITH DIFFERENT BUTTON CHECKS */ #region PLAYER 1 MOVEMENT else if (playerNumber == 1) { switch (mState) { case moveFSM.idle: xSpd = 0; if (kbState.IsKeyDown(Keys.Left)) { mState = moveFSM.moveLeft; } else if (kbState.IsKeyDown(Keys.Right)) { mState = moveFSM.moveRight; } if (kbState.IsKeyDown(Keys.Up)) { if (jState == jumpState.grounded) { PlaySound(jumpSound, 1); jState = jumpState.moveJump; } } if (jState != jumpState.moveJump && jState != jumpState.falling) { if (kbState.IsKeyDown(Keys.M)) { pState = playerState.attackState; } } break; case moveFSM.moveLeft: if (kbState.IsKeyDown(Keys.Left)) { xSpd = -spdScale; } else if (kbState.IsKeyDown(Keys.Right)) { mState = moveFSM.moveRight; } else { mState = moveFSM.idle; } if (kbState.IsKeyDown(Keys.Up)) { if (jState == jumpState.grounded) { PlaySound(jumpSound, 1); jState = jumpState.moveJump; } } if (jState != jumpState.moveJump && jState != jumpState.falling) { if (kbState.IsKeyDown(Keys.M)) { pState = playerState.attackState; } } if (playerRectangle.X < 20) { xSpd = 0; } break; case moveFSM.moveRight: if (kbState.IsKeyDown(Keys.Right)) { xSpd = spdScale; } else if (kbState.IsKeyDown(Keys.Left)) { mState = moveFSM.moveLeft; } else { mState = moveFSM.idle; } if (kbState.IsKeyDown(Keys.Up)) { if (jState == jumpState.grounded) { PlaySound(jumpSound, 1); jState = jumpState.moveJump; } } if (jState != jumpState.moveJump && jState != jumpState.falling) { if (kbState.IsKeyDown(Keys.M)) { pState = playerState.attackState; } } if (playerRectangle.X > 700) { xSpd = 0; } break; } switch (jState) { case jumpState.grounded: //the grounded state makes sure the player does not move ySpd = 0; break; case jumpState.moveJump: //the move jump state sets the player's y velocity to 10 ySpd = -10; jState = jumpState.falling; break; case jumpState.falling: //the falling state makes the player slow their jump and then fall if (playerRectangle.Y < groundY) { //if not back to original position, fall ySpd++; } else { //if back to original position, set speed to 0 and set to grounded state ySpd = 0; playerRectangle.Y = groundY; jState = jumpState.grounded; } break; } } #endregion break; //attack state case playerState.attackState: #region PLAYER ATTACK //if the player has not attacked if (!attacked) { //player type fsm switch (pType) { //sword player attack with arbitrary values case playerType.swordPlayer: PlaySound(attackSound, 1); if (dir < 0) { hitBox.ActivateHitbox(new Point(playerRectangle.X + playerRectangle.Width / 2 + (10 * dir) + (20 * dir), playerRectangle.Y + playerRectangle.Height / 2), new Point(20, 20)); } else { hitBox.ActivateHitbox(new Point(playerRectangle.X + playerRectangle.Width / 2 + (10 * dir), playerRectangle.Y + playerRectangle.Height / 2), new Point(20, 20)); } if (hitBox.CheckCollision(Other)) { Other.TakeDamage(); } hitBox.DeleteHitbox(); break; //flail player, arbitrary values case playerType.flailPlayer: PlaySound(attackSound, 1); if (dir < 0) { hitBox.ActivateHitbox(new Point(playerRectangle.X + playerRectangle.Width / 2 + (150 * dir) + (30 * dir), playerRectangle.Y + playerRectangle.Height / 2), new Point(30, 30)); } else { hitBox.ActivateHitbox(new Point(playerRectangle.X + playerRectangle.Width / 2 + (150 * dir), playerRectangle.Y + playerRectangle.Height / 2), new Point(30, 30)); } if (hitBox.CheckCollision(Other)) { Other.TakeDamage(); } hitBox.DeleteHitbox(); break; //gun player arbitrary values case playerType.gunPlayer: PlaySound(attackSound, 1); if (dir < 0) { hitBox.ActivateHitbox(new Point(playerRectangle.X + playerRectangle.Width / 2 + (10 * dir) + (500 * dir), playerRectangle.Y + playerRectangle.Height / 2), new Point(500, 5)); } else { hitBox.ActivateHitbox(new Point(playerRectangle.X + playerRectangle.Width / 2 + (10 * dir), playerRectangle.Y + playerRectangle.Height / 2), new Point(500, 5)); } if (hitBox.CheckCollision(Other)) { Other.TakeDamage(); } hitBox.DeleteHitbox(); break; } //set attacked to true and set the number of frames to wait attacked = true; } //set the frame timer if (!frameWaitSet) { if (pType == playerType.gunPlayer) { frameWait = 16; } else if (pType == playerType.swordPlayer) { frameWait = 30; } else if (pType == playerType.flailPlayer) { frameWait = 48; } frameWaitSet = true; } //if the player has waited enough, set the player state back to move and reset the ability to attack if (frameWait == 0) { attacked = false; frameWaitSet = false; pState = playerState.moveState; } else { //wait one less frame frameWait--; } #endregion break; //block state case playerState.blockState: if (kbState.IsKeyDown(Keys.B)) { pState = playerState.blockState; isInvulnerable = true; } else { pState = playerState.moveState; isInvulnerable = false; } break; //dash state (?) case playerState.dashState: break; //knockback state case playerState.knockBackState: isInvulnerable = true; if (!frameWaitSet) { frameWaitSet = true; frameWait = 4; } if (frameWait > 0) { frameWait--; } else { if (playerRectangle.Y != Other.PlayerRectangle.Y) { ySpd = -1; jState = jumpState.falling; } isInvulnerable = false; frameWait = 4; frameWaitSet = false; pState = playerState.moveState; } break; } //update the player rectangle based on the fsm code playerRectangle.X += (int)xSpd; playerRectangle.Y += (int)ySpd; }