Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Need help getting a child object to orbit a parent object ...


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
19 replies to this topic

#1 RoyP   Members   -  Reputation: 202

Like
0Likes
Like

Posted 01 January 2013 - 01:28 PM

I'm trying to figure out how to make a child object orbit around a parent object.  In my situation, I'm trying to create a parent ship that rotates waypoints with it when it rotates.  A smaller child ship will park itself in a waypoint to maintain it's position within the fleet.  

 

Here are a couple of images showing what I'm going for:

 

io0tbm.png 33kd3s6.png 

 

The child ship must keep it's position relative to the parent ship so it maintains it's position within the fleet.

 

i've tried learning enough about matrices to do it, but I'm screwing something up.  I've got my child ship orbiting the origin point of the screen instead of the parent ship.

 

Here's the code I'm using when I press a key:

parentShipRotationRadians += MathHelper.ToRadians(15);
childShipRotationRadians += MathHelper.ToRadians(15);
                    
Matrix.CreateRotationZ(parentShipRotationRadians, out childShipRotationMatrix);

childShipPositionPoint = Vector2.Transform(childShipPositionPoint, childShipRotationMatrix);

 

 

How do I rotate the child ship's center point around the parent ship's center point with matrices?  

 

Please break it down for me and help me understand what you're doing.  I've tried researching it and I just can't find the info.

 

Roy


Northwest Arkansas Game Developer Group
Live in Fayetteville, Springdale, Bentonville, or Rogers?

Interested in making video games and having fun?
Check us out on Meetup.

Sponsor:

#2 NewDisplayName   Members   -  Reputation: 359

Like
0Likes
Like

Posted 01 January 2013 - 10:59 PM

This looks like a conceptual glitch.

The worldview for your parentship should not be the same as for your child ship, for what you're trying to achieve.

Remember that your childship has a worldview dependency on the way parentship gets projected.

In short, the worldview matrix of childship keeps changing according to parentship view matrix.



#3 RoyP   Members   -  Reputation: 202

Like
0Likes
Like

Posted 02 January 2013 - 09:34 AM

I'm not doing anything with a matrix for the parent ship.  I'm just assigning it's rotation a value in the Update method and using that value to change the angle the texture is rendered at in the Draw method.  The parent ship's texture is just rotating at the center point of the screen.

 

Roy


Northwest Arkansas Game Developer Group
Live in Fayetteville, Springdale, Bentonville, or Rogers?

Interested in making video games and having fun?
Check us out on Meetup.

#4 NewDisplayName   Members   -  Reputation: 359

Like
0Likes
Like

Posted 02 January 2013 - 09:42 AM

I'm not doing anything with a matrix for the parent ship.

 

That's why I am saying that you need to do something about it, to achieve what you're looking for. In mathematical terms, what you need to implement is something like Lorentz Transformation.



#5 RoyP   Members   -  Reputation: 202

Like
0Likes
Like

Posted 02 January 2013 - 09:46 AM

So how would I go about doing that?  This is my first adventure with matrices, so I need some help understanding what I'm supposed to do and why.

 

Roy


Northwest Arkansas Game Developer Group
Live in Fayetteville, Springdale, Bentonville, or Rogers?

Interested in making video games and having fun?
Check us out on Meetup.

#6 NewDisplayName   Members   -  Reputation: 359

Like
0Likes
Like

Posted 02 January 2013 - 09:51 AM

Well, your parent ship's view matrix should become the world matrix of the child ship, where origin for child ship's world view will be the centre of parent ship.



#7 RoyP   Members   -  Reputation: 202

Like
0Likes
Like

Posted 02 January 2013 - 09:54 AM

Ok, I understand what you're saying conceptually.  How do I actually implement that in XNA?  Can you break it down step-by-step for me?  It would really help me learn it since this is my first time doing anything like this.

 

Roy


Northwest Arkansas Game Developer Group
Live in Fayetteville, Springdale, Bentonville, or Rogers?

Interested in making video games and having fun?
Check us out on Meetup.

#8 NewDisplayName   Members   -  Reputation: 359

Like
0Likes
Like

Posted 02 January 2013 - 10:00 AM

Ok, please share the code you have so far.



#9 RoyP   Members   -  Reputation: 202

Like
0Likes
Like

Posted 02 January 2013 - 10:17 AM

Here's the class code from my Game1.cs file.  The only thing I left out was the using statements and the namespace.

 

