Sign in to follow this  
Lunar180

Orienting a Ship With the Right Stick

Recommended Posts

I'm trying to make a 360 degree, two-dimensional shooter, but I can't figure out how to make a ship point in the direction that I point the right stick on a 360 controller. I'm programming in C# with XNA.

Share this post


Link to post
Share on other sites
Heya! Here's how...

#1 - Get the X and Y values of the stick
#2 - I believe they give you a "short" back (not a float) so convert the short to a float and map it from -1 to 1 on each axis. IE I forget what the max and min values it returns is but lets say it is -32767 to 32768. When you get a value back of say -1224, you divide it by 32768 to get -0.03
#3 - use Math.Atan2 to get the angle (in radians, not degrees) that they are pressing on the stick
#4 - rotate your sprite by this angle
#5 - PROFIT

(:

PS - if you are also using the stick to MOVE the player, you can use the 2 floats you got from the stick in step 2 as a vector of movement. Multiply those 2 floats by your maximum player movement speed and you have your X and Y movement vectors.

PPS - if you want to make your game feel more sophisticated, instead of setting the angle to the angle on the stick, interpolate the current angle to the angle of the stick... IE move the current angle to the destination angle over time (a small amount of time like 1/10th of a second). This will give it a more polished feeling and if the interpolation time is short enough it shouldn't interfere with game play.

Hope this helps!

Share this post


Link to post
Share on other sites
Since you are in XNA, your values are already from -1,1


Don't need to convert back to degrees, I beleive the spriteBatch.Draw call gets a radiant in parameter.
spriteBatch.Draw(yourSpriteTexture, position, ..., [float rotation] Math.Atan2(x, y), ...)

Share this post


Link to post
Share on other sites
Thanks, both of you, for the help. But I have another question. Why can't I get my projects to recognize when the BigButton is pressed? I thought the BigButton was the big button with the X on it on the center of the controller, but pushing that button didn't seem to have any effect. It didn't even go into the if statement I had for when the button is pushed.

Oh, and is there any code to close the Home menu? I'm trying to make the BigButton open and close the account menu.

EDIT: Oh, and I've come across a NullReferenceException that I can't figure out.
            tsb.Draw(shipTexture, location, null, Color.White, (float)angle, new Vector2(shipWidth * .5f, shipHeight * .5f), 1, SpriteEffects.None, 0f);



The literally "null" parameter is supposed to mean that I want to draw the entirety of my shipTexture, so I don't think that is what's causing my problem.

[Edited by - Lunar180 on February 24, 2010 12:29:50 PM]

Share this post


Link to post
Share on other sites
What is the class of tsb? What parameters is its .Draw function supposed to take?

Could shipTexture be null? Where does it come from?

Could location be null? (probably not; what type is it?)

Share this post


Link to post
Share on other sites
Ack, sorry. I forgot to mention those.
tsb is a temporary SpriteBatch, shipTexture wasn't null when I was in debug, and location was not null either (it is a Vector2)

I suppose it wouldn't hurt to just show the whole method
public override void Draw(GameTime gameTime)
{
shipHeight = shipTexture.Height;
shipWidth = shipTexture.Width;
SpriteBatch tsb = (SpriteBatch)mahGaem.Services.GetService(typeof(SpriteBatch));
tsb.Draw(shipTexture, location, null, Color.White, (float)angle, new Vector2(shipWidth * .5f, shipHeight * .5f), 1, SpriteEffects.None, 0f);

base.Draw(gameTime);
}




Draw (in this case) uses a Texture2D, Vector2 (position), Rectangle? (what section of texture, null if all), color (tint), float (rotation), Vector2 (origin), float (scale), SpriteEffects, float (layer depth)

Anything I've missed clarifying?

Share this post


Link to post
Share on other sites
I think the big button refers to the big button on the big button control pad. The one that came with Scene it. I don't think you can map the xbox button as Microsoft surely wants to keep it to themselves to access the mini-dash on the 360.

Could be wrong though.

Share this post


Link to post
Share on other sites
Quote:
Original post by Imgelling
I think the big button refers to the big button on the big button control pad. The one that came with Scene it. I don't think you can map the xbox button as Microsoft surely wants to keep it to themselves to access the mini-dash on the 360.

Could be wrong though.


Well, I was just trying to make the BigButton/XBox button open/close the mini-dash on the computer, but pushing it did nothing. Yeah, I'm not talking about sceneIt's big button pad. I tried looking up my problem before, and about 90% of my results were that.

Quote:
Original post by GWDev
Hi Lunar180,

if you don't know it already, you should read this:

MSDN Link ;

Is your project a windows or a xbox360 game?


- GWDev


Windows. Thinking about it, the BigButton would automatically have the regular function if I decide to convert to a 360 game. And that guide doesn't help me with my problem. I am using the BigButton property.

Share this post


Link to post
Share on other sites
In case it helps with my exception problem, here are the details from the debug.

System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="ShooterPrototype Mk I"
StackTrace:
at ShooterPrototype_Mk_I.Ship.Draw(GameTime gameTime) in M:\ShooterPrototype Mk I\ShooterPrototype Mk I\Ship.cs:line 72
at ShooterPrototype_Mk_I.PlayerShip.Draw(GameTime gameTime) in M:\ShooterPrototype Mk I\ShooterPrototype Mk I\PlayerShip.cs:line 66
at Microsoft.Xna.Framework.Game.Draw(GameTime gameTime)
at ShooterPrototype_Mk_I.Game1.Draw(GameTime gameTime) in M:\ShooterPrototype Mk I\ShooterPrototype Mk I\Game1.cs:line 104
at Microsoft.Xna.Framework.Game.DrawFrame()
at Microsoft.Xna.Framework.Game.Tick()
at Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
at Microsoft.Xna.Framework.GameHost.OnIdle()
at Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Microsoft.Xna.Framework.WindowsGameHost.Run()
at Microsoft.Xna.Framework.Game.Run()
at ShooterPrototype_Mk_I.Program.Main(String[] args) in M:\ShooterPrototype Mk I\ShooterPrototype Mk I\Program.cs:line 14
InnerException:

Share this post


Link to post
Share on other sites
Is it possible that I have a problem because I don't specify any SpriteSortMode? I don't know what it means, but it's my only idea so far.

Share this post


Link to post
Share on other sites
Wow, I am a moron. My friend pointed something out to me.

            SpriteBatch tsb = (SpriteBatch)mahGaem.Services.GetService(typeof(SpriteBatch));


Doesn't help when I forget to do this:
            Services.AddService(typeof(SpriteBatch), spriteBatch);



So it wasn't my Draw method that threw the exception, it was the lack of a SpriteBatch...

Share this post


Link to post
Share on other sites
And as for my rotation, it finally worked, but when I called Atan2, I had to make my first parameter (the y value) be negative whatever-it-was, and then had to add a 90 degree angle too it to make it all work. Am I doing something wrong?

Share this post


Link to post
Share on other sites
Quote:
Original post by Atrix256
Heya! Here's how...

#1 - Get the X and Y values of the stick

http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.gamepadthumbsticks_members.aspx

XNA gives you the location of the stick as a Vector2D.

then all you need to do is check the angle between the thumbstick and a vector on the X axis and you should have your radians of rotation.

http://www.wikihow.com/Find-the-Angle-Between-Two-Vectors

edit: and how did you get the guide button to work? It should be reserved.

http://msdn.microsoft.com/en-us/library/bb203941.aspx

Share this post


Link to post
Share on other sites
Quote:
Original post by way2lazy2care
edit: and how did you get the guide button to work? It should be reserved.


Technically, I didn't. It appears that the big button works the way I wanted it to all on its own, but only on a few of the computers in my school's computer lab. I don't know what's different to make it work, but BigButton pops up and closes the home menu on the computer I'm on now, which isn't the computer I work on most of the time.

In other words, it works on it's own, and I'm fine with that.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this