13.优化输入线程

  1. 13.优化输入线程
    1. 13.1 知识点
      1. 要实现的代码
      2. 主要操作
    2. 13.2 知识点代码
      1. InputThread
      2. GameScene

13.优化输入线程


13.1 知识点

要实现的代码

主要操作

  1. 发现每次 new 游戏场景类可能会造成线程垃圾。
  2. 创建一个输入线程管理类,使其成为单例模式。
  3. 声明一个线程成员变量,在输入线程管理类中初始化线程,创建一个输入线程逻辑函数传入其中,设置为后台线程并开启。
  4. 声明一个输入检测事件,在输入线程逻辑函数中编写一个死循环,判断事件不为空时执行。
  5. 这样只要把输入逻辑函数丢到事件中就能执行输入逻辑了。
  6. 在游戏场景类中注释掉之前编写的线程相关代码。
  7. 在游戏场景类的构造函数中给事件管理类添加检测输入函数,在停止线程方法中移除检测输入函数。

13.2 知识点代码

InputThread

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace CSharp进阶实践教学
{
    class InputThread
    {
        //线程成员变量
        Thread inputThread;
        //输入检测事件
        public event Action inputEvent;

        private static InputThread instance = new InputThread();

        public static InputThread Instance
        {
            get
            {
                return instance;
            }
        }

        private InputThread()
        {
            inputThread = new Thread(InputCheck);
            inputThread.IsBackground = true;
            inputThread.Start();
        }

        private void InputCheck()
        {
            while (true)
            {
                inputEvent?.Invoke();
            }
        }
    }
}

GameScene

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace CSharp进阶实践教学
{
    class GameScene : ISceneUpdate
    {
        Map map;
        BlockWorker blockWorker;

        #region Lesson10 
        //bool isRunning;
        //Thread inputThread;
        #endregion
        public GameScene()
        {
            map = new Map(this);
            blockWorker = new BlockWorker();
            #region Lesson10 输入线程

            //添加输入事件监听
            InputThread.Instance.inputEvent += CheckInputThread;

            //isRunning = true;
            //inputThread = new Thread(CheckInputThread);
            ////设置成后台线程 声明周期随主线程决定
            //inputThread.IsBackground = true;
            ////开启线程
            //inputThread.Start();
            #endregion
        }

        #region Lesson10 输入线程
        private void CheckInputThread()
        {
            //while (isRunning)
            //{
            //这只是 另一个输入线程 每帧会执行的逻辑 不需要自己来死循环
                if (Console.KeyAvailable)
                {
                    //为了避免影响主线程 在输入后加锁
                    lock (blockWorker)
                    {
                        switch (Console.ReadKey(true).Key)
                        {
                            case ConsoleKey.LeftArrow:
                                //判断能不能变形
                                if (blockWorker.CanChange(E_Change_Type.Left, map))
                                    blockWorker.Change(E_Change_Type.Left);
                                break;
                            case ConsoleKey.RightArrow:
                                //判断能不能变形
                                if (blockWorker.CanChange(E_Change_Type.Right, map))
                                    blockWorker.Change(E_Change_Type.Right);
                                break;
                            case ConsoleKey.A:
                                if (blockWorker.CanMoveRL(E_Change_Type.Left, map))
                                    blockWorker.MoveRL(E_Change_Type.Left);
                                break;
                            case ConsoleKey.D:
                                if (blockWorker.CanMoveRL(E_Change_Type.Right, map))
                                    blockWorker.MoveRL(E_Change_Type.Right);
                                break;
                            case ConsoleKey.S:
                                //向下动
                                if (blockWorker.CanMove(map))
                                    blockWorker.AutoMove();
                                break;
                        }
                    }

                }
            //}
        }
        #endregion

        /// <summary>
        /// 停止线程
        /// </summary>
        public void StopThread()
        {
            //isRunning = false;
            //inputThread = null;

            //移除输入事件监听
            InputThread.Instance.inputEvent -= CheckInputThread;

            //在某些c#版本中 会直接报错 没用
            //inputThread.Abort();
        }

        public void Update()
        {
            //锁里面不要包含 休眠 不然会影响别人
            lock(blockWorker)
            {
                //地图绘制
                map.Draw();
                //搬运工绘制
                blockWorker.Draw();
                //自动向下移动
                if (blockWorker.CanMove(map))
                    blockWorker.AutoMove();
            }
            //用线程休眠的形式 
            Thread.Sleep(200);
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