public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        float inputDelay;
        float maxInputDelay = 0.2f;

        Texture2D shipTexture;
        Vector2 shipTextureOriginPoint;
        
        Texture2D dotTexture;
        Vector2 dotTextureOriginPoint;

        Vector2 dotPositionPoint;

        Vector2 parentShipPositionPoint;
        float parentShipRotationRadians;
        
        Vector2 childShipPositionPoint;
        float childShipRotationRadians;
        Matrix childShipMatrix;
        Matrix childShipRotationMatrix;        
        
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
 
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 720;
            IsMouseVisible = true;

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

            // TODO: use this.Content to load your game content here
            shipTexture = Content.Load<Texture2D>(@"textures\ship_with_outline");
            dotTexture = Content.Load<Texture2D>(@"textures\dot");

            shipTextureOriginPoint = new Vector2(shipTexture.Width / 2, shipTexture.Height / 2);
            dotTextureOriginPoint = new Vector2(dotTexture.Width / 2, dotTexture.Height / 2);

            dotPositionPoint = new Vector2(GraphicsDevice.Viewport.Width / 2, 
                                           GraphicsDevice.Viewport.Height / 2);

            parentShipPositionPoint = new Vector2(GraphicsDevice.Viewport.Width / 2,                      
                                                  GraphicsDevice.Viewport.Height / 2);
            parentShipRotationRadians = 0;

            childShipPositionPoint = new Vector2(parentShipPositionPoint.X - 47, 
                                                 parentShipPositionPoint.Y - 47);
            childShipRotationRadians = 0;

            childShipMatrix = new Matrix();
            childShipMatrix.Translation = new Vector3(childShipPositionPoint.X, 
                                                      childShipPositionPoint.Y, 
                                                      0);

            childShipRotationMatrix = new Matrix();            
        }
                
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }
                
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here
            if (inputDelay > 0)
                inputDelay -= (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (inputDelay < 0)
                inputDelay = 0;

            if (inputDelay == 0)
            {
                if (Keyboard.GetState().IsKeyDown(Keys.Right))
                {
                    parentShipRotationRadians += MathHelper.ToRadians(15);
                    childShipRotationRadians += MathHelper.ToRadians(15);
                                                            
                    Matrix.CreateRotationZ(parentShipRotationRadians, out childShipRotationMatrix);

                    childShipPositionPoint = Vector2.Transform(childShipPositionPoint, 
                                                               childShipRotationMatrix);
                                        
                    inputDelay = maxInputDelay;
                }       
            }

            base.Update(gameTime);
        }
                
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            // TODO: Add your drawing code here
            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);

            spriteBatch.Draw(dotTexture, 
                             dotPositionPoint, 
                             null, 
                             Color.Yellow, 
                             0, 
                             dotTextureOriginPoint, 
                             0.6f, 
                             SpriteEffects.None, 
                             0.001f);

            spriteBatch.Draw(shipTexture, 
                             parentShipPositionPoint, 
                             null, 
                             Color.BlueViolet, 
                             parentShipRotationRadians, 
                             shipTextureOriginPoint, 
                             2.0f, 
                             SpriteEffects.None, 
                             0.301f);

            spriteBatch.Draw(shipTexture, 
                             childShipPositionPoint, 
                             null, 
                             Color.Orange, 
                             childShipRotationRadians, 
                             shipTextureOriginPoint, 
                             1.0f, 
                             SpriteEffects.None, 
                             0.300f);

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }

 

I basically want to rotate the parent ship by 15 degrees when I press the right key and have the child ship stay in the correct formation to it.  I also want to rotate the parent ship by -15 degrees when I press the left key and have the child ship stay in the correct formation to it.

 

This is just a really simple sandbox I'm using to learn how to implement this.

 

Roy


Northwest Arkansas Game Developer Group
Live in Fayetteville, Springdale, Bentonville, or Rogers?

Interested in making video games and having fun?
Check us out on Meetup.

#10 NewDisplayName   Members   -  Reputation: 359

Like
0Likes
Like

Posted 02 January 2013 - 10:41 AM

Try changing shipTextureOriginPoint to dotTextureOriginPoint in below code and let me know what you see is as per your requirement or no. Snapshot would be nice.

 

spriteBatch.Draw(shipTexture, 
                             childShipPositionPoint, 
                             null, 
                             Color.Orange, 
                             childShipRotationRadians, 
                             shipTextureOriginPoint, // Change this one
                             1.0f, 
                             SpriteEffects.None, 
                             0.300f);


#11 NewDisplayName   Members   -  Reputation: 359

Like
0Likes
Like

Posted 02 January 2013 - 10:46 AM

Or, I think your can comment out this line of code and try once :

 

childShipRotationRadians += MathHelper.ToRadians(15);



#12 RoyP   Members   -  Reputation: 202

Like
0Likes
Like

Posted 02 January 2013 - 10:46 AM

That's not going to do anything.  Those are just the center points on the actual textures themselves so I can rotate the texture around the texture's center point instead of the top left corner.  They have nothing to do with world space.  The coordinates that deal with the ship positions in world space are childShipPositionPoint and parentShipPositionPoint.

 

Roy 


Northwest Arkansas Game Developer Group
Live in Fayetteville, Springdale, Bentonville, or Rogers?

Interested in making video games and having fun?
Check us out on Meetup.

#13 RoyP   Members   -  Reputation: 202

Like
0Likes
Like

Posted 02 January 2013 - 10:49 AM

Or, I think your can comment out this line of code and try once :

 

childShipRotationRadians += MathHelper.ToRadians(15);

 

