Stay Updated!



Designed by:

XNA Tutorials
XNA Platformer Starter Kit - Adding Melee
Written by Jeff Brown   
Article Index
XNA Platformer Starter Kit - Adding Melee
Player.cs
Enemy.cs
Level.cs
All Pages

Adding player melee to Platform Starter Kit

You can download a working version below.

Here's a video showing off the final product of this tutorial:

 

Here is what I used for his attack animation as a placeholder, feel free to use it. Place this in the same place as the other animations: “HighResolutionContent>Sprites>Player”. Also make sure to add it to your project: Right click on the Player folder and Add>Existing Item>Attack.png


Attack


Player.cs

lt;span style="font-size: 10pt;">Find the following:

private float jumpTime;


After it add the following:

// Attacking state
public bool isAttacking;
const float MaxAttackTime = 0.33f;
public float AttackTime;


Next find the following:

public Rectangle BoundingRectangle
{    
    get    
    {        
        int left = (int)Math.Round(Position.X - sprite.Origin.X) + localBounds.X;
        int top = (int)Math.Round(Position.Y - sprite.Origin.Y) + localBounds.Y;

        return new Rectangle(left, top, localBounds.Width, localBounds.Height);
    }
}


After that add the following:

public Rectangle MeleeRectangle
{
    get
    {
        int left = (int)Math.Round(Position.X - sprite.Origin.X) + localBounds.X;          
        int top = (int)Math.Round(Position.Y - sprite.Origin.Y) + localBounds.Y;
        if (flip == SpriteEffects.FlipHorizontally)
            return new Rectangle(
                (left + localBounds.Width), 
                top, 
                localBounds.Width, 
                localBounds.Height);
        else
            return new Rectangle(
                (left - localBounds.Width), 
                top, 
                localBounds.Width, 
                localBounds.Height);
    }
}


At the top of Player.cs find the following line:

private Animation dieAnimation;


After that add the following line:

private Animation attackAnimation;


Now find the LoadContent method in Player.cs and find the following line:

dieAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/Player/Die"), 0.1f, false);


After that add the following:

attackAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/Player/Attack"), 0.1f, false);


Find the DoJump method and add a new method after it:

private void DoAttack(GameTime gameTime)
{
    // If the player wants to attack
    if (isAttacking)
    {
        // Begin or continue an attack
        if (AttackTime > 0.0f)
        {
            AttackTime -= (float)gameTime.ElapsedGameTime.TotalSeconds;
            sprite.PlayAnimation(attackAnimation);
        }
        else
        {
            isAttacking = false;
        }
    }
    else
    {
        //Continues not attack or cancels an attack in progress
        AttackTime = 0.0f;
    }
}


Now our attack is setup but we need a keybind so we can actually use it! At the very top of our player class add just the KeyboardState line below:

class Player
{
    KeyboardState previousKeyboardState = Keyboard.GetState();


Now add the following in the GetInput method:

if (previousKeyboardState.IsKeyUp(Keys.F) && keyboardState.IsKeyDown(Keys.F))
{
    if (AttackTime != MaxAttackTime)
    {
        isAttacking = true;
        AttackTime = MaxAttackTime;
    }
}


Now onto the Update method, after the GetInput() call add the following:

DoAttack(gameTime);


Find the following in the Update method:

if (IsAlive && IsOnGround)
{
    if (Math.Abs(Velocity.X) - 0.02f > 0)
    {
        sprite.PlayAnimation(runAnimation);
    }
    else
    {
        sprite.PlayAnimation(idleAnimation);
    }
}


And change it to look like the following:

if (IsAlive && IsOnGround)
{
    if (isAttacking)
    {
        sprite.PlayAnimation(attackAnimation);
    }
    else
    {
        if (Math.Abs(Velocity.X) - 0.02f > 0)
        {
            sprite.PlayAnimation(runAnimation);
        }
        else
        {
            sprite.PlayAnimation(idleAnimation);
        }
    }
}


Build the solution at this point to make sure you don’t have any errors.



Enemy.cs


In Enemy.cs find the following:

// Animations
private Animation runAnimation;
private Animation idleAnimation;
private AnimationPlayer sprite;


and add the following after it:

private Animation dieAnimation;

// Sounds
private SoundEffect killedSound;

public bool IsAlive { get; private set; }


Here we added a death animation, death sound, and an IsAlive variable that will allow our enemies to die. To initialize the IsAlive variable find the constructor for our Enemy, and after

this.position = position;

add:

this.IsAlive = true;


First we need to load the sound into the project because it isn’t there by default. In the solution explorer go to “SharedContent” right click on Sounds>Add>Existing Item and add “MonsterKilled”. Right click on MonsterKilled and go to Properties. In the Properties window find ContentProcessor and from the drop down menu to the right of that choose Sound Effect – XNA Framework. At the very top add another using statement:

using Microsoft.Xna.Framework.Audio;


We need to load the new sound so find the LoadContent method and add the following at the bottom:

//Load sounds. 
killedSound = Level.Content.Load<SoundEffect>("Sounds/MonsterKilled");  


While we’re in the LoadContent method add the following by the other animations:

dieAnimation = new Animation(Level.Content.Load<Texture2D>(spriteSet + "Die"), 0.07f, false);


Under the Update method add a new method:

public void OnKilled(Player killedBy)
{
    IsAlive = false;
    killedSound.Play();
}

Level.cs


Next in Level.cs find the following in the UpdateEnemies method

// Touching an enemy instantly kills the player
if (enemy.BoundingRectangle.Intersects(Player.BoundingRectangle))
{
    OnPlayerKilled(enemy);
}


And change it to the following:

if (enemy.IsAlive && enemy.BoundingRectangle.Intersects(Player.MeleeRectangle))
{
    if(Player.isAttacking)
        OnEnemyKilled(enemy, Player);
}


Now under the UpdateEnemies method add a new method:

private void OnEnemyKilled(Enemy enemy, Player killedBy)
{
    enemy.OnKilled(killedBy);
}


And that's it! Give it a try and see if you can finally kill those enemies!

 

Add comment


Security code
Refresh