Я изучаю C# по книге Head First C#. В первой лабораторной работе при создании игры Greyhound Racing я столкнулся с некоторым поведением, и я не понимаю, почему мой код отображается так, как есть. При первом нажатии кнопки «Гонка» лошади мчатся к концу дорожки, но они визуализируются таким образом, что каждая из них создает за собой след из предыдущих изображений, пока не достигнет конца дорожки, после чего предыдущие изображения окончательно исчезают. При последующих нажатиях кнопки «Гонка» происходит то же самое, но также не удается стереть 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;
}
}