我正在使用 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;
}
}