That just rotates the texture itself, so commenting it out just keeps the child ship pointing straight up.  It doesn't affect it's position in world space, so the child ship is still rotating around the 0,0 world origin.

 

Roy


Northwest Arkansas Game Developer Group
Live in Fayetteville, Springdale, Bentonville, or Rogers?

Interested in making video games and having fun?
Check us out on Meetup.

#14 NewDisplayName   Members   -  Reputation: 359

Like
0Likes
Like

Posted 02 January 2013 - 10:53 AM

Sorry bud, can't help out much unless I can figure out the exact outcome you desire.

You're telling me that this code will do this and that code will do that, where I am expecting that this is what you're looking for.

Well, I tried my best and gave you the exact concepts to solve the problem.

ow you might have to do some digging on your own and build up on the solution yourself.

Goodluck!



#15 RoyP   Members   -  Reputation: 202

Like
0Likes
Like

Posted 02 January 2013 - 12:07 PM

Let me try explaining exactly what I'm trying to do.  I might not be making it as clear as I thought.

 

Here's an image showing what I'm trying to do:

 

33ngf2t.jpg

 

The purple ship is the parent ship.  The orange ship is the child ship.

 

1 - I'm starting with a parent ship at (640, 320) in world space (center of the view port).  I set the child ship's position with an offset of (-47, -47) from the parent ship's position.  Both ships start with a rotation of 0 degrees (I convert all the degrees to radians with the MathHelper.ToRadians method).  The only thing I do with the rotation amount is to use it for the SpriteBatch.Draw call in the game's Draw method and use it to pass the rotation value to the Matrix.CreateRotationZ method.

 

2 - When I hit the right arrow, I want to rotate the parent ship 15 degrees clockwise and compute the new center point for the child ship in relation to the parent ship.  The goal is to have the child ship rotate with the parent ship while maintaining it's position within the fleet.  (My eventual goal is to turn the concept into a waypoint system so I can park different child ships at the waypoints.)

 

3 to 7 -  I need to repeat step 2 over and over again, so that the child ship keeps orbiting the parent ship while maintaining it's fleet formation.  I want it to orbit in a complete circle.

 

When I press the left arrow key, I want to do the same thing, but in the counter clockwise direction.

 

Does that make it any clearer?

 

I know that I need to use matrix transformations to do it, but I need help understanding how to actually do the matrix transformations.  I've never done it before and I need someone to walk me through it step-by-step so that I can learn what I'm doing.

 

I have a basic understanding of matrix and vector math, but I'm having trouble applying the abstract concepts to a concrete implementation in XNA.

 

Roy


Edited by RoyP, 02 January 2013 - 12:13 PM.

Northwest Arkansas Game Developer Group
Live in Fayetteville, Springdale, Bentonville, or Rogers?

Interested in making video games and having fun?
Check us out on Meetup.

#16 FromShadow   Members   -  Reputation: 145

Like
2Likes
Like

Posted 02 January 2013 - 06:44 PM

What you have to do is transform the difference vector between parent and child, not the child position itself.

Rotations matrices always rotate about the origin, so the easiest thing is to (temporarily) change your coordinate system so the parent ship's position is the origin:

 

 

Vector2 d = childShipPositionPoint - parentShipPositionPoint;
d = Vector2.Transform(d, Matrix.CreateRotationZ(15));
childShipPositionPoint = parentShipPositionPoint + d;

 

Let me know if this is what you are looking for.



#17 NewDisplayName   Members   -  Reputation: 359

Like
0Likes
Like

Posted 02 January 2013 - 10:18 PM

It might be just me, but even now, the snapshot that you have provided and your problem statement seem to be complementing each other.

In simple words, I think you're trying to achieve what you already have in this snapshot.

Perhaps, an altered snapshot with expected behaviour might help.



#18 FromShadow   Members   -  Reputation: 145

Like
0Likes
Like

Posted 03 January 2013 - 05:15 AM

It might be just me, but even now, the snapshot that you have provided and your problem statement seem to be complementing each other.

In simple words, I think you're trying to achieve what you already have in this snapshot.

Perhaps, an altered snapshot with expected behaviour might help.

 

The snapshot shows the expected behaviour. He wrote that the parent ship rotates about the origin instead.



#19 NewDisplayName   Members   -  Reputation: 359

Like
0Likes
Like

Posted 03 January 2013 - 06:15 AM

Oh I see now. My bad for being blind there.

Can you try to write your own CreateRotationZ method? Check out this post -- http://www.gamedev.net/topic/636093-2d-camera-transformation/



#20 RoyP   Members   -  Reputation: 202

Like
0Likes
Like

Posted 03 January 2013 - 08:02 AM

@FromShadow ... you are a genius. :-)  It does exactly what I needed.  Thanks for explaining it to me and providing the code to do it. 

 

@NewDisplayName ... thanks for trying to help.  I appreciate it.

 

Roy


Northwest Arkansas Game Developer Group
Live in Fayetteville, Springdale, Bentonville, or Rogers?

Interested in making video games and having fun?
Check us out on Meetup.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS