ET学习笔记之五星麻将2

2023-10-09 00:59
文章标签 学习 笔记 et 麻将 五星

本文主要是介绍ET学习笔记之五星麻将2,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

五星麻将2客户端游戏大厅

    • 前言
    • 游戏大厅
      • 大厅通道 LobbyAisle
      • 大厅UI
      • 灯笼摇晃动画
      • 匹配房间
      • 创建房间
      • 加入房间
      • 作者的话

前言

其实越看ET的代码,越觉得自己的知识储备不够,好多地方只能浅尝辄止,这也是半路出家当和尚的无奈。
今天是国庆节,一边看国庆直播,一边写这篇笔记,不禁感叹我天朝之伟大。
泱泱大国,不容小觑。有幸见证这样的旷世直播,真是了不起!
胸中澎湃的浩然正气,似乎无法用文字来描述。
看完直播,对我们的未来也更加期待,虽然我们还需要更加努力,毕竟川普之流还在敌视我们,香港在躁动,台湾还没有收复,脱贫尚未完成……
但是我相信,如果我们的技术足够强大,我们终将Free。
所以为了得到Free,继续努力下去。
老实讲,川普和天朝开战真是愚不可及之事,他的政治生涯恐怕会因此黯然失色。

游戏大厅

上一篇我们已经可以进入游戏大厅界面了,如下图所示:
游戏大厅
我们先来追溯进入游戏大厅的过程,在KCPUseManage发起连接之前,由ET的事件机制调用了Awake方法:

        private KCPStateManage _mStateManage;public void Awake(){Ins = this;_mStateManage= this.GetComponent<KCPStateManage>();}

Awake完成了单例模式的同时,也缓存了KCPStateManage的引用,稍后我们会进入该类。在上一篇的LoginAndConnect登录连接过程中,这个被缓存的引用完成了赋值操作:

 Action<G2C_GateLogin> connectSuccesAction = _mStateManage.ConnectSuccess;//连接成功

该事件在LoginAndConnect最后,登录成功返回确切消息后又被调用:

                //发起连接成功事件connectSuccesAction(g2CLoginGate);

这行代码实际上调用了KCPStateManage的ConnectSuccess方法:

        //连接成功public void ConnectSuccess(G2C_GateLogin g2CGateLogin){Log.Debug("连接成功");pKCPNetWorkState = KCPNetWorkState.Connect;pConnectSuccessCall?.Invoke(g2CGateLogin);}

ConnectSuccess方法中有个?号,其实是个空值判定的高级写法,等价于:

if(pConnectSuccessCall!=null)pConnectSuccessCall.Invoke(g2CGateLogin);

而该事件早就被订阅了,可以追溯到KCPUseManage被添加的时候,追溯到Init中Game.Scene.AddComponent<KCPUseManage>();//KCP使用组件,因为AddComponent而触发ET的AwakeSystem,通过KCPUseManage的Awake又self.AddComponent<KCPLocalizationDispose>();,又触发KCPLocalizationDispose的Awake,一系列ET事件机制的连锁反应。
蝴蝶的翅膀轻轻扇动,就在大洋彼岸掀起了龙卷风。
Anyway,通过事件机制pConnectSuccessCall在KCPLocalizationDispose中被订阅了:

        public void Awake(){KCPStateManage.Ins.pConnectLostCall += ConnectLostEvent;KCPStateManage.Ins.pAgainConnectFailureCall += AgainConnectFailureEvent;KCPStateManage.Ins.pStartConnectCall += StartConnectEvent;KCPStateManage.Ins.pStartReconnectionCall += StartReconnectionEvent;KCPStateManage.Ins.pConnectFailureCall += ConnectFailureEvent;KCPStateManage.Ins.pConnectSuccessCall += ConnectSuccessEvent;KCPStateManage.Ins.pAgainConnectSuccessCall += AgainConnectSuccessEvent;}

