首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使多个机器人跟随玩家?

如何使多个机器人跟随玩家?
EN

Stack Overflow用户
提问于 2019-08-12 13:24:33
回答 2查看 127关注 0票数 0

我正在学习C #,我正在创造一个假想的游戏让我理解语言。我想要几个机器人跟随正在移动矩形的玩家,但是我只能移动播放器,但是自动机器人不能移动。

我真的研究了我能做些什么来移动这些机器人。我得出的结论是,我必须理解线程,这只会导致程序不崩溃。

我把我正在尝试的全部代码留在这里。

代码语言:javascript
复制
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;
                }
            }
        });                  
    }
}

正如你所看到的,我只能移动玩家,但是机器人不能移动,我能做什么来移动机器人呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-12 14:27:07

我认为计时在这里会更好地工作,并移除此时需要您完全理解线程的要求,因为它将为您处理细节。我假设您实际上希望机器人“跟随”,而不是只在Player移动时移动,如果玩家移动得很快,就会落在后面。

因此,要使用Timer,我将调整您的Bot类,如下所示,以删除线程的使用,并且只允许它朝着Follow方法中的播放器迈出一步,该方法将每100 as调用一次。注意,Rectangle是一个结构,所以它不是可变的--这就是为什么您的机器人不能移动--如果您执行以下操作:

代码语言:javascript
复制
Point bot = Rectangle.Location;
bot.X = 5;

您可能认为Rectangle.Location.X现在是5岁,但事实并非如此。所以我们用新的位置创建一个新的矩形。

代码语言:javascript
复制
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滴答。

代码语言:javascript
复制
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();
}
票数 0
EN

Stack Overflow用户

发布于 2019-08-12 14:51:48

Point是一个值类型(一个struct)。(在在.NET中,struct和class有什么区别?上阅读更多有关这方面的内容)

当你这么做的时候

代码语言:javascript
复制
Point bot = Rectangle.Location;
bot.X = i;

...you创建了一个本地点并对其进行了修改。这不会改变机器人矩形的位置。另外,矩形也是结构化的,所以您必须修改原始Bot的矩形,或者将一个新的矩形分配给Bot。

要修复,您可以替换:

代码语言:javascript
复制
bot.X = i;

...with...

代码语言:javascript
复制
this.rectangle.X = i;

并对.Y进行类似的更改(在所有for循环位置中)

把它拼出来:

代码语言:javascript
复制
        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;
                    }
                }
            });
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57462090

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档