10.输入线程
10.1 知识点
主要操作
测试发现输入有延迟,因为在
Update
方法里休眠了,休眠期间不能检测输入。在游戏场景类中:
- 声明一个线程对象和检测输入逻辑函数。
- 在游戏场景类构造函数内创建一个用于检测输入的线程,将检测输入的逻辑函数作为参数传入。
将线程设置为后台线程后启动线程,将检测输入的逻辑放在检测输入函数逻辑函数中。
测试发现可能出现方块乱飞的情况,这是因为两个线程同时访问光标,需要加锁处理。
将搬砖工人对象作为锁,将有冲突的代码放入锁内,但不包含休眠操作,以免影响其他线程。
在输入的逻辑中实现按下 “s” 键往下移动方块的逻辑。
10.2 知识点代码
GameScene
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace CSharp实践教学
{
class GameScene : ISceneUpdate
{
Map map;
BlockWorker blockWorker;
### Lesson10 输入线程
Thread inputThread;
### endregion
public GameScene()
{
map = new Map();
blockWorker = new BlockWorker();
### Lesson10 输入线程
inputThread = new Thread(CheckInputThread);
//设置成后台线程 声明周期随主线程决定
inputThread.IsBackground = true;
//开启线程
inputThread.Start();
### endregion
}
### Lesson10 输入线程
private void CheckInputThread()
{
while (true)
{
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
public void Update()
{
//锁里面不要包含 休眠 不然会影响别人
lock(blockWorker)
{
//地图绘制
map.Draw();
//搬运工绘制
blockWorker.Draw();
//自动向下移动
if (blockWorker.CanMove(map))
blockWorker.AutoMove();
}
//用线程休眠的形式
Thread.Sleep(200);
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com