实际上订阅了一大堆KCPStateManage的状态事件,只要对应的事件触发,这里对应的方法就会调用:

        //连接成功private void ConnectSuccessEvent(G2C_GateLogin g2CGateLogin){UIComponent.GetUiView<LoadingIconPanelComponent>().Hide();User user = g2CGateLogin.User;Game.Scene.GetComponent<UserComponent>().SetSelfUser(user); ;Game.Scene.GetComponent<ToyGameComponent>().StartGame(ToyGameId.Lobby);SessionComponent.Instance.Session.AddComponent<HeartbeatComponent>();//添加心跳组件 }

连接成功后,先隐藏了负责显示加载的UI面板LoadingIconPanel,然后获取用户User信息并进行设置。
接着通过StartGame方法进入大厅的通道,同时开始心跳。

大厅通道 LobbyAisle

之前已经讲过,五星麻将都是通过通道来切换场景的,可以在下图的位置找到相关代码:
通道
在执行StartGame(ToyGameId.Lobby);时,最终调用的就是LobbyAisle的StartGame方法:

        public override void StartGame(params object[] objs){base.StartGame();Log.Debug("进入大厅");UIComponent.GetUiView<FiveStarLobbyPanelComponent>().Show();}

至此进入大厅的整个流程已经追溯完了。

大厅UI

加载UI以后,首先是要缓存引用:

            ReferenceCollector rc = this.GetParent<UI>().GameObject.GetComponent<ReferenceCollector>();mMuChuangViewGo = rc.Get<GameObject>("MuChuangViewGo");mRecordPerformanceBtn = rc.Get<GameObject>("RecordPerformanceBtn").GetComponent<Button>();mRightBtnViewGo = rc.Get<GameObject>("RightBtnViewGo");mUserInfoViewGo = rc.Get<GameObject>("UserInfoViewGo");mTopBtnViewGo = rc.Get<GameObject>("TopBtnViewGo");mBroadcastViewGo = rc.Get<GameObject>("BroadcastViewGo");mLobbyBgClip = rc.Get<AudioClip>("lobbybgMusic");InitPanel();

后面就是一些UI初始化的操作,比较基础的知识点,所以我就不啰嗦了。
其中SdkCall是微信开放平台对应的接口,调用一些社交方面的功能,例如用户信息、定位、朋友圈等。

灯笼摇晃动画

其实很多2D游戏的UI都是带动画效果的,这样显得整个界面很有生机,五星麻将大厅的灯笼就有随风飘动的效果,这个其实是很简单的动画,我们甚至可以放一个风车在里面转动。

public class LanternAnim{private GameObject _AigletGo;public GameObject gameObject;public LanternAnim(GameObject go){gameObject = go;_AigletGo = go.FindChild("AigletGo").gameObject;PlayAnim();}public const float LanternRange = 3.00f;//灯笼的摇晃幅度public const float AigletRange = 18.00f;//吊坠的摇晃幅度private Vector3 _LanternVector = new Vector3(0, 0, 0);private Vector3 _AigletVector = new Vector3(0, 0, 0);private static int RangePlus = 1;private bool isAnimIn;public async void PlayAnim(){if (isAnimIn){return;}isAnimIn = true;while (gameObject.activeInHierarchy){_LanternVector.z = (float)RandomTool.Random(LanternRange/2, LanternRange) * RangePlus;_AigletVector.z = (float)RandomTool.Random(AigletRange/2, AigletRange) * RangePlus;gameObject.transform.DOLocalRotate(_LanternVector, 3f);_AigletGo.transform.DOLocalRotate(_AigletVector, 3f);RangePlus = RangePlus * -1;await ETModel.Game.Scene.GetComponent<TimerComponent>().WaitAsync(2000);}isAnimIn = false;}}

这个很简单,用一个协程来调用DOLocalRotate,这是属于DOTween插件的transform扩展方法。
我们的游戏如果有在UI上挂灯笼,也完全可以用得上这段代码。

匹配房间

当点击大厅灯笼上的匹配房间按钮时,对应的UI事件就触发了:

        public void MatchBtnEvent(){UIComponent.GetUiView<MatchingRoomPanelComponent>().Show();}

这时就弹出了匹配房间的面板,如图所示:
匹配房间面板
这里的初级场、中级场、高级场是根据配置生成的,这里同样使用了协程:

        private async void InitRoomList(){if (_MatchRoomConfigs==null){await RequestMatchRoomConfigs();}Transform roomItemParent = mRoomItemGo.transform.parent;_RoomLists=roomItemParent.CreatorChildAndAddItem<MathRoomItem, MatchRoomConfig>(_MatchRoomConfigs);}

如果匹配房间配置没有,就会请求服务器:

        //想服务器请求 所有匹配房间配置private RepeatedField<MatchRoomConfig> _MatchRoomConfigs;private async Task RequestMatchRoomConfigs(){L2C_GetMatchRoomConfigs l2CGetMatchRoomConfigs = (L2C_GetMatchRoomConfigs)await SessionComponent.Instance.Call(new C2L_GetMatchRoomConfigs() { ToyGameId = ToyGameId.CardFiveStar });_MatchRoomConfigs = l2CGetMatchRoomConfigs.MatchRoomConfigs;}

RepeatedField相当于是List列表,从服务器得到这些配置列表后,就可以创建对应的按钮了。

        public void EnterRoom(){CardFiveStarAisle.MatchingEnterRoom(mData.MatchRoomId,mData.RoomConfigs);}

点击对应的按钮就会进入对应MatchRoomId的房间,也就是上面的EnterRoom方法,该方法是和按钮事件绑定的,这属于是基本操作了。下面开始进入到房间,房间的玩法逻辑已经不再大厅范畴,请看后文。

创建房间

点击创建房间那个灯笼,就触发了下面的方法:

        public void CreateRoomBtnEvent(){UIComponent.GetUiView<CreateRoomPanelComponent>().ShowCraterRoomPanel(ShowCraterRoomPanelType.NormalCraterRoom, CardFiveStarAisle.CreateRoom);}

弹出对应的窗口,如下图所示:
创建房间

加入房间

加入房间同上,都是些UI按钮事件,逻辑简单,这里就不赘述了。如果这方面有疑惑,应该学习下对应的教程。当然,大厅的功能是比较全面的,全部写下来会很啰嗦,那样的话可以录制视频教程了。
所以,在这里就此打住好了,已经起到抛砖引玉的效果了,看看源代码都可以顺藤摸瓜了。
之前有做过麻将游戏的开发,所以游戏逻辑对于我来说,都十分熟悉了。不太熟悉的只是ET框架而已,所以五星麻将就写到这一篇作为结束篇,如果大家想学习麻将的逻辑,请评论点赞。
设置一个Flag在这里好了,评论或点赞数超过100的话,我就把五星麻将完整的麻将逻辑梳理出来。
麻将游戏对于我个人来说,完全是得心应手的事情,这是我不愿意写下去的原因,成长收益不高。但是大家想学习这方面的知识的话,我也是个助人为乐的人,所以根据大家的意愿来吧。
时间是宝贵的,祝大家国庆节快乐,愿祖国繁荣昌盛,早日实现中华民族的伟大复兴!
我们这些程序猿也要继续努力啊!

作者的话

Alt

如果喜欢可以点赞支持一下,谢谢鼓励!如果有什么疑问可以给我留言,有错漏的地方请批评指证!
技术难题?加入开发者联盟:566189328(QQ付费群)提供有限技术探讨,以及,心灵鸡汤Orz!
当然,不需要技术探讨也欢迎加入进来,在这里劈柴、遛狗、聊天、撸猫!( ̄┰ ̄*)

这篇关于ET学习笔记之五星麻将2的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/169218

相关文章

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06