5 Replies - 4381 Views - Last Post: 10 April 2012 - 07:11 AM

#1 Hockeyrock93  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 08-April 12

Rotating while moving 2D sprite trouble

Posted 08 April 2012 - 03:06 PM

Hi, I am sorry if this is a very simple question, but I am not very experienced in the XNA framework. In my current 2D project, a very cool looking blue triangle, the player, moves around with WASD. He rotates with A and D, and does this very well. W and S increases his moving speed. However, I am having trouble getting him going in the right direction. I am trying to allow him to freely rotate and move forward at the same time, which does work. But, the problem is, he starts off moving to the right! When you start the game, he is frozen and facing up like he should be, then when you press W he goes to the right. From there you can rotate him and move him all you want, but he is going to the right. His starting rotation is 0, I have not previously rotated his texture. By messing around, I have reason to believe it happens in this area:

private void Movement()
        {
            float RadianAngle = MathHelper.ToRadians(RotationAngle);

            MovementX = (float)Math.Cos(RadianAngle);
            MovementY = (float)Math.Sin(RadianAngle);

            playerPosition.X += playerSpeed * MovementX;
            playerPosition.Y += playerSpeed * MovementY;
        } 


This is just so that I can determine the direction to move, however it probably isn't write. Also, in case you were wondering, I tried rotating the picture itself to the left so that it would at least go up, no luck, it then went backwards. I also tried rotating it in game to the left, then it went up, but with the triangle pointing left. When I rotate the picture to the right instead, it works, but I can't have my player starting facing to the right every level. Thanks for the help!

Is This A Good Question/Topic? 0
  • +

Replies To: Rotating while moving 2D sprite trouble

#2 DanielLeone  Icon User is offline

  • D.I.C Head

Reputation: 22
  • View blog
  • Posts: 177
  • Joined: 04-February 12

Re: Rotating while moving 2D sprite trouble

Posted 09 April 2012 - 04:03 AM

Hi there HockeyRock,

It is rather hard to define the exact point at which the issue is occurring in the code, so it might be and idea to post your entire Player class, or if you don't have one then just the Game1.cs, or whatever ;).

The method you currently have posted is rather irrelevant seen as you haven't shown us where RotationAngle is set, so it isn't of much use, but it is a common pattern used for movement.

So when you post more of your code I'll be happy to help, but until then I can't be of much assistance.

I can however recommend this video of a tutorial to do much the same as what you described.

http://www.youtube.c...JY8oi_G0imm9Ro=

http://www.youtube.c...8oi_G0imm9Ro%3D

Hope I've helped,
Daniel,
Was This Post Helpful? 0
  • +
  • -

#3 Hockeyrock93  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 08-April 12

Re: Rotating while moving 2D sprite trouble

Posted 09 April 2012 - 03:13 PM

Thanks for the response Daniel! The video did help me see another way of doing this, however what that person was trying to achieve wasn't as ambitious as my movement. He has it so that when you let go of your increase speed key, it continues on in that direction no matter which way you rotate it until you repress the key. Although I can think of a billion theories on how to take that and simply place the code in other places, nothing has worked. Here is a compilation of everything relevant to this problem, and thank you for your time!

