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