XNA Creators Club Online
Page 1 of 2 (34 items) 1 2 Next >
Sort Posts: Previous Next

Adding ladders to the platform starter kit

Last post 2/26/2010 11:09 AM by FirestormXVI. 33 replies.
  • 7/24/2009 5:08 PM

    Adding ladders to the platform starter kit

    Hello again everyone,

    My attempts at adding new things into the platform starter kit are going very well indeed. Now, I have a melee attack and enemy death, horizontal scrolling and all the things that go with that, but now I am stuck on getting ladders implemented into the system.

    I did see one thread about climbing them but it didn't leave much detail on how it was done so I attempted it myself. I have a Ladder collision set up, and when the player collides with the ladder it does return true. However, I can't get the player to go up the ladder with out jumping up it. I know there has to be an easier way to do this. Granted I don't know much about the collision system but I am taking a lot of time getting it figured out.


    So I have two questions:

    1.) How can I get the player to move up the ladder? Do I change position or the velocity?

    2.) How can I check easily what tile player is standing on?



    Here is a picture to show a reference on what I mean. If you need me to post the code of the player then let me know.



  • 7/25/2009 2:40 PM In reply to

    Re: Adding ladders to the platform starter kit

    I am trying to figure out the same thing. I have extended the starter kit a lot but for the life of me I can't figure out the ladder. I can get it to move up the ladder really fast and down the ladder a tile at a time but that's not what I want. Also, the problem with that is that if the player jumps while in front of the ladder, he stops on the nearest tile plus if the player walks across the top of the ladder, he falls down.

    In the collision method I added:
    if (tryingToClimb) 
                        { 
                            if (collision == TileCollision.Ladder) 
                            { 
                                Position = new Vector2(Position.X, Position.Y + depth.Y); 
                            } 
                        }    

  • 7/25/2009 4:19 PM In reply to

    Re: Adding ladders to the platform starter kit

    Ladders can be really tough to make. This is one solution:
    -First you need to understand collision detection. Lets say each ladder have a collision rectangle.

    if(move direction == up)
    {
      bool ladderWalk = false

      for each Ladder
      {  if (Player.Rectangle does collide with Ladder.Rectangle ) { ladderWalk =true; break;  }   }

       if (ladderWalk)
       {
             const float CLIMBSPEED = 0.1f;
             Player.Y -=  CLIMBSPEED * time;
        }
       else
     { Player Aim up}

    After this you will probably have to make a lot of tweaking to get it right..
  • 7/25/2009 7:15 PM In reply to

    Re: Adding ladders to the platform starter kit

    OK, that part I understand. what is bugging me is when the player needs to get back down I need to know what kind of tile collision the player is standing on. Many attempts on checking the code in my "debugger" have failed.

    Is there an easy way of checking the code so I can tell what kind of tile the player is STANDING ON. The current collision checks for the player colliding with the tile behind it.

    I have some more tweaks to do but I'm still at an impasse.
  • 7/25/2009 9:02 PM In reply to

    Re: Adding ladders to the platform starter kit

    Scratch that.

    Sorry for double post.


    I got the code to detect if the player is standing on a ladder or not. Now the problem lies within getting the player to move up and down the ladder. I believe it has something to do with either velocity or Position but position is not editable unless I declare a new Position vector like it does in the handleCollisions function.

    Am I on the right track or what?
  • 7/25/2009 11:20 PM In reply to

    Re: Adding ladders to the platform starter kit

    You can't change the individual x and y coordinates of Position but to change Position, yes you would declare a new Vector2. For example if you wanted you modify just the y value, you would do this:

         Position = new Vector2(Position.X, Position.Y - 10)
  • 7/26/2009 2:55 AM In reply to

    Re: Adding ladders to the platform starter kit

    Have a look at my code and see if anyone can give me some pointers on getting the Position right.

    using System; 
    using Microsoft.Xna.Framework; 
    using Microsoft.Xna.Framework.Audio; 
    using Microsoft.Xna.Framework.Graphics; 
    using Microsoft.Xna.Framework.Input; 
     
    namespace SpriteTest 
        enum PlayerState 
        { 
            Idle = 0, 
            Run = 1, 
            Knife = 2, 
            Jump = 3, 
            ClimbUp = 4, 
            ClimbDown = 5, 
        } 
     
        class Player 
        { 
            // Animations 
            private Animation idleAnimation; 
            private Animation runAnimation; 
            private Animation knifeAnimation; 
            private Animation jumpAnimation; 
     
            private SpriteEffects flip = SpriteEffects.None; 
            private AnimationPlayer sprite; 
     
            // Sounds 
            private SoundEffect killedSound; 
            private SoundEffect jumpSound; 
            private SoundEffect fallSound; 
     
            Texture2D bulletTexture; 
            int bulletDelay; 
            public double elapsedMilliseconds; 
     
            public Level Level 
            { 
                get { return level; } 
            } 
            Level level; 
     
            public bool IsAttacking 
            { 
                get { return isAttacking; } 
                set { isAttacking = value; } 
            } 
            bool isAttacking; 
     
            public bool IsAlive 
            { 
                get { return isAlive; } 
            } 
            bool isAlive; 
     
            // Physics state 
            public Vector2 Position 
            { 
                get { return position; } 
                set { position = value; } 
            } 
            Vector2 position; 
     
            public float previousBottom; 
     
            public Vector2 Velocity 
            { 
                get { return velocity; } 
                set { velocity = value; } 
            } 
            Vector2 velocity; 
     
            public PlayerState State 
            { 
                get { return (PlayerState)state; } 
                set { state = (int)value; } 
            } 
     
            public int state; 
     
            public bool TouchingLadder 
            { 
                get { return touchingLadder; } 
                set { touchingLadder = value; } 
            } 
            private bool touchingLadder; 
     
            private bool climbingUp, climbingDown; 
     
            // Constants for controling horizontal movement 
            private const float MoveAcceleration = 8000.0f; 
            private const float MaxMoveSpeed = 2000.0f; 
            private const float GroundDragFactor = 0.53f; 
            private const float AirDragFactor = 0.65f; 
     
            // Constants for controlling vertical movement 
            private const float MaxJumpTime = 0.35f; 
            private const float JumpLaunchVelocity = -4000.0f; 
            private const float GravityAcceleration = 3500.0f; 
            private const float MaxFallSpeed = 600.0f; 
            private const float JumpControlPower = 0.14f; 
     
            // Input configuration 
            private const float MoveStickScale = 1.0f; 
            private const Buttons JumpButton = Buttons.A; 
     
            /// <summary> 
            /// Gets whether or not the player's feet are on the ground. 
            /// </summary> 
            public bool IsOnGround 
            { 
                get { return isOnGround; } 
            } 
            bool isOnGround; 
     
            /// <summary> 
            /// Current user movement input. 
            /// </summary> 
            private float movement; 
     
            // Jumping state 
            private bool isJumping; 
            private bool wasJumping; 
            private float jumpTime; 
     
            //Shooting State 
            private bool isShooting; 
     
            //Knife State 
            private bool isStabbing; 
     
            private Rectangle localBounds; 
            /// <summary> 
            /// Gets a rectangle which bounds this player in world space. 
            /// </summary> 
            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); 
                } 
            } 
     
            /// <summary> 
            /// Constructors a new player. 
            /// </summary> 
            public Player(Level level, Vector2 position) 
            { 
                this.level = level; 
                this.IsAttacking = false
                this.touchingLadder = false
     
                LoadContent(); 
     
                Reset(position); 
            } 
     
            /// <summary> 
            /// Loads the player sprite sheet and sounds. 
            /// </summary> 
            public void LoadContent() 
            { 
                // Load animated textures. 
                idleAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/Player/Idle"), 0.2f, true); 
                runAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/Player/Run"), 0.05f, true); 
                knifeAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/Player/Knife"), 0.1f, false); 
                jumpAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/Player/Jump"), 0.2f, true); 
     
                // Calculate bounds within texture size.             
                int width = (int)(idleAnimation.FrameWidth * 0.4); 
                int left = (idleAnimation.FrameWidth - width) / 2; 
                int height = (int)(idleAnimation.FrameWidth * 0.8); 
                int top = idleAnimation.FrameHeight - height; 
                localBounds = new Rectangle(left, top, width, height); 
     
                // Load sounds.             
                //killedSound = Level.Content.Load<SoundEffect>("Sounds/PlayerKilled"); 
                //jumpSound = Level.Content.Load<SoundEffect>("Sounds/PlayerJump"); 
                //fallSound = Level.Content.Load<SoundEffect>("Sounds/PlayerFall"); 
     
                bulletTexture = Level.Content.Load<Texture2D>("Sprites/Bullet"); 
            } 
     
            /// <summary> 
            /// Resets the player to life. 
            /// </summary> 
            /// <param name="position">The position to come to life at.</param> 
            public void Reset(Vector2 position) 
            { 
                Position = position; 
                Velocity = Vector2.Zero; 
                isAlive = true
                IsAttacking = false
                TouchingLadder = false
                sprite.PlayAnimation(idleAnimation); 
            } 
     
            /// <summary> 
            /// Handles input, performs physics, and animates the player sprite. 
            /// </summary> 
            public void Update(GameTime gameTime) 
            { 
                GetInput(gameTime); 
     
                ApplyPhysics(gameTime); 
     
                if (IsAlive && IsOnGround) 
                { 
                    if (Math.Abs(Velocity.X) - 0.02f > 0) 
                    { 
                        State = PlayerState.Run; 
                    } 
                    else if (isStabbing) 
                    { 
                        IsAttacking = true
                        State = PlayerState.Knife; 
                    } 
                    else if (isJumping) 
                    { 
                        State = PlayerState.Jump; 
                    } 
                    else 
                    { 
                        State = PlayerState.Idle; 
                    } 
                } 
     
                if (IsAlive && IsOnGround && climbingUp) 
                    State = PlayerState.ClimbUp; 
     
                if (IsAlive && !IsOnGround && climbingDown) 
                    State = PlayerState.ClimbDown; 
     
                CheckState(State, gameTime); 
     
                // Clear input. 
                movement = 0.0f; 
                isJumping = false
                 
                climbingUp = false
                climbingDown = false
            } 
     
            private void CheckState(PlayerState State, GameTime gameTime) 
            { 
                switch (State) 
                { 
                    case PlayerState.Idle: 
                        sprite.PlayAnimation(idleAnimation); 
                        break
                    case PlayerState.Run: 
                        sprite.PlayAnimation(runAnimation); 
                        break
                    case PlayerState.Knife: 
                        sprite.PlayAnimation(knifeAnimation); 
                        break
                    case PlayerState.ClimbUp: 
                        Position = new Vector2(Position.X, position.Y + 2); 
                        break
                    case PlayerState.ClimbDown: 
                        Position = new Vector2(position.X, position.Y - 2); 
                        break
                    default
                        sprite.PlayAnimation(idleAnimation); 
                        break
                } 
            } 
     
            /// <summary> 
            /// Gets player horizontal movement and jump commands from input. 
            /// </summary> 
            private void GetInput(GameTime gameTime) 
            { 
                elapsedMilliseconds = gameTime.TotalGameTime.Seconds /2; 
     
                // Get input state. 
                GamePadState gamePadState = GamePad.GetState(PlayerIndex.One); 
                KeyboardState keyboardState = Keyboard.GetState(); 
                KeyboardState previousKeyboardState = keyboardState; 
     
                // Get analog horizontal movement. 
                movement = gamePadState.ThumbSticks.Left.X * MoveStickScale; 
     
                // Ignore small movements to prevent running in place. 
                if (Math.Abs(movement) < 0.5f) 
                    movement = 0.0f; 
     
                //If any digital horizontal movement input is found, override the analog movement. 
                if (gamePadState.IsButtonDown(Buttons.DPadLeft) || 
                    keyboardState.IsKeyDown(Keys.Left)) 
                { 
                    movement = -1.0f; 
                } 
                else if (gamePadState.IsButtonDown(Buttons.DPadRight) || 
                         keyboardState.IsKeyDown(Keys.Right)) 
                { 
                    movement = 1.0f; 
                } 
                isShooting = keyboardState.IsKeyDown(Keys.Z) && gameTime.TotalGameTime.TotalMilliseconds - bulletDelay > 1000; 
                if(keyboardState.IsKeyUp(Keys.Z)) 
                    bulletDelay = 0; 
     
                if(keyboardState.IsKeyDown(Keys.A)) 
                { 
                    isStabbing = true
                    IsAttacking = true
                } 
                else if (keyboardState.IsKeyUp(Keys.A)) 
                { 
                    isStabbing = false
                    IsAttacking = false
                } 
                 //Check if the player wants to jump. 
                isJumping = 
                    gamePadState.IsButtonDown(JumpButton) || 
                    keyboardState.IsKeyDown(Keys.Space); 
     
                if (keyboardState.IsKeyDown(Keys.Up) && TouchingLadder) 
                { 
                    movement = 0.0f; 
                    climbingUp = true
                    climbingDown = false
                } 
                if (keyboardState.IsKeyDown(Keys.Down) && TouchingLadder) 
                { 
                    movement = 0.0f; 
                    climbingUp = false
                    climbingDown = true
                } 
     
                 
                 
            } 
     
            /// <summary> 
            /// Updates the player's velocity and position based on input, gravity, etc. 
            /// </summary> 
            public void ApplyPhysics(GameTime gameTime) 
            { 
                float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; 
     
                Vector2 previousPosition = Position; 
     
                // Base velocity is a combination of horizontal movement control and 
                // acceleration downward due to gravity. 
                velocity.X += movement * MoveAcceleration * elapsed; 
                velocity.Y = MathHelper.Clamp(velocity.Y + GravityAcceleration * elapsed, -MaxFallSpeed, MaxFallSpeed); 
     
                velocity.Y = DoJump(velocity.Y, gameTime); 
     
                // Apply pseudo-drag horizontally. 
                if (IsOnGround) 
                    velocity.X *= GroundDragFactor; 
                else 
                    velocity.X *= AirDragFactor; 
     
                // Prevent the player from running faster than his top speed.             
                velocity.X = MathHelper.Clamp(velocity.X, -MaxMoveSpeed, MaxMoveSpeed); 
     
                // Apply velocity. 
                Position += velocity * elapsed; 
                Position = new Vector2((float)Math.Round(Position.X), (float)Math.Round(Position.Y)); 
     
                // If the player is now colliding with the level, separate them. 
                HandleCollisions(); 
     
                // If the collision stopped us from moving, reset the velocity to zero. 
                if (Position.X == previousPosition.X) 
                    velocity.X = 0; 
     
                if (Position.Y == previousPosition.Y) 
                    velocity.Y = 0; 
            } 
     
             ///<summary> 
             ///Calculates the Y velocity accounting for jumping and 
             ///animates accordingly. 
             ///</summary> 
             ///<remarks> 
             ///During the accent of a jump, the Y velocity is completely 
             ///overridden by a power curve. During the decent, gravity takes 
             ///over. The jump velocity is controlled by the jumpTime field 
             ///which measures time into the accent of the current jump. 
             ///</remarks> 
             ///<param name="velocityY"> 
             ///The player's current velocity along the Y axis. 
             ///</param> 
             ///<returns> 
             ///A new Y velocity if beginning or continuing a jump. 
             ///Otherwise, the existing Y velocity. 
             ///</returns> 
            private float DoJump(float velocityY, GameTime gameTime) 
            { 
                // If the player wants to jump 
                if (isJumping) 
                { 
                    State = PlayerState.Jump; 
                    // Begin or continue a jump 
                    if ((!wasJumping && IsOnGround) || jumpTime > 0.0f) 
                    { 
                        //if (jumpTime == 0.0f) 
                        //    jumpSound.Play(); 
     
                        jumpTime += (float)gameTime.ElapsedGameTime.TotalSeconds; 
                        sprite.PlayAnimation(jumpAnimation); 
                    } 
     
                    // If we are in the ascent of the jump 
                    if (0.0f < jumpTime && jumpTime <= MaxJumpTime) 
                    { 
                        // Fully override the vertical velocity with a power curve that gives players more control over the top of the jump 
                        velocityY = JumpLaunchVelocity * (1.0f - (float)Math.Pow(jumpTime / MaxJumpTime, JumpControlPower)); 
                    } 
                    else 
                    { 
                        // Reached the apex of the jump 
                        jumpTime = 0.0f; 
                    } 
                } 
                else 
                { 
                    // Continues not jumping or cancels a jump in progress 
                    jumpTime = 0.0f; 
                } 
                wasJumping = isJumping; 
     
                return velocityY; 
            } 
     
            /// <summary> 
            /// Detects and resolves all collisions between the player and his neighboring 
            /// tiles. When a collision is detected, the player is pushed away along one 
            /// axis to prevent overlapping. There is some special logic for the Y axis to 
            /// handle platforms which behave differently depending on direction of movement. 
            /// </summary> 
            private void HandleCollisions() 
            { 
                // Get the player's bounding rectangle and find neighboring tiles. 
                Rectangle bounds = BoundingRectangle; 
                int leftTile = (int)Math.Floor((float)bounds.Left / Tile.Width); 
                int rightTile = (int)Math.Ceiling(((float)bounds.Right / Tile.Width)) - 1; 
                int topTile = (int)Math.Floor((float)bounds.Top / Tile.Height); 
                int bottomTile = (int)Math.Ceiling(((float)bounds.Bottom / Tile.Height)) - 1; 
     
                // Reset flag to search for ground collision. 
                isOnGround = false
     
                // For each potentially colliding tile, 
                for (int y = topTile; y <= bottomTile; ++y) 
                { 
                    for (int x = leftTile; x <= rightTile; ++x) 
                    { 
                        // If this tile is collidable, 
                        TileCollision collision = Level.GetCollision(x, y); 
                        if (collision != TileCollision.Passable) 
                        { 
                            // Determine collision depth (with direction) and magnitude. 
                            Rectangle tileBounds = Level.GetBounds(x, y); 
                            Vector2 depth = RectangleExtensions.GetIntersectionDepth(bounds, tileBounds); 
                            if (depth != Vector2.Zero) 
                            { 
                                float absDepthX = Math.Abs(depth.X); 
                                float absDepthY = Math.Abs(depth.Y); 
     
                                // Resolve the collision along the shallow axis. 
                                if (absDepthY < absDepthX || collision == TileCollision.Platform) 
                                { 
                                    // If we crossed the top of a tile, we are on the ground. 
                                    if (previousBottom <= tileBounds.Top) 
                                        isOnGround = true
     
                                    // Ignore platforms, unless we are on the ground. 
                                    if (collision == TileCollision.Impassable || IsOnGround) 
                                    { 
                                        // Resolve the collision along the Y axis. 
                                        Position = new Vector2(Position.X, Position.Y + depth.Y); 
     
                                        // Perform further collisions with the new bounds. 
                                        bounds = BoundingRectangle; 
                                    } 
                                } 
                                else if (collision == TileCollision.Impassable) // Ignore platforms. 
                                { 
                                    // Resolve the collision along the X axis. 
                                    Position = new Vector2(Position.X + depth.X, Position.Y); 
     
                                    // Perform further collisions with the new bounds. 
                                    bounds = BoundingRectangle; 
                                } 
                                if (collision == TileCollision.Ladder) 
                                { 
                                    TouchingLadder = true
                                } 
                                else 
                                    TouchingLadder = false
     
                                 
                            } 
                        } 
                    } 
                } 
     
                // Save the new bounds bottom. 
                previousBottom = bounds.Bottom; 
            } 
     
            /// <summary> 
            /// Called when the player has been killed. 
            /// </summary> 
            /// <param name="killedBy"> 
            /// The enemy who killed the player. This parameter is null if the player was 
            /// not killed by an enemy (fell into a hole). 
            /// </param> 
            //public void OnKilled(Enemy killedBy) 
            //{ 
            //    isAlive = false; 
     
            //    if (killedBy != null) 
            //        killedSound.Play(); 
            //    else 
            //        fallSound.Play(); 
     
            //    sprite.PlayAnimation(dieAnimation); 
            //} 
     
            /// <summary> 
            /// Called when this player reaches the level's exit. 
            /// </summary> 
            //public void OnReachedExit() 
            //{ 
            //    sprite.PlayAnimation(celebrateAnimation); 
            //} 
     
            /// <summary> 
            /// Draws the animated player. 
            /// </summary> 
            public void Draw(GameTime gameTime, SpriteBatch spriteBatch) 
            { 
                // Flip the sprite to face the way we are moving. 
                if (Velocity.X < 0) 
                    flip = SpriteEffects.FlipHorizontally; 
                else if (Velocity.X > 0) 
                    flip = SpriteEffects.None; 
     
                // Draw that sprite. 
                sprite.Draw(gameTime, spriteBatch, Position, flip); 
            } 
        } 
     

    I noticed it only adds the new position once and not as long as you have the key down. for instance the position.y +2 only adds 2 to the actual Y coord and not continually adding it until I stop. Any help would be great!
  • 7/26/2009 1:32 PM In reply to

    Re: Adding ladders to the platform starter kit

    It's because in the HandleCollision method touchingLadder is set to true but is is also being set to false while you are still touching the ladder. Put a break point where you set touchingLadder = true. Once you hit that break point, put another break point where touchingLadder = false. Hit F5 a couple of times and you will see that even though your player is still touching the ladder, is is being set to false.

    The reason I believe this is happening is because when it checks for collisions, it checks left, right, up and down.
  • 7/28/2009 6:51 AM In reply to

    Re: Adding ladders to the platform starter kit

    So, how would I rectify it only checking it the tiles once instead of left, right, up and down?

    Should I check the ladder first before anything else?

    Or would another else if statement be better.

    Plus when I get to check for ladder and it returns true the character just seems to hop in place until I let go. How can I nullify the physics only when climbing?
  • 7/28/2009 2:58 PM In reply to

    Re: Adding ladders to the platform starter kit

    What i do is on the HandleCollision method, after the for loop I check to see if the user is trying to climb and if so check the tile player is currently on.

    if (tryingToClimb) 
                    if (Level.GetCollision(currentTileX, currentTileY) == TileCollision.Ladder) 
                        isOnLadder = true
                    else if (Level.GetCollision(currentTileX, currentTileY + 1) == TileCollision.Ladder) 
                        isOnLadder = true
                    else 
                        isOnLadder = false

    Then in the ApplyPhysics method at the top:

    if (isOnLadder || isOnTopOfLadder)  
    {  
                GravityAcceleration = 0;  
                velocity.Y = 0;  
    }  
    else  
    {  
                GravityAcceleration = 3500;  
     

    The isOnTopOfLadder is used to check if the user is standing on the top of the ladder because we don't want him to fall through if he is just crossing over.

  • 7/29/2009 8:37 PM In reply to

    Re: Adding ladders to the platform starter kit

    OK, here is what I've gotten so far. its a little buggy as you can see the actions it does within the youtube video. watch the beautiful trace box to the left as it indicates what all is happening.

    Youtube Video Preview:
    http://www.youtube.com/watch?v=fdmX47BgPzw

    Ladder.cs
    http://pastebin.com/f739cdbe
    ^^^^note for Ladder.cs
    its pretty safe to just copy the entire script and use it, the only thing you will need to change in it is the namespace and the path used to grab the ladder.

    Player.cs
    http://pastebin.com/f4f8b1a9a
    ^^^^note for Player.cs
    (I highlighted what all needs to be looked at, i think i highlighted most parts, though on the ApplyPhysics (the one starting on line 403, the one with the yellow highlights, the one that is not commented out ect ect), you might want to just comment out the default applyphysics and copy the whole void.)

    Level.cs
    http://pastebin.com/feced20d
    ^^^^note for Level.cs
    i erased some extra coding i had in there that was for other features, just to shorten it up. any parts that are related with apples are highlighted yellow, and any void that contained a single reference to ladders i did not remove anything from them.



    This is not complete, as you can see in the youtube video its only a starting, i can not figure a way to get him to continuously be seen as touching the ladder, if anyone is willing to help feel free to use the coding i have supplied to work from for the ladders. and if you get the ladders working, PLEASE psot the updated fixed version.
  • 7/29/2009 11:35 PM In reply to

    Re: Adding ladders to the platform starter kit

    I have ladders working as follows:
    1. Player can walk over a ladder tile onto a platform on the other side.
    2. Player can climb down a ladder and resume the correct state at the bottom.
    3. Player can jump left or right off a ladder.
    4. Player can jump onto a ladder by holding up or down when they're centered over the middle of it.
    It works, but it feels more like an enhackment rather than a clean change. I'm setting flags in the input handler to indicate the player is climbing, when I really want everything done in HandleCollisions(). That method is getting fairly messy, with IsOnGround, IsJumping and IsClimbing flags all over the place. I'd really like a playerState enum. There's also a single use of a wasClimbing flag, which is annoying. It also needs autocentering code so that when you press up and you're sort of over the ladder, it centers you. This is pretty simple at least.

    And finally, I haven't figured out a decent way of having a "climbing at the top of the ladder" animation as once the player is at the top of the ladder and is on the ground, the Idle animation takes over. The only thoughts I've got here are to add a queueing mechanism to the AnimationPlayer, so that you can queue the Idle animation after the top of ladder animation.

    I'm hoping Brandon Bloom is watching this thread - seems like ladders are a challenge for some of us.
  • 7/30/2009 12:17 AM In reply to

    Re: Adding ladders to the platform starter kit

    HadesSpaniel:
    I have ladders working as follows:
    1. Player can walk over a ladder tile onto a platform on the other side.
    2. Player can climb down a ladder and resume the correct state at the bottom.
    3. Player can jump left or right off a ladder.
    4. Player can jump onto a ladder by holding up or down when they're centered over the middle of it.
    It works, but it feels more like an enhackment rather than a clean change. I'm setting flags in the input handler to indicate the player is climbing, when I really want everything done in HandleCollisions(). That method is getting fairly messy, with IsOnGround, IsJumping and IsClimbing flags all over the place. I'd really like a playerState enum. There's also a single use of a wasClimbing flag, which is annoying. It also needs autocentering code so that when you press up and you're sort of over the ladder, it centers you. This is pretty simple at least.

    And finally, I haven't figured out a decent way of having a "climbing at the top of the ladder" animation as once the player is at the top of the ladder and is on the ground, the Idle animation takes over. The only thoughts I've got here are to add a queueing mechanism to the AnimationPlayer, so that you can queue the Idle animation after the top of ladder animation.

    I'm hoping Brandon Bloom is watching this thread - seems like ladders are a challenge for some of us.


    So, you have figured out a way to make ladders? and if your talking about my code, im sorry its not all tidy and neat and 100% polished.
    when im creating something, what my main objective is is to make it actually work, its all i care about, after i get it to work, thats when i can worry about the cleanliness and whatnot. after all, its not all about how the code works, its just that it works. do you take the time to look at crash bandicoots collisions methods? lol.
  • 7/30/2009 2:26 AM In reply to

    Re: Adding ladders to the platform starter kit

    LordKtulu:

    So, you have figured out a way to make ladders? and if your talking about my code, im sorry its not all tidy and neat and 100% polished.


    Yes, and no - I'm not talking about your code, I'm talking about mine :D
  • 7/30/2009 5:08 AM In reply to

    Re: Adding ladders to the platform starter kit

    HadesSpaniel:

    Yes, and no - I'm not talking about your code, I'm talking about mine :D

    So, yes to the ladder? or yes and no to the ladder?

    maybe you could possibly share your technique with the rest of us??? please? =D
  • 7/30/2009 6:15 AM In reply to

    Re: Adding ladders to the platform starter kit

    It was yes to the ladder, and no I wasn't talking about your code. I'm still cleaning things up, but I'll upload my project to RapidShare or somewhere in the next few days.
  • 7/30/2009 6:05 PM In reply to

    Re: Adding ladders to the platform starter kit

    HadesSpaniel:
    It was yes to the ladder, and no I wasn't talking about your code. I'm still cleaning things up, but I'll upload my project to RapidShare or somewhere in the next few days.


    omg sweetness! thanks
  • 7/31/2009 4:02 AM In reply to

    Re: Adding ladders to the platform starter kit

    I think I speak for both LordKtulu and myself when I say that if this works you will be in our debt.

    You know its really funny because almost all NES games have ladders in them at some point. Yet years later, we can't even figure out how they work! Anyone know where we can get a hold of some old NES programmers? anyone? anyone?

    Oh, well. For now I think I'm going to wait and see how this guy's solution works out. I think I'll work on the backgrounds for now. they need some major work.
  • 7/31/2009 4:54 AM In reply to

    Re: Adding ladders to the platform starter kit

    I've uploaded the following class files to pastebin:

     

    You'll need to create a ladder texture and add it to your project - same size tile as the others of course. This code is based on the Advanced section of the help pages, plus I've added in the vertical scrolling that Brandon Bloom described elsewhere in these forums. Ladders are denoted with "l" (lowercase L) in the map file. Most of the work is in Player.cs - I've converted a few floats to Vector2s along the way as well. There's still some work to do with the climbing animations as well, but the placeholders are there to cut your own animations in.

    Have a nice weekend.

  • 7/31/2009 2:31 PM In reply to

    Re: Adding ladders to the platform starter kit

    The only thing I don't like about this is that you can't walk off the ladder from the middle.
  • 7/31/2009 8:23 PM In reply to

    Re: Adding ladders to the platform starter kit

    Wow. It shocks me that I was nearly there. Only some subtle differences in the calculations. I'm going to test this out.

    And for the record. You can make it to where you can walk off the ladder. I suppose you would edit the collisions and whatnot to make it do that. doesn't look too hard but not what I need in my project although it is something to consider for future projects.
  • 7/31/2009 9:29 PM In reply to

    Re: Adding ladders to the platform starter kit

    HadesSpaniel:

    I've uploaded the following class files to pastebin:

     

    You'll need to create a ladder texture and add it to your project - same size tile as the others of course. This code is based on the Advanced section of the help pages, plus I've added in the vertical scrolling that Brandon Bloom described elsewhere in these forums. Ladders are denoted with "l" (lowercase L) in the map file. Most of the work is in Player.cs - I've converted a few floats to Vector2s along the way as well. There's still some work to do with the climbing animations as well, but the placeholders are there to cut your own animations in.

    Have a nice weekend.



    You might want to check your jump method, lol if you hold jump you continuously jump, but other than that looks like its getting somewhere. more quicker than my guy only making up a few steps lol.
  • 7/31/2009 11:25 PM In reply to

    Re: Adding ladders to the platform starter kit

    Celinedrules:
    The only thing I don't like about this is that you can't walk off the ladder from the middle.
    The only way to learn is to step through the code, experiment and try to understand what's going on. Have a look in ApplyPhysics and see if you can identify where the player's horizontal movement is restricted if they're climbing a ladder.
  • 7/31/2009 11:29 PM In reply to

    Re: Adding ladders to the platform starter kit

    LordKtulu:

    You might want to check your jump method, lol if you hold jump you continuously jump, but other than that looks like its getting somewhere. more quicker than my guy only making up a few steps lol.

    Yep this was a consequence of my changing the jump flags around and using a "jumpRequested" flag instead. It sounded like you all wanted something for the weekend, so I just uploaded my current snapshot, warts and all. You can correct this by storing the previous keyboard/gamepad state and comparing on the next update cycle - the player can only jump if the jump key was released on a previous update.
  • 8/1/2009 12:30 AM In reply to

    Re: Adding ladders to the platform starter kit

    Ok I figured it out. Pretty simple. In the GetInput menthod you will have:

    if (keyboardState.IsKeyDown(Keys.Left) || keyboardState.IsKeyDown(Keys.A)) 

         movement.X = -1.0f;
         if (level.GetTileCollisionBelowPlayer(level.Player.Position) == TileCollision.Passable)
         {
              isClimbing = false;
              isJumping = false;
              isOnGround = false;
         }
    }
    else if (keyboardState.IsKeyDown(Keys.Right) || keyboardState.IsKeyDown(Keys.D)) 
         movement.X = 1.0f; 
     
         if (level.GetTileCollisionBelowPlayer(level.Player.Position) == TileCollision.Passable) 
         { 
              isClimbing = false
              isJumping = false
              isOnGround = false
         } 

    and in the ApplyPhysics change this:

    if (!isClimbing) 
         if (wasClimbing) 
              velocity.Y = 0; 
         else 
              velocity.Y = MathHelper.Clamp(velocity.Y + GravityAcceleration * elapsed, -MaxFallSpeed, MaxFallSpeed); 
    else 
         velocity.Y = movement.Y * MoveAcceleration * elapsed; 
                 
    velocity.X += movement.X * MoveAcceleration * elapsed; 


Page 1 of 2 (34 items) 1 2 Next > Previous Next