title: Making Kitty Cannon in Monogame, how do I align a cannonball with its cannon?
body: <p>As the title says, I'm trying to make a simple 2D game similar to Kitty Cannon in Monogame. However I'm having trouble with aligning the cannonball with the pipe, since it's rotatable. How do I connect the cannonball's spawn point with the correct angle and position?
  I'm posting the code I currently have below, hope it's understandable!</p>
  <pre><code>class CannonBallSprite
  {
      private Texture2D texture;public bool shootingActive = false;
      public bool shootCannon = false;
      public bool keyPressed = false;
  
      public Vector2 position;
      public Vector2 origin;
      public Vector2 speed = new Vector2(0, 0.1f);
      public Vector2 originalSpeed = new Vector2(0, 0.1f);
      public Vector2 angle; //Trajectory
      public float scale;
      public float minPower = 10;
      public float maxPower = 15;
      public float power = 10;
  
      public CannonBallSprite(Texture2D texture)
      {
          this.texture = texture;
      }
  
      public void Update(float rotation, Sprite sprite)
      {
  
          if (Keyboard.GetState().IsKeyDown(Keys.Left) &amp;&amp; power &gt; minPower &amp;&amp; !keyPressed)
          {
              power -= 1;
              keyPressed = true;
          }
          else if (Keyboard.GetState().IsKeyDown(Keys.Right) &amp;&amp; power &lt; maxPower &amp;&amp; !keyPressed)
          {
              power += 1;
              keyPressed = true;
          }
  
          if (Keyboard.GetState().IsKeyUp(Keys.Left) &amp;&amp; keyPressed)
          {
              System.Threading.Thread.Sleep(300);
              keyPressed = false;
          }
          else if(Keyboard.GetState().IsKeyUp(Keys.Right) &amp;&amp; keyPressed)
          {
              System.Threading.Thread.Sleep(300);
              keyPressed = false;
          }
  
          if (Keyboard.GetState().IsKeyDown(Keys.Space) &amp;&amp; !shootingActive)
          {
              position = new Vector2(107, 365);                                   // here maybe?
              sprite.hasHit = false;
              shootCannon = true;
          }
  
          if(shootCannon)
          {
              Move(angle, power);
  
              speed += new Vector2(0, 0.1f); //standard gravitation
              angle = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
                  Debug.Write(&quot;test&quot;);
  
              position += speed; //Definiera marken
          }
          else
          {
              speed = originalSpeed;
          }
  
      }
  
      public void Move(Vector2 rot, float shootPower)
      {
          position.X += rot.X * shootPower;
          position.Y += rot.Y * shootPower;
      }
  
      public void Draw(SpriteBatch spriteBatch)
      {
          spriteBatch.Draw(texture, position, null, Color.White, 0, origin, scale, SpriteEffects.None, 0f);
      }
  }
  </code></pre>
  <p>Game1 Class:</p>
  <pre><code> namespace CannonShoot
   {
      public class Game1 : Game
      {
          private GraphicsDeviceManager graphics;
          private SpriteBatch spriteBatch;
          private Texture2D cannon;
          private Texture2D cannonball;
          private Texture2D man;
          private SpriteFont font;
          private Sprite spriteCannon;
          private Sprite manSprite;
          private CannonBallSprite cannonBallSprite;
  
          public Game1()
          {
              graphics = new GraphicsDeviceManager(this);
              Content.RootDirectory = &quot;Content&quot;;
              IsMouseVisible = true;
          }
  
          protected override void Initialize()
          {
              base.Initialize();
          }
  
          protected override void LoadContent()
          {
              spriteBatch = new SpriteBatch(GraphicsDevice);
              font = Content.Load&lt;SpriteFont&gt;(&quot;fontfile&quot;);       
              cannon = Content.Load&lt;Texture2D&gt;(&quot;cannon&quot;);
              cannonball = Content.Load&lt;Texture2D&gt;(&quot;cannonball&quot;);
              man = Content.Load&lt;Texture2D&gt;(&quot;man&quot;);
  
              spriteCannon = new Sprite(cannon)
              {
                  position = new Vector2(100, 400),
                  origin = new Vector2(cannon.Width / 2, cannon.Height / 2),
                  scale = 0.12f
              };
  
              cannonBallSprite = new CannonBallSprite(cannonball)
              {
  
                  position = new Vector2(1150, 3750),
                  scale = 0.2f
              };
  
              manSprite = new Sprite(man)
              {
                  position = new Vector2(700, 250),
                  origin = new Vector2(man.Width / 2, man.Height / 2),
                  scale = 0.4f
              };
  
          }
  
          protected override void Update(GameTime gameTime)
          {
              if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                  Exit();
              
              if(!cannonBallSprite.shootCannon)
              {
                  spriteCannon.Update();
              }
  
              //cannonBallSprite = (spriteCannon.position.X, spriteCannon.position.Y); 
  
              cannonBallSprite.Update(spriteCannon.rotation, manSprite);
              manSprite.UpdateHitbox(cannonBallSprite);
  
              if(cannonBallSprite.position.X &gt;= 1000 || cannonBallSprite.position.Y &gt;= 600) //respawn
              {
                 
                  cannonBallSprite.shootCannon = false;
              }
  
              base.Update(gameTime);
          }
  
          protected override void Draw(GameTime gameTime)
          {
              GraphicsDevice.Clear(Color.CornflowerBlue);
  
              spriteBatch.Begin();
              spriteCannon.Draw(spriteBatch);
              manSprite.Draw(spriteBatch);
              cannonBallSprite.Draw(spriteBatch);
              spriteBatch.DrawString(font, &quot;Power: &quot; + cannonBallSprite.power, new Vector2(16, 16), Color.Black);
              spriteBatch.DrawString(font, &quot;Hits: &quot; + manSprite.hit, new Vector2(16, 62), Color.Black);
              spriteBatch.End();
  
              base.Draw(gameTime);
          }
      }
  }
  </code></pre>
  <p>Sprite class:</p>
  <pre><code>namespace CannonShoot
  {
      class Sprite
      {
          private Texture2D texture;
  
          public Vector2 position;
          public Vector2 origin;
          public float scale;
  
          public float rotationVelocity = 3f;
          public float linearVelocity = 4f;
  
          public float minRot = -1f;
          public float maxRot = 0f;
          public float rotation;
  
  
          public float hit = 0;
          public bool hasHit = false;
  
          public Sprite(Texture2D texture)
          {
              this.texture = texture;
          }
  
          public void Update()
          {
              if (rotation &lt;= maxRot &amp;&amp; rotation &gt;= minRot)
              {
                  if (Keyboard.GetState().IsKeyDown(Keys.Up))
                  {
                      rotation -= MathHelper.ToRadians(rotationVelocity);
  
                  }
                  else if (Keyboard.GetState().IsKeyDown(Keys.Down))
                  {
                      rotation += MathHelper.ToRadians(rotationVelocity);
  
                  }
  
                  if(rotation &lt; minRot)
                  {
                      rotation = minRot;
                  }
                  
                  if (rotation &gt; maxRot)
                  {
                      rotation = maxRot;
                  }
              }
  
             
          }
  
          public void UpdateHitbox(CannonBallSprite cbSprite) //hitbox och 
          {
              if(cbSprite.position.X &gt;= 700 &amp;&amp; cbSprite.position.Y &lt;= 350 &amp;&amp; cbSprite.position.Y &gt;= 150 &amp;&amp; !hasHit)
              {
                  hit++;
                  hasHit = true;
                  cbSprite.shootCannon = false;
              }
          }
  
          public void Draw(SpriteBatch spriteBatch)
          {
              spriteBatch.Draw(texture, position, null, Color.White, rotation, origin, scale, SpriteEffects.None, 0f);
          }
      }
  }
  </code></pre>