我正在使用 Head First C# 书学习 C#。在构建 Greyhound Racing 游戏的第一个实验室中,我遇到了一些行为,但我不明白为什么我的代码会以这种方式呈现。在第一次点击 Race 按钮时,马匹会跑到赛道的尽头,但它们会被渲染成它们各自在它们身后创建一条先前图像的轨迹,直到它们到达赛道的尽头,而先前的图像最终消失了。在随后单击 Race 按钮时,会发生同样的事情,但它也无法从终点线擦除每只狗的 PictureBox,直到当前比赛完成。

这是一个简短的 19 秒视频,演示了我的意思:尾随图像示例
为什么狗在比赛中会“尾随”,为什么在下一场比赛完成之前,它们在重新开始时没有从终点线消失?我认为当狗被重新定位时,TakeStartingPosition()它们会被移动,而不是重新绘制。与 相同Run(),我认为每个新位置都是一个动作,而不是重绘,但它似乎在每个动作步骤都重绘图像,直到比赛结束才抹掉旧位置。我做错了什么?
灰狗.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RaceTrackSimulator
{
    class Greyhound
    {
        public int StartingPosition;
        public int RacetrackLength;
        public PictureBox MyPictureBox = null;
        public int Location = 0;
        public Random Randomizer;
        public bool Run()
        {
            // Move forward either 1, 2, 3 or 4 spaces at random
            int moveSpaces = Randomizer.Next(1, 4);
            // Update the position of my Picturebox on the form like this:
            //  MyPictureBox.Left = StartingPosition + Location;
            MyPictureBox.Left = StartingPosition + Location;
            // Return true if I won the race
            if (Location >= RacetrackLength)
            {
                return true;
            }
            else
            {
                Location += moveSpaces;
                return false;
            }
        }
        public void TakeStartingPosition()
        {
            // Reset my location to 0 and my PictureBox to starting position
            Location = 0;
            MyPictureBox.Left = StartingPosition;
        }
    }
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RaceTrackSimulator
{
    public partial class Form1 : Form
    {
        Greyhound[] Dogs;
        public Form1()
        {
            InitializeComponent();
            Random MyRandomizer = new Random();
            // Initialize Dogs
            Dogs = new Greyhound[4];
            Dogs[0] = new Greyhound()
            {
                MyPictureBox = pictureBox2,
                StartingPosition = racetrackPictureBox.Left,
                RacetrackLength = racetrackPictureBox.Width - pictureBox2.Width,
                Randomizer = MyRandomizer
            };
            Dogs[1] = new Greyhound()
            {
                MyPictureBox = pictureBox3,
                StartingPosition = racetrackPictureBox.Left,
                RacetrackLength = racetrackPictureBox.Width - pictureBox3.Width,
                Randomizer = MyRandomizer
            };
            Dogs[2] = new Greyhound()
            {
                MyPictureBox = pictureBox4,
                StartingPosition = racetrackPictureBox.Left,
                RacetrackLength = racetrackPictureBox.Width - pictureBox4.Width,
                Randomizer = MyRandomizer
            };
            Dogs[3] = new Greyhound()
            {
                MyPictureBox = pictureBox5,
                StartingPosition = racetrackPictureBox.Left,
                RacetrackLength = racetrackPictureBox.Width - pictureBox5.Width,
                Randomizer = MyRandomizer
            };
        }
        private void raceButton_Click(object sender, EventArgs e)
        {
            bool winner = false;
            int winningDog = 0;
            for (int eachDog = 0; eachDog < Dogs.Length; eachDog++)
            {
                Dogs[eachDog].TakeStartingPosition();
            }
            while (!winner)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (Dogs[i].Run())
                    {
                        winner = true;
                        winningDog = i+1;
                    }
                    System.Threading.Thread.Sleep(1);
                }
            }
            MessageBox.Show("Winning Dog is #" + winningDog);
        }
    }
}
Form1.Designer.cs
namespace RaceTrackSimulator
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.pictureBox2 = new System.Windows.Forms.PictureBox();
            this.racetrackPictureBox = new System.Windows.Forms.PictureBox();
            this.pictureBox3 = new System.Windows.Forms.PictureBox();
            this.pictureBox4 = new System.Windows.Forms.PictureBox();
            this.pictureBox5 = new System.Windows.Forms.PictureBox();
            this.raceButton = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.racetrackPictureBox)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox5)).BeginInit();
            this.SuspendLayout();
            // 
            // pictureBox2
            // 
            this.pictureBox2.Image = global::RaceTrackSimulator.Properties.Resources.dog;
            this.pictureBox2.Location = new System.Drawing.Point(13, 22);
            this.pictureBox2.Name = "pictureBox2";
            this.pictureBox2.Size = new System.Drawing.Size(75, 20);
            this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.pictureBox2.TabIndex = 2;
            this.pictureBox2.TabStop = false;
            // 
            // racetrackPictureBox
            // 
            this.racetrackPictureBox.Image = global::RaceTrackSimulator.Properties.Resources.racetrack;
            this.racetrackPictureBox.Location = new System.Drawing.Point(13, 12);
            this.racetrackPictureBox.Name = "racetrackPictureBox";
            this.racetrackPictureBox.Size = new System.Drawing.Size(600, 200);
            this.racetrackPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.racetrackPictureBox.TabIndex = 0;
            this.racetrackPictureBox.TabStop = false;
            // 
            // pictureBox3
            // 
            this.pictureBox3.Image = global::RaceTrackSimulator.Properties.Resources.dog;
            this.pictureBox3.Location = new System.Drawing.Point(13, 74);
            this.pictureBox3.Name = "pictureBox3";
            this.pictureBox3.Size = new System.Drawing.Size(75, 20);
            this.pictureBox3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.pictureBox3.TabIndex = 3;
            this.pictureBox3.TabStop = false;
            // 
            // pictureBox4
            // 
            this.pictureBox4.Image = global::RaceTrackSimulator.Properties.Resources.dog;
            this.pictureBox4.Location = new System.Drawing.Point(13, 126);
            this.pictureBox4.Name = "pictureBox4";
            this.pictureBox4.Size = new System.Drawing.Size(75, 20);
            this.pictureBox4.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.pictureBox4.TabIndex = 4;
            this.pictureBox4.TabStop = false;
            // 
            // pictureBox5
            // 
            this.pictureBox5.Image = global::RaceTrackSimulator.Properties.Resources.dog;
            this.pictureBox5.Location = new System.Drawing.Point(13, 178);
            this.pictureBox5.Name = "pictureBox5";
            this.pictureBox5.Size = new System.Drawing.Size(75, 20);
            this.pictureBox5.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.pictureBox5.TabIndex = 5;
            this.pictureBox5.TabStop = false;
            // 
            // raceButton
            // 
            this.raceButton.Location = new System.Drawing.Point(538, 377);
            this.raceButton.Name = "raceButton";
            this.raceButton.Size = new System.Drawing.Size(75, 23);
            this.raceButton.TabIndex = 6;
            this.raceButton.Text = "RACE!";
            this.raceButton.UseVisualStyleBackColor = true;
            this.raceButton.Click += new System.EventHandler(this.raceButton_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(625, 412);
            this.Controls.Add(this.raceButton);
            this.Controls.Add(this.pictureBox5);
            this.Controls.Add(this.pictureBox4);
            this.Controls.Add(this.pictureBox3);
            this.Controls.Add(this.pictureBox2);
            this.Controls.Add(this.racetrackPictureBox);
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.racetrackPictureBox)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox5)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();
        }
        #endregion
        private System.Windows.Forms.PictureBox racetrackPictureBox;
        private System.Windows.Forms.PictureBox pictureBox2;
        private System.Windows.Forms.PictureBox pictureBox3;
        private System.Windows.Forms.PictureBox pictureBox4;
        private System.Windows.Forms.PictureBox pictureBox5;
        private System.Windows.Forms.Button raceButton;
    }
}