10.输入线程

  1. 10.输入线程
    1. 10.1 知识点
      1. 主要操作
    2. 10.2 知识点代码
      1. GameScene

10.输入线程


10.1 知识点

主要操作

  1. 测试发现输入有延迟,因为在 Update 方法里休眠了,休眠期间不能检测输入。

  2. 在游戏场景类中:

    • 声明一个线程对象和检测输入逻辑函数。
    • 在游戏场景类构造函数内创建一个用于检测输入的线程,将检测输入的逻辑函数作为参数传入。
  3. 将线程设置为后台线程后启动线程,将检测输入的逻辑放在检测输入函数逻辑函数中。

  4. 测试发现可能出现方块乱飞的情况,这是因为两个线程同时访问光标,需要加锁处理。

  5. 将搬砖工人对象作为锁,将有冲突的代码放入锁内,但不包含休眠操作,以免影响其他线程。

  6. 在输入的逻辑中实现按下 “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

×

喜欢就点赞,疼爱就打赏