public class Game1 : Microsoft.Xna.Framework.Game
    {
        Texture2D player;
        int playerSpeed = 0;
        float RotationAngle = 0;
        Vector2 playerOrigin = new Vector2(90, 90);
        KeyboardState oldState;
        float MovementX = 0;
        float MovementY = 0; 

        protected override void Initialize()
        {
            oldState = Keyboard.GetState(); //Retrieve old keyboard state
            base.Initialize();
        }
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            player = Content.Load<Texture2D>("BlueTriangle2");
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            UpdateInput();
            ControllingSpeed();
            Movement();            

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Gray);
            spriteBatch.Begin();
            spriteBatch.Draw(player, playerPosition, null, playerColor, MathHelper.ToRadians(RotationAngle), playerOrigin, playerScaling, SpriteEffects.None, playerDepth);
            spriteBatch.End();
            base.Draw(gameTime);
        }

        private void UpdateInput()
        {
            KeyboardState newState = Keyboard.GetState();

            if (newState.IsKeyDown(Keys.D))
            {
                if (!oldState.IsKeyDown(Keys.D))
                {
                    //Rotate player by playerTurning pre-determined speed
                    RotationAngle += playerTurning;
                }
                else if (oldState.IsKeyDown(Keys.D))
                {
                    //Key was down last update, but not down now, so it has been released, do nothing
                }
            }
            if (newState.IsKeyDown(Keys.A))
            {
                if (!oldState.IsKeyDown(Keys.A))
                {
                    //Rotate player by playerTurning pre-determined speed
                    RotationAngle -= playerTurning;
                }
                else if (oldState.IsKeyDown(Keys.A))
                {
                    //Key was down last update, but not down now, so it has been released, do nothing
                }
            }
            if (newState.IsKeyDown(Keys.W))
            {
                if (!oldState.IsKeyDown(Keys.W))
                {
                    playerSpeed += movementspeed; //increase by moving speed
                }
                else
                {
                    //Nothing happens
                }
            }
            if (newState.IsKeyDown(Keys.S))
            {
                if (!oldState.IsKeyDown(Keys.S))
                {
                        //Lower player speed
                        playerSpeed -= playerBrake; //decrease by slowing speed
                }
                else if (oldState.IsKeyDown(Keys.S))
                {
                        //Do nothing
                }
            }
        }
        
        private void ControllingSpeed()
        {
            if (playerSpeed > maxPlayerSpeed)
            {
                playerSpeed = maxPlayerSpeed;
            }

            if (playerSpeed < minPlayerSpeed)
            {
                playerSpeed = minPlayerSpeed;
            }
        }

        private void Movement()
        {
            //Change the degrees of RotationAngle to Radians in order to find the Cosine and sine
            float RadianAngle = MathHelper.ToRadians(RotationAngle);  

            //Determine the movement position to be added to playerPosition
            MovementX = (float)Math.Cos(RadianAngle);
            MovementY = (float)Math.Sin(RadianAngle);

            //Multiply speed by movement to get the new position!
            playerPosition.X += playerSpeed * MovementX;
            playerPosition.Y += playerSpeed * MovementY;
        }
        }



I've left out ALOT of irrelevant stuff (I don't want to put my whole project in).
Was This Post Helpful? 0
  • +
  • -

#4 DanielLeone  Icon User is offline

  • D.I.C Head

Reputation: 22
  • View blog
  • Posts: 177
  • Joined: 04-February 12

Re: Rotating while moving 2D sprite trouble

Posted 09 April 2012 - 06:28 PM

Okay I'm sorry to say that I can't seem to figure out where your code is going wrong simply from this.

So I created a whole new project and pasted your code in :D.
Many of the variables are not created in what you gave me, so I generated them with a single value, therefore my outcome may be somewhat different if these specific variables are changed elsewhere.

What I have discovered:
PlayerOrigin - depending on how you game functions might want to be set here. Just a pointer.

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);



            player = Content.Load<Texture2D>("BlueTriangle2");
            playerOrigin = new Vector2(player.Width / 2, player.Height / 2);
        }



Your WASD statements are quite messy, and use many pointless 'if' statements. Unless you have another use for the 'else' statements, I'd do it like this, but again up too you.

            if (newState.IsKeyDown(Keys.D) && oldState.IsKeyUp(Keys.D))
            {
                RotationAngle += playerTurning;
            }
            if (newState.IsKeyDown(Keys.A) && oldState.IsKeyUp(Keys.D))
            {
                RotationAngle -= playerTurning;
            }
            if (newState.IsKeyDown(Keys.W) && oldState.IsKeyUp(Keys.D))
            {
                playerSpeed += movementspeed;
            }
            if (newState.IsKeyDown(Keys.S) && oldState.IsKeyUp(Keys.S))
            {
                playerSpeed -= playerBrake;
            }



Unless MovementX and MovementY are set outside this code, or minPlayerSpeed has an initial value, then nothing will move.

Summarizing what you said, I presume minPlayerSpeed does infact have an initial value, lets say 1, so at the beginning of your game, you player will be moving 1 pixel per frame.

As for the direction your player is initially facing that is due to your RotationAngle having a default value of 0. Which means pointing right evidently, or it's changed at another point outside this class.

So I hope I've answered your question, and your realize why this was happening.
If you indeed want you player to start standing still and be able to stop at any point in the game, I believe I have some what fixed your problem.

