我正在学习C #,我正在创造一个假想的游戏让我理解语言。我想要几个机器人跟随正在移动矩形的玩家,但是我只能移动播放器,但是自动机器人不能移动。
我真的研究了我能做些什么来移动这些机器人。我得出的结论是,我必须理解线程,这只会导致程序不崩溃。
我把我正在尝试的全部代码留在这里。
public partial class Form1 : Form
{
public enum Direction { Up, Down, Left, Right }
private Player player;
private List<Bot> bots;
public Form1()
{
InitializeComponent();
this.Paint += Form1_Paint;
this.KeyPreview = true;
this.KeyDown += Form1_KeyDown;
this.player = new Player(new Size(8, 8));
this.bots = new List<Bot>();
for (int i = 0; i < 30; i++)
{
Bot bot = new Bot(player, new Size(8, 8));
bot.Follow();
this.bots.Add(bot);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up:
player.Move(Direction.Up);
break;
case Keys.Down:
player.Move(Direction.Down);
break;
case Keys.Left:
player.Move(Direction.Left);
break;
case Keys.Right:
player.Move(Direction.Right);
break;
}
this.Invalidate();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
List<Rectangle> rs = new List<Rectangle>();
rs = this.bots.Select(x => x.Rectangle).ToList();
rs.Add(player.Rectangle);
if (rs.Count > 0)
{
e.Graphics.FillRectangles(new SolidBrush(Color.Red), rs.ToArray());
}
}
}
public class Player
{
private Rectangle rectangle;
public Rectangle Rectangle { get => rectangle; }
public Player(Size size)
{
this.rectangle = new Rectangle() { Size = size };
}
public void Move(Direction direction)
{
switch (direction)
{
case Direction.Up:
this.rectangle.Y -= 3;
break;
case Direction.Down:
this.rectangle.Y += 3;
break;
case Direction.Left:
this.rectangle.X -= 3;
break;
case Direction.Right:
this.rectangle.X += 3;
break;
default:
break;
}
}
}
public class Bot
{
private Rectangle rectangle;
private Player player;
public Rectangle Rectangle { get => rectangle; }
public Bot(Player player, Size size)
{
this.player = player;
this.rectangle = new Rectangle() { Size = size };
}
public void Follow()
{
Task.Run(() =>
{
while (true)
{
Point p = player.Rectangle.Location;
Point bot = rectangle.Location;
for (int i = bot.X; i < p.X; i += 2)
{
Thread.Sleep(100);
bot.X = i;
}
for (int i = bot.X; i > p.X; i -= 2)
{
Thread.Sleep(100);
bot.X = i;
}
for (int i = bot.Y; i < p.Y; i += 2)
{
Thread.Sleep(100);
bot.Y = i;
}
for (int i = bot.Y; i > p.Y; i -= 2)
{
Thread.Sleep(100);
bot.Y = i;
}
}
});
}
}正如你所看到的,我只能移动玩家,但是机器人不能移动,我能做什么来移动机器人呢?
发布于 2019-08-12 14:27:07
我认为计时在这里会更好地工作,并移除此时需要您完全理解线程的要求,因为它将为您处理细节。我假设您实际上希望机器人“跟随”,而不是只在Player移动时移动,如果玩家移动得很快,就会落在后面。
因此,要使用Timer,我将调整您的Bot类,如下所示,以删除线程的使用,并且只允许它朝着Follow方法中的播放器迈出一步,该方法将每100 as调用一次。注意,Rectangle是一个结构,所以它不是可变的--这就是为什么您的机器人不能移动--如果您执行以下操作:
Point bot = Rectangle.Location;
bot.X = 5;您可能认为Rectangle.Location.X现在是5岁,但事实并非如此。所以我们用新的位置创建一个新的矩形。
public class Bot
{
private Player player;
public Rectangle Rectangle { get; set; }
public Bot(Player player, Size size)
{
this.player = player;
this.Rectangle = new Rectangle() { Size = size };
}
public void Follow()
{
Point p = player.Rectangle.Location;
Point bot = Rectangle.Location;
for (int i = bot.X + 2; i < p.X;)
{
bot.X = i;
break;
}
for (int i = bot.X - 2; i > p.X;)
{
bot.X = i;
break;
}
for (int i = bot.Y + 2; i < p.Y;)
{
bot.Y = i;
break;
}
for (int i = bot.Y - 2; i > p.Y;)
{
bot.Y = i;
break;
}
Rectangle = new Rectangle(bot, player.Rectangle.Size);
}
}并添加以下代码来替换现有的构造函数,并添加另一种方法来处理Timer滴答。
private Timer timer;
public Form1()
{
InitializeComponent();
this.Paint += Form1_Paint;
this.KeyPreview = true;
this.KeyDown += Form1_KeyDown;
// setup a timer which will call Timer_Tick every 100ms
timer = new System.Windows.Forms.Timer();
timer.Interval = 100;
timer.Tick += Timer_Tick;
timer.Start();
this.player = new Player(new Size(8, 8));
this.bots = new List<Bot>();
for (int i = 0; i < 30; i++)
{
Bot bot = new Bot(player, new Size(8, 8));
bot.Follow();
this.bots.Add(bot);
}
}
private void Timer_Tick(object sender, System.EventArgs e)
{
foreach (var bot in bots)
bot.Follow();
this.Invalidate();
}发布于 2019-08-12 14:51:48
Point是一个值类型(一个struct)。(在在.NET中,struct和class有什么区别?上阅读更多有关这方面的内容)
当你这么做的时候
Point bot = Rectangle.Location;
bot.X = i;...you创建了一个本地点并对其进行了修改。这不会改变机器人矩形的位置。另外,矩形也是结构化的,所以您必须修改原始Bot的矩形,或者将一个新的矩形分配给Bot。
要修复,您可以替换:
bot.X = i;...with...
this.rectangle.X = i;并对.Y进行类似的更改(在所有for循环位置中)
把它拼出来:
public void Follow()
{
Task.Run(() =>
{
while (true) {
Point p = player.Rectangle.Location;
Point bot = rectangle.Location;
for (int i = bot.X; i < p.X; i += 2) {
Thread.Sleep(100);
this.rectangle.X = i;
}
for (int i = bot.X; i > p.X; i -= 2) {
Thread.Sleep(100);
this.rectangle.X = i;
}
for (int i = bot.Y; i < p.Y; i += 2) {
Thread.Sleep(100);
this.rectangle.Y = i;
}
for (int i = bot.Y; i > p.Y; i -= 2) {
Thread.Sleep(100);
this.rectangle.Y = i;
}
}
});
}https://stackoverflow.com/questions/57462090
复制相似问题