代码之家  ›  专栏  ›  技术社区  ›  user1937012

C第一节简单课

  •  0
  • user1937012  · 技术社区  · 8 年前

    所以我开始学C_(实际上这是我的第三天),我在左右拨弄它。

    所以我用 Console ,我创建了我的第一个非常简单的类

    using System.Timers;
    
    public class Star
    {
        private int x, y;
    
        public Star(int fx, int fy)
        {
            Create(fx, fy);
            Move();
        }
    
        private void Create(int fx, int fy)
        {
            this.x = fx;
            this.y = fy;
            Console.SetCursorPosition(this.x, this.y);
            Console.Write("*");
        }
        private void Move()
        {
            Timer aTimer = new Timer();
            aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            aTimer.Interval = 500;
            aTimer.AutoReset = false;
            aTimer.Start();
    
        }
        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            Console.SetCursorPosition(this.x, this.y);
            Console.Write(" ");
        }
    }
    

    }

    我有一个主程序循环,它执行不停地等待用户输入,它有不同的状态。

    while (true)
    {
        if (Mode == 0)
        {
            Console.SetCursorPosition(tX, tY);
            Console.BackgroundColor = ConsoleColor.Black;
            Console.Write("[ " + System.DateTime.Now + " ]");
    
            Cursor(Selection, OldSelection);
        }
        if (Mode == 2)
        {
            Random r = new Random();
    
            System.Threading.Thread.Sleep(500);
    
            for (int i = 0; i< 10; i++)
                Star myStar = new Star(r.Next(nScreenWidth), r.Next(nScreenHeight));
        }
    
    
        if (Console.KeyAvailable)
        {
            ConsoleKeyInfo keyInfo = Console.ReadKey(true);
    
            if (Mode == 0)
            {
                switch (keyInfo.Key)
                {
                    case ConsoleKey.DownArrow:
                        OldSelection = Selection;
    
                        if (Selection == 4) Selection = 0;
                        else Selection++;
                    break;
                    case ConsoleKey.UpArrow:
                        OldSelection = Selection;
    
                        if (Selection == 0) Selection = 4;
                        else Selection--;
                    break;
                    case ConsoleKey.Enter:
                        if (Selection == 0)
                        {
                            Console.Clear();
                            Mode = 1;
                        }
    
                        if (Selection == 1)
                        {
                            Console.Clear();
                            Mode = 2;
                        }
    
                        if (Selection == 4) return;
                    break;
                }
            }
    
            if (keyInfo.Key == ConsoleKey.Escape)
            {
                Console.Clear();
                MainMenu();
                Mode = 0;
            }
        }
    }
    

    我的问题是当我启动星星(模式2)时,它会随机显示星星,但如果我退出,对象不会立即死亡,它们的计时器仍在执行,它们正在定位光标位置,并扰乱主菜单。我可能这是件可怕的事,但我不知道是什么。

    当做 罗伯特

    最终工作示例

    在irc上聊了一会儿之后,我被告知最好使用一个定时器,因为我已经有一个主循环了。我这样修改了代码。

    一流的

       public class Star : IDisposable
        {
            public static int instances = 0;
    
            public Star(int fx, int fy)
            {
                Create(fx, fy);
                Animate();
            }
    
            int x, y, animpos;
    
            private void Create(int fx, int fy)
            {
                this.x = fx;
                this.y = fy;
                this.animpos = 0;
    
                instances++;
            }
    
            public void Animate()
            {
                Console.SetCursorPosition(this.x, this.y);
    
                switch (animpos)
                {
                    case 0:
                        {
                            Console.Write("+");
                        }
                        break;
                    case 1:
                        {
                            Console.Write("*");
                        }
                        break;
                    case 2:
                        {
                            Console.Write(".");
                        }
                        break;
                }
                animpos++;
                if (animpos == 3) { animpos = 0; }
            }
    
            public void Dispose()
            {
                instances--;
            }
        }
    

    然后是程序的主循环,只有相关部分:

            if (Mode == 2)
            {
                System.Threading.Thread.Sleep(200);
    
                if(Star.instances < 30)
                {
                    Star myStar = new Star(r.Next(nScreenWidth-1), r.Next(nScreenHeight-1));
                    stars.Add(myStar);
                }
    
                if (stars.Count != 0)
                {
                    foreach(var star in stars)
                    {
                        star.Animate();
                    }
                }
    
                Console.SetCursorPosition(0, nScreenHeight-1);
                Console.Write("NUMBER OF STARS ON SCREEN : " + Star.instances);
            }
    

    我把dispose放在那里,只是为了记住这一点,将来我希望能生成更复杂的代码。但我想这不是真的需要。

    再次感谢!

    1 回复  |  直到 8 年前
        1
  •  1
  •   Creyke    8 年前

    您正在尝试创建 Star 每500毫秒初始化一次,但不维护对这些对象的引用。

    您需要将它们添加到集合中,例如列表…

    static List<Star> stars = new List<Star>();
    
    for (int i = 0; i< 10; i++)
    {
        Star myStar = new Star(r.Next(nScreenWidth), r.Next(nScreenHeight));
        stars.Add(myStar);
    }
    

    然后,当您退出主菜单时,您需要显式地处理这些实例,以便确保它们的计时器不再触发。

    在c_中,通常的做法是 IDisposable 希望能够显式处理的类中的接口…

    public class Star : IDisposable
    {
        ...
        public void Dispose()
        {
            if (aTimer != null)
            {
                aTimer.Dispose();
                aTimer = null;
            }
        }
        ...
    }
    

    然后可以通过调用dispose来处理star实例…

    if (keyInfo.Key == ConsoleKey.Escape)
    {
        foreach (var star in stars)
            star.Dispose();
        Console.Clear();
        MainMenu();
        Mode = 0;
    }
    
    推荐文章