CocosCreator实现UNO纸牌游戏

1,678 阅读3分钟

CocosCreator实现UNO纸牌游戏

摘要

模仿4399小游戏UNO颜色纸牌,通过typescript语言开发,代码注释较多,适合学习。 游戏已打包为App,可以通过 百度网盘 提取码:9i4j 进行下载,源代码以上传cocos商店,希望感兴趣的小伙伴能够支持一下~~

正文

使用版本

CocosCreator2.4.5

游戏演示

玩法说明 发牌 退出游戏

玩法说明

UNO纸牌已经风靡全球数十年,被誉为是世界上最好玩的纸牌游戏,据说由意大利一个理发师发明,简单易学,版本众多,被加入许多新的功能,玩法更加刺激,而在此游戏中最考的是集中和反应,还有相互间的思维较量。 每副uno牌包括:108张牌和一张说明书(108 张纸牌中包括80张数字牌,28张特殊牌)。Uno由红黄蓝绿4种颜色,每种色牌有0~9号牌各两张,各种颜色还各有6张普通功能牌(“draw 2(加两张)”、“skip(跳过下家)”、“reverse(逆转方向)”各两张。 首先,每人发8张牌,胜利条件是谁的牌首先出完;可以出与上家颜色相同或数字相同的牌,或者wild牌。然后,可以出draw 2(+2) 或draw 4(+4)来陷害下家,让下家摸牌,下家可以出相应的牌来转移或累加要摸的牌,直到最后被陷害的玩家没有更大的牌时,就要摸相应的数量的牌,这样总有人要摸很多牌。然后,玩家在打完倒数第二张牌时要喊UNO(剩一张),捉住其他玩家忘了喊剩一张而罚他摸两张也是游戏的乐趣之一 每副游戏牌共有108张卡牌,游戏牌分四种颜色:红色、绿色、蓝色及黄色,每种颜色各有25张牌(合共100张),其中20张为数字牌(0-9有两张),其余6张(24张)为功能牌:“skip”(跳牌)、“draw two”(罚牌2张)及"reverse"(反转出牌方向),每种各2张。另有黑色特别牌2张:“wild”(转色)及"wild draw four"(转色及罚牌2张),每种各2张。

架构说明

游戏采用MVC架构,通过事件派发实现解耦合,通过controller层管理数据层和视图层,数据层关联卡牌数据,通过事件派发的形式进行视图层渲染,实现游戏的逻辑控制。其中prefab的渲染,控件的操作和脚本的绑定不依赖拖拽的方式,而是通过代码实现,尽量减少编辑器与游戏的耦合。 编辑器说明

代码说明

  • View基类,所有视图相关的脚本都基于View类,通过show_ui_at方法加载prefab预制体并挂载对应的脚本,load_all_object方法获取视图的全部子节点,方便通过代码的方式来对node节点进行操作。
import OnEventMode from "./OnEventMode";
const { ccclass, property } = cc._decorator;

@ccclass
export default class View extends OnEventMode {

    // 展示对应的UI(Prefab)
    protected show_ui_at(parent: cc.Node, ui_name: string, target?: any, isAnimation?: boolean, callbackEvent?: string, ...args: any) {
        let location = 'panel'
        let name = ui_name
        if (isAnimation) {
            location = 'animations'
            name = 'UIAnimation'
        }
        cc.resources.load(`/prefab/${location}/${ui_name}`, cc.Prefab, (err, prefab) => {
            if (err) {
                console.warn(err)
            } else {
                let node = cc.instantiate(prefab as cc.Prefab)
                node.parent = parent
                node.addComponent(name)
                if (target) node.getComponent(name).init(target, ...args)
                if (callbackEvent) {
                    this.emit(callbackEvent, node)
                }
            }
        })

    }

    //    加载UI面板的全部children
    protected load_all_object(root: cc.Node, path: string) {
        let view = {}
        view = this.loadObj(root, path, view)
        return view
    }

    private loadObj(root: cc.Node, path: string, view: any): any {
        let result = view
        for (let i = 0; i < root.childrenCount; i++) {
            view[path + root.children[i].name] = root.children[i]
            this.loadObj(root.children[i], path + root.children[i].name + '/', result)
        }
        return result
    }
}
  • GameEventListen类,继承cc.EventTarget,通过单例的方式用于事件派发。
const { ccclass, property } = cc._decorator;

@ccclass
//继承cc.EventTarget,事件派发基类
export default class GameEventListen extends cc.EventTarget {

    private static _event: GameEventListen = null
    public static ins() {
        if (!this._event) {
            this._event = new GameEventListen()
        }
        return this._event
    }
}

  • GameEventListen 类,重新封装了派发事件,方便子类继承与实现。
import GameEventListen from "./GameEventListen";

const {ccclass, property} = cc._decorator;

@ccclass
export default class OnEventMode extends cc.Component {

     protected on(type:string,callback:Function,target?:any,useCapture?:boolean){
       GameEventListen.ins().on(type,callback,target,useCapture)
   }

   protected emit(type:string,...args:any){
       GameEventListen.ins().emit(type,...args)
   }

   protected off(type:string,callback:Function,target?:any){
       GameEventListen.ins().off(type,callback,target)
   }
}

代码部分暂时展示到这,展示了主要的基类,而关于游戏逻辑部分的model层和view层,因为代码量较多,就不一一展示说明了,可以先去4399小游戏试玩下原版游戏,也可以通过app下载本游戏 (提取码:9i4j)进行试玩,感兴趣的小伙伴希望能够下载支持一下~~