If you wanted the player to start of still, but not be able to stop again, then I am sorry , but you may have to look into another variable or something ;).

This is the modified version of your code I made purely for your reference :

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace HockeyRocky
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Texture2D player;
        int playerSpeed = 0;
        float RotationAngle = 180;
        Vector2 playerOrigin;
        KeyboardState oldState;
        float MovementX = 0;
        float MovementY = 0;


        //Remember these are all generated by Daniel, so they may not be of the correct value.
        private Vector2 playerPosition = new Vector2(200,200);
        private int minPlayerSpeed = 0;
        private int maxPlayerSpeed = 4;
        private float playerTurning = 3f;
        private int playerBrake = 2;
        private int movementspeed = 3;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            oldState = Keyboard.GetState(); //Retrieve old keyboard state


            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);



            player = Content.Load<Texture2D>("BlueTriangle2");
            playerOrigin = new Vector2(player.Width / 2, player.Height / 2);
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            UpdateInput();

            ControllingSpeed();

            Movement();

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            spriteBatch.Draw(player, playerPosition, null, Color.White, MathHelper.ToRadians(RotationAngle), playerOrigin, 1f, SpriteEffects.None, 1f);

            spriteBatch.End();

            base.Draw(gameTime);
        }

        private void UpdateInput()
        {
            KeyboardState newState = Keyboard.GetState();

            if (newState.IsKeyDown(Keys.D) && oldState.IsKeyUp(Keys.D))
            {
                RotationAngle += playerTurning;
            }
            if (newState.IsKeyDown(Keys.A) && oldState.IsKeyUp(Keys.D))
            {
                RotationAngle -= playerTurning;
            }
            if (newState.IsKeyDown(Keys.W) && oldState.IsKeyUp(Keys.D))
            {
                playerSpeed += movementspeed;
            }
            if (newState.IsKeyDown(Keys.S) && oldState.IsKeyUp(Keys.S))
            {
                playerSpeed -= playerBrake;
            }
        }

        private void ControllingSpeed()
        {
            if (playerSpeed > maxPlayerSpeed)
            {
                playerSpeed = maxPlayerSpeed;
            }
            if (playerSpeed < minPlayerSpeed)
            {
                playerSpeed = minPlayerSpeed;
            }
        }

        private void Movement()
        {

            //Change the degrees of RotationAngle to Radians in order to find the Cosine and sine

            float RadianAngle = MathHelper.ToRadians(RotationAngle);


            //Determine the movement position to be added to playerPosition

            MovementX = (float)Math.Cos(RadianAngle);

            MovementY = (float)Math.Sin(RadianAngle);


            //Multiply speed by movement to get the new position!

            playerPosition.X += playerSpeed * MovementX;

            playerPosition.Y += playerSpeed * MovementY;

        }
    }
}




I now have a nicely function program to play with ;), and I must commend you on this, if you truely are new to XNA.

Hope I helped,
Daniel,

This post has been edited by DanielLeone: 09 April 2012 - 06:28 PM

Was This Post Helpful? 1
  • +
  • -

#5 Hockeyrock93  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 08-April 12

Re: Rotating while moving 2D sprite trouble

Posted 10 April 2012 - 03:57 AM

You did an amazing job of re-creating my project! I really appreciate the time you've put into helping me! I am glad that my movement code is a lot neater now too :) . And I have fixed the problem! It was a combination of a rotation problem in my picture, and a misplacement and incorrect value of playerOrigin (based on your help). It now moves around perfectly. Now to get a 2D camera working.
Was This Post Helpful? 0
  • +
  • -

#6 DanielLeone  Icon User is offline

  • D.I.C Head

Reputation: 22
  • View blog
  • Posts: 177
  • Joined: 04-February 12

Re: Rotating while moving 2D sprite trouble

Posted 10 April 2012 - 07:11 AM

Glad to be of assistance HockeyRock,

If you did want some help on your 2D Camera, I can recommend the same guy as the videos before, and another tutorial.

http://www.youtube.c...8oi_G0imm9Ro%3D

http://www.youtube.c...xnsssAPIkfyw%3D

One more thing about your breaking I found after posting the answer earlier. Changing both the playerSpeed and breaingSpeed to a float, and then setting breakingSpeed to something like 0.1f creates a nice velocity effect. But it's up too you what you do.

Thanks once again,
Daniel,
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1