主要目录结构,比较粗暴
[mw_shl_code=cpp,true]
/**逻辑 这个是后端完成的,这里模拟后端和延迟通信*/
class LogicDemo {
private _cards: Array<CardData>;
public __dealRing:number = 0;
private _getted:boolean = true;
private static _ins: LogicDemo;
public aiCard:CardData;
//---在这里配置你想摸到的牌,方便测试---
private _initSelfCardTypes:number[] = [1,1,1,1,2,2,2,2];
private _initSelfCardNum:number[] = [1,1,1,1,2,2,2,2];
public constructor() {
}
public static get ins(): LogicDemo {
if (!LogicDemo._ins)
LogicDemo._ins = new LogicDemo();
return LogicDemo._ins;
}
/**发牌 */
public dealCards(): void {
SelfCardGroup.getIns().setInfo("正在发牌...");
this.__dealRing = 0;
this.createCards();//创建
this.shuffle();//洗牌
this.deal();
}
//我的回合结束
public optionEnd():void
{
this._getted = false;
this.__dealRing = 0;
this.continueGame();
}
//继续
public goOn():void
{
this.continueGame();
}
/**发一张牌给我,从开头 */
public shiftOne():void
{
SelfCardGroup.getIns().addCard(this._cards.shift(),false);
SelfCardGroup.getIns().gogo();
}
/**开始游戏 */
private continueGame():void
{
if(this._getted)//等待玩家出牌
{
SelfCardGroup.getIns().gogo();
return;
}
else
{
this.__dealRing++;
if(this.__dealRing%4!=0)//给计算机发牌
{
this.jump();
}
else//给自己发牌
{
DelayCall.call(1000,this.dealSelf,this);
}
}
}
/**计算机出牌,僵尸摸什么打什么 */
private jump():void
{
this.aiCard = this._cards.pop();
SelfCardGroup.getIns().looklook();
}
/**给自己发一张牌 */
private dealSelf():void
{
//玩家得到一张牌后等待玩家操作
this._getted = true;
SelfCardGroup.getIns().addCard(this._cards.pop(),false);
}
/**开始发牌逻辑 */
private deal():void
{
if(this.__dealRing<3)//给所有人发牌,一次发4张
{
//给自己发一张,其他人直接丢掉(测试用)
SelfCardGroup.getIns().addCard(this._cards.pop(),true);
SelfCardGroup.getIns().addCard(this._cards.pop(),true);
SelfCardGroup.getIns().addCard(this._cards.pop(),true);
SelfCardGroup.getIns().addCard(this._cards.pop(),true);
this._cards.splice(this._cards.length-12,12);
DelayCall.call(500,this.deal,this);
}
else//给自己补发一张
{
this._getted = true;
this.__dealRing = 0;
SelfCardGroup.getIns().addCard(this._cards.pop(),true);
this._cards.pop();
this._cards.pop();
this._cards.pop();
SelfCardGroup.getIns().addCard(this._cards.pop(),true);
SelfCardGroup.getIns().sortCards(1000);
this.continueGame();
return;
}
this.__dealRing++;
}
//创建108
private createCards(): void {
this._cards = new Array<CardData>();
//108张,如果要玩东南风需要扩展.对应筒条万
for (var i: number = 1; i <= 3; i++) {
for (var c: number = 1; c <= 9; c++) {
this._cards.push(new CardData(i, c));
this._cards.push(new CardData(i, c));
this._cards.push(new CardData(i, c));
this._cards.push(new CardData(i, c));
}
}
}
private _hzList:number[] = [];
/**洗牌 */
private shuffle():void{
this._hzList = [];
var cards:Array<CardData> = new Array<CardData>();
var key:any;
var card:CardData;
for(key in this._cards)
{
card = this._cards[key];
cards.splice(Math.floor(cards.length*Math.random()),0,card);
}
//----------在这里洗盒子-----------洗前12个就好了
var insertIndex:number = 0;
for(var i:number=0;i<this._initSelfCardTypes.length;i++)
{
var insertCard:CardData = this.getChildBy(cards,this._initSelfCardTypes,this._initSelfCardNum);
this._hzList.push(insertCard.id);
if(insertCard==null)
console.log("异常");
cards.splice(cards.indexOf(insertCard),1);
cards.splice(cards.length-insertIndex,0,insertCard)
insertIndex++;
if(insertIndex%4==0)
insertIndex+=12;
}
this._cards = cards;
}
/**取 */
private getChildBy(from:Array<CardData>,type:number,num:number):CardData
{
var key:any;
var dd:CardData;
for(key in from)
{
dd = from[key];
if(dd.cType == type && dd.cNum == num && this._hzList.indexOf(dd.id)<0)
return dd;
}
return null;
}
}[/mw_shl_code]
[mw_shl_code=cpp,true]
/**自己的牌组显示对象 */
class SelfCardGroup extends egret.DisplayObjectContainer {
private _cards: Array<CardData> = new Array<CardData>();//手上的牌
private _deskCards: Array<CardData> = new Array<CardData>();//碰和杠的牌
private _cardBox: HBox;
private _deskBox: HBox;
private _focusCard: CardSprite;
private _debugInfo: egret.TextField;
private _focusType: string = "";
private _cardKey: string = "";
private _gangIndex: number = 0;
private _gangArray: string[] = [];
/**自己的牌面显示对象只会有一个 */
private static _ins: SelfCardGroup;
/**私有掉构造 */
private constructor() {
super();
this._cardBox = new HBox();
this._cardBox.touchEnabled = true;
this.addChild(this._cardBox);
this._deskBox = new HBox();
this.addChild(this._deskBox);
this.addChild(OptionBar.getIns());
this._debugInfo = new egret.TextField();
this._debugInfo.size = 30;
this.addChild(this._debugInfo);
}
public static getIns(): SelfCardGroup {
if (!SelfCardGroup._ins)
SelfCardGroup._ins = new SelfCardGroup();
return SelfCardGroup._ins;
}
public setInfo(str: string): void {
this._debugInfo.text = str;
this._debugInfo.x = (this.stage.stageWidth - this._debugInfo.textWidth) / 2;
this._debugInfo.y = 10;
}
/**得到一张牌 */
public addCard(cd: CardData, isDeal: boolean = false): void {
var card: CardSprite;
if (isDeal)//如果是发牌
{
card = new CardSprite(-1, cd);
card.delayFace();
}
else//如果是摸牌
{
card = new CardSprite(1, cd);
this.gogo();
}
this._cards.push(cd);
this._cardBox.addEle(card);
this.resize();
}
public resize(): void {
this._cardBox.y = this.stage.stageHeight - this._cardBox.height;
this._cardBox.x = (this.stage.stageWidth - this._cardBox.width) / 2;
this._deskBox.x = 10;
this._deskBox.y = this.stage.stageHeight - 400;
OptionBar.getIns().x = this.stage.stageWidth - OptionBar.getIns().width;
OptionBar.getIns().y = this.stage.stageHeight - 400;
this._debugInfo.x = (this.stage.stageWidth - this._debugInfo.textWidth) / 2;
this._debugInfo.y = 10;
}
/**make your choose */
public gogo(): void {
this._focusType = "";//重置当前操作类型
SelfCardGroup.getIns().setInfo("该你出牌...");
this._cardBox.addEventListener(egret.TouchEvent.TOUCH_TAP, this.tabHandler, this)
this.checkOpt("put");
}
/**do what? */
public looklook(): void {
this.setInfo("【" + LogicDemo.ins.__dealRing + "】出牌=" + CardSprite.getTxt(LogicDemo.ins.aiCard) + " 你要怎么操作?");
OptionBar.getIns().changeBtnState("过", true);
//如果有其他可操作的,放开确认
this.checkOpt("turn");
}
/**点击事件 */
private tabHandler(evt: egret.TouchEvent): void {
this._focusType = "";//重置操作类型
if (typeof (evt.target) != "object")
return;
var cCount: number = this._cardBox.numChildren;
for (var i: number = 0; i < cCount; i++)
this._cardBox.getChildAt(i).y = 0;
var target: CardSprite = evt.target as CardSprite;
if (this._focusCard == target) {
this._focusCard = null;
this.checkOpt("put");
return;
}
else {
this._focusCard = target;
this._focusCard.y = -20;
this.checkOpt("put");
}
}
/**检查当前可操作项目,自己的出牌环节 */
public checkOpt(t: string): void {
if (t == "put")//检查出牌
{
//检查自摸
//检查暗杠,检查明杠
OptionBar.getIns().changeBtnState("杠", this.checkGang());
//检查出牌和确认
OptionBar.getIns().changeBtnState("确认", true);
//这里不能过牌
OptionBar.getIns().changeBtnState("过", false);
}
else if (t == "turn")//检查所有
{
//检查胡牌
//检查明杠
var gangFlag: boolean = this.checkGang(LogicDemo.ins.aiCard);
OptionBar.getIns().changeBtnState("杠", gangFlag);
//检查碰牌
//如果有其他可操作项,这里就有确认
OptionBar.getIns().changeBtnState("确认", gangFlag);
//这里可以过
OptionBar.getIns().changeBtnState("过", true);
}
}
/**排序 */
public sortCards(delayTime: number = 0): void {
if (delayTime > 0) {
DelayCall.call(delayTime, this.sortCards, this);
return;
}
//------将牌进行排序-------
this._cards.sort(function (a: CardData, b: CardData): number {
if (a.cType * 10 + a.cNum > b.cType * 10 + b.cNum)
return 1;
return -1;
});
for (var i: number = 0; i < this._cards.length; i++) {
(this._cardBox.getChildAt(i) as CardSprite).setData(this._cards);
}
}
/**操作来了 */
public optionHandler(type: string): void {
switch (type) {
case "确认": this.option_queren();
break;
case "过":
this.clearOption();
LogicDemo.ins.goOn();
break;
case "杠":
this._focusType = "杠";
this.changeGang();
break;
default:
console.log("还未处理这个类型" + type);
break;
}
}
private clearOption(): void {
OptionBar.getIns().changeBtnState("过", false);
OptionBar.getIns().changeBtnState("确认", false);
OptionBar.getIns().changeBtnState("杠", false);
OptionBar.getIns().changeBtnState("胡", false);
OptionBar.getIns().changeBtnState("碰", false);
}
private doEnd(): void {
this._cardBox.removeEventListener(egret.TouchEvent.TOUCH_TAP, this.tabHandler, this)
this.clearOption();
LogicDemo.ins.optionEnd();
}
/**确认的操作响应 */
private option_queren(): void {
if (this._focusType == "")//出牌
{
if (this._focusCard == null)
this.setInfo("点击一张你要出的牌");
else {
var delIndex: number = this._cards.indexOf(this._focusCard.data);
this._cardBox.removeEle(this._focusCard);
this._cards.splice(delIndex, 1);
this.doEnd();
this.sortCards(0);
}
}
else {
switch (this._focusType) {
case "杠":
this.removeCardToDesk(this._cardKey, 4);
this.clearOption();
LogicDemo.ins.shiftOne();
break;
}
}
}
//-------------------------逻辑部分粗暴解决------------------------
//为了更好的性能和维护性,应该在玩家牌组发生变化的时候就计算好哪些是可以杠,哪些是可以碰的。这里懒的改了,随手写
/**显示多少个牌 */
private showKeys(key: string, count: number): void {
var cCount: number = this._cardBox.numChildren;
var i: number = 0;
for (i = 0; i < cCount; i++)
this._cardBox.getChildAt(i).y = 0;
var cs: CardSprite;
var cc: number = 0;
for (i = 0; i < cCount; i++) {
cs = this._cardBox.getChildAt(i) as CardSprite;
if (cs.data.key != key)
continue;
cs.y = -20;
cc++;
if (cc >= count)
return;
}
}
/**移动牌到桌子 */
private removeCardToDesk(key: string, count: number): void {
var cCount: number = this._cardBox.numChildren;
var i: number = 0;
for (i = 0; i < cCount; i++)
this._cardBox.getChildAt(i).y = 0;
var cc: number = 0;
if (LogicDemo.ins.aiCard && LogicDemo.ins.aiCard.key == key) {
cc++;
this._deskCards.push(LogicDemo.ins.aiCard);
LogicDemo.ins.aiCard = null;
}
var keyc: any;
var cd: CardData;
for (keyc in this._cards) {
if (cc >= count)
break;
cd = this._cards[keyc];
if (cd.key == key) {
cc++;
this._deskCards.push(cd);
}
}
for (keyc in this._deskCards) {
cd = this._deskCards[keyc];
i = this._cards.indexOf(cd);
if (i >= 0)
{
this._cards.splice(i, 1);
this.removeCardByID(cd.id);
}
}
this.sortCards(0);
var index:number = 0;
if(count==4)
count=1;
while(this._deskBox.numChildren<this._deskCards.length)
{
var putIndex:number = this._deskBox.numChildren;
var dsc:CardSprite = new CardSprite(index++<count?1:-1,this._deskCards[putIndex]);
this._deskBox.addEle(dsc);
}
}
/**移除显示 */
private removeCardByID(cid: number): void {
var cCount: number = this._cardBox.numChildren;
var i: number = 0;
for (i = 0; i < cCount; i++) {
var cs:CardSprite = this._cardBox.getChildAt(i) as CardSprite;
if(cs.data.id == cid)
{
this._cardBox.removeEle(cs,false);
break;
}
}
}
private addCardToMap(map: Map<string, number>, c: CardData, checkHas: boolean = false): void {
if (map.get(c.key) == null && !checkHas)
map.set(c.key, 1);
else
map.set(c.key, map.get(c.key) + 1);
}
/**
* 明暗杠检查
* 重点:无论是明杠还是按杠,首先必须受伤要有这个牌.
*/
private checkGang(fromCard: CardData = null): boolean {
var oc: CardData = fromCard;
this._gangArray = [];
this._gangIndex = 0;
var handMap: Map<string, number> = new Map<string, number>();
var keys: string[] = [];
if (fromCard != null)//说明是杠他人的牌,只算手牌
{
this.addCardToMap(handMap, fromCard);
keys.push(fromCard.key);
}
var key: any;
for (key in this._cards) {
fromCard = this._cards[key];
this.addCardToMap(handMap, fromCard, oc != null);
if (keys.indexOf(fromCard.key) < 0)
keys.push(fromCard.key);
}
for (key in this._deskCards) {
fromCard = this._deskCards[key];
this.addCardToMap(handMap, fromCard, true);
}
for (key in keys) {
if (handMap.get(keys[key]) >= 4)
this._gangArray.push(keys[key]);
}
return this._gangArray.length > 0;
}
/**更换杠的组合 */
private changeGang(): void {
this._cardKey = this._gangArray[this._gangIndex];
this.showKeys(this._cardKey, 4);
this._gangIndex++;
if (this._gangIndex >= this._gangArray.length)
this._gangIndex = 0;
}
}[/mw_shl_code]
大概结构和最主要的两个类,都是比较粗暴的解决了。
从main.entergame开始,这里没有改框架生成的代码。
逻辑代码的衔接主要在
SelfCardGroup的checkOpt();
"put" = 出牌
"turn" = 等待过牌
optionBar中用了中文,主要是为了方便阅读。
CardType里1-3对应筒条万
|