[关闭]
@ts541933433 2020-04-28T02:18:45.000000Z 字数 3980 阅读 811

《蒙琦游戏》

地幕端交互说明文档

步骤:

当踏入点进入—>判断踏入点是否踩到元素—>当踩到元素时触发的操作

  • 使用(Touch Script)插件
  • SubwayProjectionMain.cs(地幕端主逻辑,负责加载游戏配置文件、与电视机端通讯、显示不同的地幕模块)
  • BaseBlock.cs (地幕功能块基类)
  • AnswerLineBlock.cs (地幕功能块子类,表示各类功能区)
  • ClickElement.cs (地幕元素基类)
  • NumberBubble.cs (地幕元素子类,表示各种元素)
  • SubwayEvent.cs (定义的事件)
  • EventManager.cs (事件管理)
  • IEventHandler.cs (时间手柄接口)
  • PlayGame.cs (最终实现类)

1.检测点进入,触发事件

SubwayProjectionMain.cs

  1. public class SubwayProjectionMain : MonoBehaviour, IEventHandler
  2. {
  3. private BaseBlock curBlock = null; //当前显示的区块
  4. public AnswerLineBlock answerLineBlock;
  5. private BaseBlock GetPlayBlock()
  6. {
  7. return answerLineBlock;
  8. }
  9. void Start()
  10. {
  11. //赋值当前区块
  12. curBlock = GetPlayBlock();
  13. if (TouchManager.Instance != null)
  14. {
  15. //监听输入源事件(TouchSript已定义的事件,直接进行监听)
  16. TouchManager.Instance.PointersAdded += pointersUpdateHandler;
  17. TouchManager.Instance.PointersUpdated += pointersUpdateHandler;
  18. TouchManager.Instance.PointersRemoved += pointersRemovedHandler;
  19. }
  20. }
  21. //当检测到有输入源进入时
  22. private void pointersUpdateHandler(object sender, PointerEventArgs e)
  23. {
  24. if (curBlock && curBlock.gameObject.activeSelf)
  25. {
  26. //遍历接收到的点
  27. foreach (var pointer in e.Pointers)
  28. {
  29. //对每个点进行更新
  30. curBlock.OnUpdatePointer(pointer);
  31. }
  32. }
  33. }
  34. }

更新点的方法,从区块到元素

Created with Raphaël 2.1.2区块基类区块子类元素基类元素子类

BaseBlock.cs

  1. //区块基类
  2. public class BaseBlock : MonoBehaviour
  3. {
  4. public virtual void OnUpdatePointer(Pointer pointer)
  5. {
  6. //区块基类虚方法
  7. }
  8. }

AnswerLineBlock.cs

  1. //区块子类
  2. public class AnswerLineBlock : BaseBlock
  3. {
  4. private List<NumberBubble> NumberBubbleList= new List<NumberBubble>(); //储存所有数字块
  5. public override void OnUpdatePointer(Pointer pointer)
  6. {
  7. base.OnUpdatePointer(pointer);
  8. foreach (NumberBubble number in NumberBubbleList)
  9. {
  10. if (number == null) continue;
  11. number.OnUpdatePointer(pointer);
  12. }
  13. }
  14. }

2.判断踏入点是否踩到元素

元素基类

