cc.Class({ extends: cc.Component, properties: { m_NodePos:[cc.Node], m_CardItem:[cc.Prefab], m_SingleRow:cc.Integer, //单行牌数 //11 m_Arrow:cc.Node, }, // LIFE-CYCLE CALLBACKS: // 构造函数,在对象创建时被调用 ctor: function () { // 初始化一个空数组来存储牌的数据 this.m_CardData = new Array(); // 循环4次,为每个玩家(假设共4个玩家)创建一个空数组来存储他们的牌 for (var i = 0; i < 4; i++) { this.m_CardData[i] = new Array(); } // 初始化一个数组来记录每个玩家弃牌的数量,初始值为0 this.m_DiscardCount = new Array(0, 0, 0, 0); // 设置一个布尔值来表示弃牌区的显示方式,false表示横向,true表示纵向 this.m_cbViewType = false; // false横向,true纵向 // 将m_SingleRow转换为整数类型(假设m_SingleRow已经定义,此处仅做类型转换) this.m_SingleRow = parseInt(this.m_SingleRow); }, onLoad: function () { // 循环4次,分别处理四个方向的手牌:底部、顶部、左侧、右侧 for (var j = 0; j < 4; j++) { var posX = 0, posY = 0; // 初始化手牌的位置坐标 // 根据方向和单行手牌数量确定每副手牌的布局 for (var i = 0; i < 2 * this.m_SingleRow; i++) { // 实例化手牌对象 var card = cc.instantiate(this.m_CardItem[j]); // 根据方向设置手牌的位置 if (GameDef.HAND_BOTTOM == j) { // 当前方向是底部 posX = i % this.m_SingleRow * card.width; // 计算X坐标,按单行排列 if (parseInt(i / this.m_SingleRow) >= 1) { posY = -97; // 如果有多行,Y坐标设为-97 } } else if (GameDef.HAND_TOP == j) { // 当前方向是顶部 posX = ((this.m_SingleRow - 1) - i % this.m_SingleRow) * card.width; // 计算X坐标,反向排列 if (parseInt(i / this.m_SingleRow) >= 1) { posY = -97; // 如果有多行,Y坐标设为-97 } } else if (GameDef.HAND_LEFT == j) { // 当前方向是左侧 posY = i % this.m_SingleRow * card.height * -1; // 计算Y坐标,按单行排列 if (parseInt(i / this.m_SingleRow) >= 1) { posX = 56; // 如果有多行,X坐标设为56 } } else if (GameDef.HAND_RIGHT == j) { // 当前方向是右侧 posY = ((this.m_SingleRow - 1) - i % this.m_SingleRow) * card.height * -1; // 计算Y坐标,反向排列 if (parseInt(i / this.m_SingleRow) >= 1) { posX = 56; // 如果有多行,X坐标设为56 } // 设置右侧手牌的zIndex,使其按顺序排列 card.zIndex = this.m_SingleRow - i; } // 设置手牌显示阴影的条件 var ShowShoadow = false; if (GameDef.HAND_TOP == j || GameDef.HAND_BOTTOM == j) { // 当前方向是顶部或底部 ShowShoadow = (i == 0 || i == 11); // 第一张和最后一张手牌显示阴影 } else if (GameDef.HAND_LEFT == j) { // 当前方向是左侧 ShowShoadow = (i < 11); // 前11张手牌显示阴影 } else if (GameDef.HAND_RIGHT == j) { // 当前方向是右侧 ShowShoadow = (i >= this.m_SingleRow); // 超过单行数量的手牌显示阴影 } // 设置手牌的位置 card.setPosition(posX, posY); // 将手牌添加到对应的节点上 this.m_NodePos[j].addChild(card); // 获取手牌的组件 card = card.getComponent('CardItem'); // 设置手牌是否显示阴影 card.SetShadowShow(ShowShoadow); // 将手牌数据保存到对应的数组中 this.m_CardData[j][i] = card; // 设置手牌的显示状态 card.SetState(GameDef.HAND_STATE_SHOW); // 初始状态下不激活手牌节点 card.node.active = false; } } // // 创建一个动作序列,先向下移动20个单位,再向上移动20个单位 // var seq1 = cc.sequence(cc.moveBy(0.5, 0, 20), cc.moveBy(0.5, 0, -20)); // // 创建一个动作序列,先放大到1.5倍,再恢复到1倍 // var seq2 = cc.sequence(cc.scaleTo(0.5, 1.5), cc.scaleTo(0.5, 1)); // // 同时执行上述两个动作序列 // var spawn = cc.spawn(seq1, seq2); // // 无限循环执行上述动作组合 // this.m_Arrow.runAction(cc.repeatForever(spawn)); // 初始状态下不激活箭头节点 this.m_Arrow.active = false; }, start () { }, // 设置玩家手牌数据的函数 SetCardData: function(viewID, cbCardData, cbCardCount, cbTingHouOut) { // 如果传入的cbCardData为0或null,直接返回 if (cbCardData == 0 || cbCardData == null) return; // 遍历当前玩家手牌数组,将所有牌的node设置为不激活状态 for (var i = 0; i < this.m_CardData[viewID].length; i++) { this.m_CardData[viewID][i].node.active = false; } // 计算需要新增的牌的数量 var index = 0; if (cbCardCount > this.m_CardData[viewID].length) { index = cbCardCount - this.m_CardData[viewID].length; } // 更新玩家手牌数据 for (var i = 0; i < this.m_CardData[viewID].length; i++) { // 如果当前手牌数组中的元素为null,输出错误信息并跳过 if (this.m_CardData[viewID][i] == null) { console.log('SetCardData this.m_CardData[viewID][i] 越界:', i); continue; } // 如果新的手牌数据中有牌(值大于0),则激活node并设置手牌数据和状态为显示 if (cbCardData[i + index] > 0) { this.m_CardData[viewID][i].node.active = true; this.m_CardData[viewID][i].SetCardData(cbCardData[i + index]); this.m_CardData[viewID][i].SetState(GameDef.HAND_STATE_SHOW); } // 如果有报听的牌,并且该牌需要显示为背面 if (cbTingHouOut != null && cbTingHouOut[i + index] > 0) { // 设置手牌状态为显示背面 this.m_CardData[viewID][i].SetState(GameDef.HAND_STATE_SHOW_BACK); } } // 根据手牌数量和玩家数量设置丢弃的牌的数量 if (cbCardCount > this.m_SingleRow * 2 && this.m_UserCount > 2) { this.m_DiscardCount[viewID] = this.m_SingleRow * 2; } else { this.m_DiscardCount[viewID] = cbCardCount; } }, /** * 根据视图ID和卡牌ID获取卡牌节点 * @param {number} viewID - 视图ID,标识不同的玩家或玩家位置 * @param {number} CardID - 卡牌ID,标识玩家手牌中的具体哪一张卡牌 * @returns {CardNode} - 返回指定视图和ID对应的卡牌节点 */ GetCardNode: function(viewID, CardID) { // 返回存储在m_CardData数组中的指定视图和ID对应的卡牌节点 return this.m_CardData[viewID][CardID]; }, /** * 获取下一张弃牌节点 * @param {number} viewID - 视图ID,用于标识不同的玩家或视角 * @returns {Node} - 返回弃牌节点 */ GetNextDiscardNode: function(viewID) { // 获取当前视角下的弃牌计数索引 var index = this.m_DiscardCount[viewID]; // 检查索引是否超出当前视角下的牌数据长度 if (index >= this.m_CardData[viewID].length) { // 如果超出长度,将所有牌的数据向前移动一位 for (var i = 0; i < this.m_CardData[viewID].length - 1; i++) { // 将第i+1张牌的数据赋值给第i张牌 this.m_CardData[viewID][i].SetCardData(this.m_CardData[viewID][i + 1].GetCardData()); } // 获取最后一张牌的索引 var nMaxIndex = this.m_CardData[viewID].length - 1; // 将最后一张牌的节点设置为不活跃(隐藏) this.m_CardData[viewID][nMaxIndex].node.active = false; // 返回最后一张牌的节点 return this.m_CardData[viewID][nMaxIndex]; } // 如果索引未超出长度,直接返回对应索引的牌节点 return this.m_CardData[viewID][index]; }, /** * 获取指定视图ID的节点的缩放比例 * @param {number} viewID - 视图的唯一标识符 * @returns {number} - 返回该视图ID对应的节点的缩放比例 */ GetScale:function(viewID){ return this.m_NodePos[viewID].scale; }, // 定义 AddDiscard 函数,用于在指定玩家位置丢弃一张牌 AddDiscard: function(viewID, cbCardData, bShowArrow, wTingCard) { // 如果传入的牌数据为空或为0,则直接返回,不执行后续操作 if (cbCardData == 0 || cbCardData == null) return; // 获取当前玩家丢弃的牌数据 var CardData = this.m_CardData[viewID][this.m_DiscardCount[viewID]]; // 如果当前索引的牌数据为空,则使用该玩家最后一张牌的数据 if (CardData == null) { CardData = this.m_CardData[viewID][this.m_CardData[viewID].length - 1]; } // 激活牌节点 CardData.node.active = true; // 设置牌的数据 CardData.SetCardData(cbCardData); // 根据是否传入了听牌信息来设置牌的显示状态 if (wTingCard != null && wTingCard != 0) { // 如果传入了听牌信息,则设置牌为背面显示状态 CardData.SetState(GameDef.HAND_STATE_SHOW_BACK); } else { // 否则,设置牌为正面显示状态 CardData.SetState(GameDef.HAND_STATE_SHOW); } // 根据玩家数量来决定丢弃计数的增加方式 if (this.m_UserCount == 2) { // 如果玩家数量为2,则每次丢弃计数加1 this.m_DiscardCount[viewID]++; } else { // 如果玩家数量不为2,则只有当当前丢弃计数小于单行牌数的两倍时,才增加丢弃计数 if (this.m_DiscardCount[viewID] < this.m_SingleRow * 2) { this.m_DiscardCount[viewID]++; } } // 如果传入了显示箭头的标志且为真,则显示箭头 if (bShowArrow != null && bShowArrow) { this.ShowArrow(viewID); } }, GetLastCardData:function(viewID){ if(this.m_DiscardCount[viewID]<=0)return 0; var CardData = this.m_CardData[viewID][this.m_DiscardCount[viewID]]; return CardData.GetCardData(); }, RemoveDiscard:function(viewID){ if(this.m_DiscardCount[viewID]<=0)return; this.m_CardData[viewID][--this.m_DiscardCount[viewID]].node.active = false; if( this.m_Arrow.active ) { this.m_Arrow.active = false; } }, Reset:function(){ for(var j = 0 ;j<4;j++){ this.m_DiscardCount[j] = 0; for (const i in this.m_CardData[j]) { this.m_CardData[j][i].node.active = false; this.m_CardData[j][i].SetCardData(0); } } }, // 显示箭头的方法,用于指示某个玩家丢弃牌的位置 ShowArrow: function(viewID) { // 检查viewID是否在有效范围内(0到4),以及该玩家是否有丢弃的牌 if (viewID < 0 || viewID > 4 || this.m_DiscardCount[viewID] == 0) { // 如果viewID无效或没有丢弃的牌,则隐藏箭头并返回 this.m_Arrow.active = false; return; } // 如果viewID有效且有丢弃的牌,则显示箭头 this.m_Arrow.active = true; // 计算箭头应指向的丢弃牌的索引 var arrowIndex = this.m_DiscardCount[viewID] - 1; // 确保arrowIndex不超出该玩家丢弃牌数组的长度范围 if (arrowIndex > this.m_CardData[viewID].length - 1) { arrowIndex = this.m_CardData[viewID].length - 1; } // 获取该玩家丢弃牌的节点的世界坐标位置 var pos = this.m_CardData[viewID][arrowIndex].node.convertToWorldSpaceAR(cc.v2(0, 0)); // 将世界坐标转换为当前节点的本地坐标 pos = this.node.convertToNodeSpaceAR(pos); // 根据viewID调整箭头的Y轴位置,以更好地适应UI布局 if (viewID == GameDef.HAND_LEFT || viewID == GameDef.HAND_RIGHT) { // 如果是左手玩家或右手玩家,箭头Y轴位置加20 pos.y += 20; } else { // 其他情况(例如上家或下家),箭头Y轴位置加30 pos.y += 30; } // 设置箭头的位置为计算后的pos this.m_Arrow.setPosition(pos); }, setUserCount:function(wUserCount){ this.m_UserCount = wUserCount; // 当玩家数量为2人时 if( wUserCount == 2 ){ // 初始化X和Y位置变量 var posX = 0, posY = 0; // 遍历四个玩家位置(0, 1, 2, 3) for (var j = 0; j < 4; j++) { // 跳过玩家位置1和3,因为他们不参与当前的布局 if( j == 1 || j == 3 ) continue; // 从第2*this.m_SingleRow张牌开始布局,c用于计算当前是第几张牌 for (var i = 2*this.m_SingleRow, c=0; i<65; i++, c++) { // 初始化index变量,用于确定手牌的左右位置 var index = 0; // 根据玩家位置设置index if( 0 == j ){ // 玩家位置0 index = GameDef.HAND_LEFT; // 左手 } else if( 2 == j ){ // 玩家位置2 index = GameDef.HAND_RIGHT; // 右手 } // 如果当前位置已经有牌,则跳过 if( this.m_CardData[j][i] != null ) continue; // 实例化一张新的牌 var card = cc.instantiate(this.m_CardItem[index]); // 根据玩家位置计算新牌的位置 if(0 == j){ // 玩家位置0 // 计算X位置,每排的牌宽度为card.width,向左移动 posX = parseInt(c/this.m_SingleRow) * card.width * -1; // 计算Y位置,每张牌的高度为card.height,向下移动 posY = parseInt(c % this.m_SingleRow) * card.height * -1; // 调整X位置,使牌稍微向右移动 posX += 40; }else if(2 == j){ // 玩家位置2 // 计算X位置,每排的牌宽度为card.width,向右移动 posX = parseInt(c/this.m_SingleRow) * card.width; // 计算Y位置,每张牌的高度为card.height,向下移动 posY = parseInt(c % this.m_SingleRow) * card.height * -1; // 调整X位置,使牌稍微向左移动 posX += 5; } // 设置新牌的位置 card.setPosition(cc.v2(posX, posY)); // 将新牌添加到相应位置节点的子节点中 this.m_NodePos[index].addChild(card); // 获取新牌的CardItem组件 card = card.getComponent('CardItem'); // 在m_CardData数组中记录新牌的位置信息 this.m_CardData[j][i] = card; // 设置新牌的状态为显示状态 card.SetState(GameDef.HAND_STATE_SHOW); // 将新牌的节点设置为不可见 card.node.active = false; } } } // if( wUserCount == 3 ){ // // var width = this.m_CardData[0][0].node.width; // // this.m_NodePos[0].x += width; // // this.m_NodePos[1].x += width-20; // // this.m_NodePos[2].x += width; // var posX =0; // var posY =0; // for (var j = 0; j < 3; j++) { // this.m_NodePos[j].removeAllChildren(); // this.m_CardData[j] = new Array(); // for (var i = 0; i < 3*this.m_SingleRow; i++) { // if( this.m_CardData[j][i] != null ) continue; // var card = cc.instantiate(this.m_CardItem[j]); // if(GameDef.HAND_LEFT == j){ // posX = parseInt( i/this.m_SingleRow )*card.width; // posY = parseInt( i%this.m_SingleRow )*card.height*-1; // } // else if(GameDef.HAND_TOP == j){ //0 // var value = 15; // posX = (i%value)*card.width; // posY = (parseInt( i/value) -1)*card.height*-1; // posY -= card.height // posX += card.width // }else if( GameDef.HAND_BOTTOM == j){ //2 // var value = 15; // posX = (i%value)*card.width; // posY = (parseInt( i/value) -1)*card.height*-1; // posX += card.width // posY -= card.height // if( i >= 30 ){ // posY +=card.height*3; // } // } // var ShowShoadow = false; // if(GameDef.HAND_TOP == j|| GameDef.HAND_BOTTOM == j){ // ShowShoadow = (i == 0 || i == 15); // } // else if(GameDef.HAND_LEFT == j){ // ShowShoadow = (i <11); // } // card.setPosition(posX,posY); // this.m_NodePos[j].addChild(card); // card = card.getComponent('CardItem'); // this.m_CardData[j][i] = card; // card.SetState(GameDef.HAND_STATE_SHOW); // card.SetShadowShow(ShowShoadow); // card.node.active = false; // } // } // } }, // update (dt) {}, });