Making a scrolling space shooting video game in C# where the player will fight one on one with their opponent. I was able to figure out how to make the missile go up if the opponent was above the player. But, I can't seem to make it work if the opponent is below or right infront of the player. Can someone help me? I know the answer is right under my nose.

The function below handles the movement of the missile

 void movemissile()
        {
            foreach (Control y in this.Controls)
            {
                if (y is PictureBox && y.Tag == "missile") 
                {

                    //y.Left += 100;//x.Top -= 10;
                    if (y.Left > enemy.Left)//<100
                    {
                        y.Left += 10;
                        //this.Controls.Remove(y);
                    }

                    //plyer missile goes up if opponent is above
                    if (y.Top > enemy.Top)
                    {
                        y.Left += 10;
                        y.Top -= 20;
                        y.Left += 10;
                        //this.Controls.Remove(y);
                    }
                    y.Left += 100;//x.Top -= 10;
                    if (y.Top > enemy.Left)//<100
                    { 
                        this.Controls.Remove(y);
                    }
                }
            }
        }

        This function handles drawing the missile of the player for the game.
                void Missile()
        {
            PictureBox m = new PictureBox();
            m.SizeMode = PictureBoxSizeMode.AutoSize;
            m.Image = Properties.Resources.Missile1;
            m.BackColor = System.Drawing.Color.Transparent;
            m.Tag = "missile";
            m.Left = Player.Left + 100;//moves bullet left or right
            m.Top = Player.Top + 55;//55 is perfect
            this.Controls.Add(m);
            m.BringToFront();
        }

Dani AI

Generated

A few practical notes that build on the replies by and and target the specific symptoms you described.

Your main problems are (a) movement being overridden by an unconditional large X increment and (b) using integer math / control removals in-place, which hides subtle bugs. A more robust, frame-independent approach is to treat the missile as an object with a floating-point position and a velocity computed from the normalized vector toward the target. That keeps speed constant in every direction (so a diagonal path isn’t faster or slower) and avoids truncation when you divide coordinates.

Example pattern (keeps logic separate from controls, safe removal, avoids divide-by-zero):

// small Missile class sketch
class Missile
{
    public PictureBox Sprite;
    public float X, Y;
    public float Speed; // pixels per second

    public bool Update(PointF target, float dtSeconds)
    {
        float dx = target.X - X;
        float dy = target.Y - Y;
        float dist = (float)Math.Sqrt(dx*dx + dy*dy);
        if (dist < 4f) return true; // hit or close enough
        float nx = dx / dist;
        float ny = dy / dist;
        X += nx * Speed * dtSeconds;
        Y += ny * Speed * dtSeconds;
        Sprite.Location = new Point((int)(X + 0.5f), (int)(Y + 0.5f));
        return false;
    }
}

Practical tips:

  • Use center points (sprite.Left + sprite.Width/2) when forming target/launcher positions.
  • Protect against dist == 0 before normalizing.
  • Update missiles from a List<Missile> and remove after the loop (don’t remove inside foreach over Controls).
  • If you use a WinForms Timer, translate ticks into seconds (dt) or use a Stopwatch for smoother motion.
  • For collision, prefer Bounds.IntersectsWith or the distance threshold above rather than exact equality.

This approach is smoother than per-axis integer steps and will handle “below” or “directly in front” cases consistently while keeping the code more maintainable.

Recommended Answers

All 2 Replies

While I have some other thoughts about how to improve this code, my immediate thought regarding the left/right and up/down movements of the missile is something like so:

                if (y.Left > enemy.Left)
                {
                     y.Left += 10;
                }
                else if (y.Left < enemy.Left)
                {
                     y.Left -= 10;
                }
                else 
                {
                    // no change, stay on course
                }

                if (y.Top < enemy.Top)
                {
                     y.Top += 10;
                }
                else if (y.Top > enemy.Top)
                {
                     y.Top -= 10;
                }
                else 
                {
                    // no change, stay on course
                }
                if ((abs(y.Left - enemy.left) < 5) && (abs(y.Top - enemy.Top) < 5))
                {
                    // impact
                }

I suspect you've tried this already, however.

The first thing I'd suggest is, use m.Name = "missile", instead of Tag. This allows you to get rid of that loop and access the missile picturebox directly using indexing, PictureBox y = (PictureBox)this.Controls["missile"];

Instead of trying to calculate the trajectory of the missile, you can use the Location property of the player and the enemy to calculate the direction of the missile movement and have it step a portion of the path each time you call MoveMissile. Something like this should work:

    int missileStep { get; } = 10;
    void MoveMissile()
    {
        PictureBox missile = (PictureBox)Controls["missile"];
        int xOffset = (enemy.Location.X - player.Location.X) / missileStep;
        int yOffset = (enemy.Location.Y - player.Location.Y) / missileStep;
        missile.Location = new Point(missile.Location.X + xOffset, missile.Location.Y + yOffset);
        if (missile.Location == enemy.Location)
        {
            Controls.Remove(missile);
        }
    }

missileStep can set to the value which suits you best.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.