ClickElement.cs

  1. public class ClickElement
  2. {
  3. protected float pressedTime = 0; //按下时的计时时间
  4. public float pressToClickTime = 0.8f; //按下多久算点击
  5. protected int pressID = -1; //硬件对应的点的id
  6. public void OnUpdatePointer(Pointer pointer)
  7. {
  8. if (!this.gameObject.activeInHierarchy) return;
  9. float w, h;
  10. //将踏入点坐标从屏幕坐标转换为世界坐标
  11. var pos = Camera.main.ScreenToWorldPoint(pointer.Position);
  12. //获取该元素的宽高
  13. w = this.getWidth();
  14. h = this.getHeight();
  15. //判断踏入点是否在元素的范围内
  16. if (pos.x > this.transform.position.x - w / 2 && pos.x < this.transform.position.x + w / 2 && pos.y > this.transform.position.y - h / 2 && pos.y < this.transform.position.y + h / 2)
  17. {
  18. //如果是,执行按下处理。
  19. OnPressed(pointer.Id);
  20. }
  21. else
  22. {
  23. //如果不是,但之前记录过这个点是按下的,释放该点
  24. if (this.pressID == pointer.Id)
  25. {
  26. OnPointerOut(pointer.Id);
  27. }
  28. }
  29. }
  30. //按下处理
  31. public void OnPressed(int id)
  32. {
  33. if (!this.gameObject.activeInHierarchy) return;
  34. if (pressID == -1)
  35. {
  36. pressedTime = Time.time;
  37. pressID = id;
  38. }
  39. }
  40. //释放处理
  41. public void OnReleased(int id)
  42. {
  43. if (pressID == id)
  44. {
  45. pressedTime = 0;
  46. pressID = -1;
  47. }
  48. }
  49. //实时检测是否满足点击
  50. protected virtual void Update()
  51. {
  52. if (pressedTime > 0)
  53. {
  54. if (Time.time - pressedTime >= pressToClickTime)
  55. {
  56. pressedTime = 0;
  57. OnClickHandler();
  58. }
  59. }
  60. }
  61. //触发点击事件
  62. protected virtual void OnClickHandler()
  63. {
  64. print(gameObject.name + " clicked");
  65. }
  66. }

3.满足点击条件,执行方法

元素子类

NumberBubble.cs

  1. public class NumberBubble : ClickElement
  2. {
  3. //在子类Update中实时检测是否满足点击
  4. protected override void Update()
  5. {
  6. base.Update();
  7. }
  8. //满足点击后触发事件
  9. protected override void OnClickHandler()
  10. {
  11. base.OnClickHandler();
  12. //事件处理器
  13. EventManager.GetInstance().DispachEvent(SubwayEvent.ENTER_GAME);
  14. }
  15. }

定义事件

SubwayEvent.cs

  1. public class SubwayEvent
  2. {
  3. public const string ENTER_GAME = "Enter_Game"; //进入游戏
  4. public const string Exit_GAME = "Exit_Game"; //退出游戏
  5. }

派发各类事件EventManager.GetInstance().DispachEvent

EventManager.cs

  1. //事件处理器
  2. public class EventManager
  3. {
  4. //单例
  5. private static EventManager instance;
  6. public static EventManager GetInstance()
  7. {
  8. if (instance == null)
  9. {
  10. instance = new EventManager();
  11. }
  12. return instance;
  13. }
  14. //定义一个value为事件手柄列表的字典
  15. private Dictionary<string, List<IEventHandler>> dicHandler;
  16. // 注册事件监听
  17. public void AddEventListener(string type, IEventHandler listher)
  18. {
  19. if (!dicHandler.ContainsKey(type))
  20. {
  21. dicHandler.Add(type, new List<IEventHandler>());
  22. }
  23. dicHandler[type].Add(listher);
  24. }
  25. //派发事件
  26. public void DispachEvent(string type, object data = null)
  27. {
  28. List<IEventHandler> list = dicHandler[type];
  29. for (int i = 0; i < list.Count; i++)
  30. {
  31. list[i].OnEvent(type, data);
  32. }
  33. }
  34. }

事件接口

IEventHandler.cs

  1. public interface IEventHandler
  2. {
  3. //事件手柄
  4. void OnEvent(string type, object data);
  5. }

最终实现

PlayGame.cs

  1. public class PlayGame : IEventHandler
  2. {
  3. //事件接口处理
  4. public void OnEvent(string type, object data)
  5. {
  6. switch (type)
  7. {
  8. case SubwayEvent.ENTER_GAME:
  9. //开始游戏
  10. break;
  11. case SubwayEvent.EXIT_GAME:
  12. //退出游戏
  13. break;
  14. }
  15. }
  16. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注