cocoscreator 搭建小游戏

Posted 易小顺

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cocoscreator 搭建小游戏相关的知识,希望对你有一定的参考价值。

1、 游戏基本介绍

1.1 游戏介绍

  • 本游戏主题是探索收集类的 RPG游戏,对于剧情任务没有太多的设计,是一个自由探索度较高的游戏。

  • 人物可通过在地图上的自由探索获得宝箱,在野外刷怪获得经验进行升级,获取相应的奖励,游戏特点是在玩家被击败之后将会失去所有的拾取物品,但是会保留当前的hero等级。

  • 采用的程序设计语言是 javascript 脚本语言,适用于和引擎进行交互,利用 cocos creator 游戏引擎进行游戏外观的整体实现,内层逻辑由编写的脚本进行控制。

1.2 游戏思想

  • 主角设定是 hero ,游戏版图是 迷宫式 的大地图,通过在一个地图上 探索收集 装备,打怪 获得经验升级;NPC的设定是静态的,当hero接近时便会与之进行交谈,获取迷宫的信息或普通的交谈对话;
  • monsterNPC 有一样的规则设定,但是与hero的唯一交互就是战斗。
  • 当hero接近游戏地图的传送点时会进行游戏的传送,但是会实现进行hero等级的检测,如果没有满足相应的等级要求,则不能进行地图的传送,也就是所谓的通关。
  • 地图的周围有墙体限定,hero不能越过地图边界,防止出现穿模现象。
  • 在通过某些特定的场景或者是特殊的monster时,会开启场景的音效设置,包括人物的释放技能,与NPC的交互等等。

2、 游戏规划

  • 第一步:在确定游戏的整个流程走向之后,便开始针对hero,monster,NPC等进行属性、行为设计(预先规划可能会与后面的实现有些许的冲突,最终的效果由后期完善的结果为准),属性设计完成之后便开始寻找相关的素材贴图。

  • 第二步:对游戏素材进行一个处理,将一类型之类的素材进行打包防止,防止内部资源访问错乱。确定主要人物的行走、攻击动作,各种UI界面的贴图,按键的响应动画,敌人的动作,制作地图即游戏背景,还有设计与NPC有关的剧情设计,寻找合适的背景音乐,音效等等,游戏的大部分素材此阶段完成准备,后期需要的特定素材再进行单独的处理。图片的预处理由 ShoeBoxTexturePackerGUI 等图片处理工具进行,包括动态动作的拆分序列、重新打包成合集图片等等。

  • 第三步:搭建游戏主场景,制作相关的人物预制体,包括技能、怪物等动画制作。

  • 第四步:按照游戏设计规划,进行游戏脚本的编写,逐步实现整个游戏的制作。

  • 第五步:游戏整体测试,完善逻辑,修复bug,打包发布。

3、 游戏功能设计

 3.1 地图设计

  由于是探索式的收集游戏,地图采取大图的方式,视图窗口随着hero的移动而在整个大背景地图上进行移动。避免 游戏穿模 的现象发生,在 房屋城墙树木 等应具有实体的物体上添加碰撞检测,全部设计为静态的floor层级,当与hero的层级对象进行碰撞时,将静止hero进行任何方向的位置偏移,也就限制hero的活动范围。当hero满足一定的条件后会开启下一个地图的通道,可实现场景的切换,地图间的设定规格一致。

游戏地图

 3.2 界面设计

  游戏涉及的UI界面不多,主要是绑定在hero身上的一个大界面以及一个显示当前hero所拥有的物品的背包界面,代表hero拥有的 金币钻石的UIhero等级血量蓝量名称的UI背包 及设置界面的按钮UI,以及各类的 游戏物品 。用户刚进入游戏时会在主界面进行停留,根据用户的选择而进行游戏的具体开展。
游戏界面

登陆界面

 3.3 交互设计

  整个游戏的交互系统都是由hero进行触发的,hero靠近宝箱时会随机产生一个宝物被hero所拾取,同时会获得相应的金币和钻石。靠近游戏的NPC时会进行相应的对话交谈,遇见monster时可以选择交战或者逃 走,战胜则可获得hero升级所需的经验,有几率掉落稀有的物品。

NPC 交互

 3.4 角色设计

  作为一个RPG游戏,首先的需求便是玩家操控的角色,在此游戏中为一个hero人物,玩家操作此角色在游戏中任意探索。

  玩家对应一个角色,开始游戏,随着后面关卡的发展,会有不同敌人出现,玩家扮演的hero角色对抗monster,玩家可根据游戏规则进行相应的攻击玩法。

  给每个角色的属性:bloodBase(基础血量),bloodTime(实时血量), blueBase (基础蓝量),blueTime(实时蓝量),experice(经验值),grade (等级),attack(攻击力),property(随机属性增强),goal(金币),diamond(钻石)。这些属性初始值决定这个角色的生命值魔法值经验值,通过对抗每个属性值会减少,生命值也会降低。如果生命值为零,则说明游戏失败。

  HP初始值为 100,BP初始值为 100 ,EXP初始值为 0,需要玩家通过游戏来获取,游戏中途会掉落宝箱,有可能会有宝物,或其他道具来提升属性,战胜monster也会获得一些奖励。

  • 每个属性初始值:

    初始属性基础血量实时血量基础蓝量实时蓝量经验值
    等级*100100等级*1001000
    等级金币钻石攻击属性
    100201

  说明:

  初始值:HP=100,BP=100,EXP=0

  每升一级提升1个属性点,属性点随机增强hero的各项属性技能,按照0-0.5之间的偏移变化,游戏为自由随机机制,属性会随机分配,同样的条件下可能会产生不一样的结果,玩家可自行探索。

hero

 3.5 敌人设计

  其次需要与主角作战的敌人,在此游戏中为世界各地的怪物,包括鸡怪、鸭怪、狗怪、猪怪以及大龙等。

  敌人其实和玩家操作的角色相同,只不过随着hero的升级,我们遇到的属性更加强大,游戏难度会随之加大。玩家需要根据实际情况进行对战,合理攻击并击败敌人夺取胜利。

  给每个角色的属性:bloodBase(基础血量),grade(等级),property(随机属性增强)。这些属性初始值决定这个角色的生命值。生命初始值为100,通过对抗属性值会减少,生命值也会降低。如果怪物生命值为零,说明玩家胜利 ,敌人的生命值一般是不可以增加的,但存在特殊的monster会存在增加生命的技能属性,而玩家可以使用道具来恢复生命。

  • 每个属性初始值

    角色/属性力量敏捷血量智慧
    200.210025
    450.210040
    700.210060
    800.210075
    900.4100095

dragon

 3.6 装备设计

  为了增加游戏性,还需要装备系统,应分为不同品质,使玩家乐意花时间去刷装备,增加他们的游戏时间。

  游戏装备应该有服装,玩家可以使用获得的金币,去购买一些更好看的服饰,装扮物品,来提升游戏体验。

  还有道具,玩家可以在游戏开始前,前往商店,使用金币,购买一些能够提升技能的装备,让自己更加强大对抗敌人,还可以购买一些让自己恢复的药品。

  宝箱:玩家可以购买宝箱,然后打开,里面会有随机物品出现,有可能是钱币,一份,道具,装扮,经验卡,复活卡,等东西。针对不同属性的恢复药品。

  玩家所有的东西都可在背包中查看。

bag

4、 游戏程序设计

 4.1 HeroControl.js

游戏的所有线索由hero进行推动,也就是控制hero的脚本控制整个游戏的走向,其他的脚本起到丰富游戏的作用。Hero有一个全局属性目录,包括背包属性、物品属性等,这一系列的属性归整个游戏所共有,可以方便数据的更新处理。

var box = require("BoxControl");

cc.Class({
    extends: cc.Component,
    
    properties: {
        //  播放主键
        m_animation : cc.Animation,
        m_sprite : [cc.Sprite],
    },
    //  游戏加载时的函数
    onLoad: function () {
        //  当前hero的移动方向
        this.move = 0;
        //  当前hero的技能标记
        this.kill;
        //  英雄等级标签
        var nodeGrade = cc.find("Canvas/Main/Hero/name/grade");
        this.gradeString = nodeGrade.getComponent(cc.Label);
        this.gradeString.string = "等级:" + hero.grade;
        //  注册按钮事件
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
        //  hero静止
        this.m_animation.play("3");
        //  获取当前的经验条
        this.experice = cc.find('Canvas/Main/Hero/Experiencebar/Time');
        // 记载金币钻石
        this.heroDiamondChange();
        //  获取本地的技能预制
        this.bone = cc.loader.loadRes("Prefab/bone", cc.Prefab, (err, prefab) => {
            //  加载错误则报错
            if (err) {
                console.error(err);
                return;
            }
            this.newMyPrefab = cc.instantiate(prefab);
            
        });
    },
    //  游戏的帧处理 控制hero的移动
    update: function (dt) {
        this.bloodDetection();
        this.actionJudge();
        if(this.move == 1){
            this.node.x += speed;
        }
        else if(this.move == 2){
            this.node.x += -speed;
        }
        else if(this.move == 3){
            this.node.y += speed;
        }
        else if(this.move == 4){
            this.node.y +=  -speed;
        }
    },
    //  设置代表金币和钻石的数量
    heroDiamondChange: function() {
        //  获取金币标签父节点
        var nodegoal = cc.find("Canvas/Main/Hero/buttongoal/New Label");
        //  取得金币标签并进行数量设置
        var goal = nodegoal.getComponent(cc.Label);
        goal.string = hero.goal;
        //  获取钻石标签父节点
        var nodediamond = cc.find("Canvas/Main/Hero/buttondiamond/New Label");
        //  取得钻石标签并进行数量设置
        var diamond = nodediamond.getComponent(cc.Label);
        diamond.string = hero.diamond;
        //  hero经验条的变换
        this.expericeChange();
    },
    //  更改播放的动画
    animationChange: function(data){
        if(this.actionJudge()){
            //  右移动画
            if(this.move == 1)
                this.m_animation.play("runr");
            //  左移动画
            else if(this.move == 2)
                this.m_animation.play("runl");
            //  上移动画
            else if(this.move == 3)
                this.m_animation.play("runu");
            //  下移动画
            else if(this.move == 4){
                this.m_animation.play("rund");
            }  
            //  攻击动画
            else if(this.move == 5){
                this.playingKill();
            }
        }
    },
    //  按键按下时的响应函数
    onKeyDown:function(event){
       switch(event.keyCode){
            //  按下D键      
            case 68:{
                this.move = 1;
            }
                break;
            //  按下A键
            case 65:{
                this.move = 2;
            }
                break;
            //  按下W键
            case 87:
                this.move = 3;
                break;
            //  按下S键
            case 83:
                this.move = 4;
                break;
            //  按下K键
            case 75:
                pickUp = 1;
                break;
            //  按下H键
            case 72:
                this.move = 5;
                this.kill = 1;
            break;
            case 74:
                this.move = 6;
            break;
        }
        this.animationChange("");
    },
    //  按键弹起时的响应函数
    onKeyUp: function(event){
       switch(event.keyCode){
           case 68:
           break;

           case 65:
           break;

           case 87:
           break;

           case 83:
           break;

           case 75:
           pickUp = 0;
           break;
       }
       this.move = 0;
       this.heroDiamondChange();
    },

    //  检测是否可以进行动画的播放
    actionJudge: function() {
        if(this.m_animation.getAnimationState("kill_swing")._isPlaying){
            speed = 0;
            return false;
        }
        else{
            if(this.node.getChildByName("bone") != null){
                this.newMyPrefab.removeFromParent();
                this.animationChange();
                speed = 1.5;
            }  
            return true;
        }
    },

    //  hero血条的实时响应方法
    bloodDetection: function() {
        //  人物血条制作
        this.m_sprite[0].fillRange = hero.bloodTime / hero.bloodBase * hero.grade;
        this.m_sprite[1].fillRange = hero.blueTime / hero.blueBase * hero.grade;       
    },

    //  hero经验条的更新检测
    expericeChange: function() {
        //  如果经验条满了
        if(hero.experice >= 100 * hero.grade){
            hero.experice -= 100 * hero.grade;
            hero.grade += 1;
            this.gradeString.string = "等级:" + hero.grade;
            expericeChange();
        }
        //  如果经验条没满
        else{
            this.experice.scaleX = hero.experice / (100 * hero.grade);
        }
    },

    //  技能播放
    playingKill(){
        if(this.kill == 1){
            this.m_animation.play("kill_swing");
            this.node.addChild(this.newMyPrefab);
            this.newMyPrefab.setPosition(-200, 0);
        }
    }
});

 4.2 BoxControl.js

控制游戏的一切界面交互,例如游戏界面的跳转、背包界面的打开、hero物品的生成等等。

cc.Class({
    extends: cc.Component,
    properties: {
        packet: {
            default: null,
            type: cc.Node,
            count : Boolean,
            display : Boolean,
        },
        monsterbame: {
            default: null,
            type: cc.Node,
        },
    },
    
    //  场景初始化
    onLoad: function () {
        //  monster的血条显示
        this.sign = true;
        //  背包的点击状态
        this.packet.count = true;
        //  背包显示情况
        this.packet.display = true;
        //  怪物血条的刷新频率
        this.loadMonsterBloodPassTime = 0.2;
        this.loadMonsterBloodNowTime = 0;
        //  怪物血条和名字控件
        this.monstername = this.monsterbame.getChildByName("name").getComponent(cc.Label);
        this.monsterblood = this.monsterbame.getChildByName("ui").getChildByName("blood").getComponent(cc.Sprite);
        //  注册按钮事件
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);

    },

    update: function (dt) {
        //  累计刷新时间
        this.loadMonsterBloodNowTime += dt;
        if(this.loadMonsterBloodNowTime > this.loadMonsterBloodPassTime){
            this.loadMonsterBloodNowTime = 0;
            if(isLoad){ 
                this.loadMonsterBlood();
                this.sign = false;
            }
            else{
                this.removeMonsterBlood();
                this.sign = true;
            }
        }
        
    },
    //  按键按下时的响应函数
    onKeyDown:function(event){
        switch(event.keyCode){    
            //  按下 B 键  
            case 66:
            this.bagClick();
                break;
         }
     },

    //  背包点击方法
    bagClick: function(data){
        if(this.packet.count){
            //  将背包显示到界面
            this.packet.setPosition(0, 0);
            this.packet.count = false;
            speed = 0;
            this.loadGoods();
        }
        else if (!this.packet.count){
            //  将背包移除界面
            this.packet.setPosition(1000, 0);
            this.packet.count = true;
            this.packet.display = true;
            var node = cc.find('Canvas/Main/Hero/package');
            //  移除所有物品
            node.removeAllChildren();
            speed = 1.5;
        }
    },

    //  背包物品加载
    loadGoods: function() {
        var node = cc.find('Canvas/Main/Hero/package');
        node.removeAllChildren();
        if(this.packet.display){
            cc.loader.loadRes('Interface/button1',cc.SpriteAtlas, (以上是关于cocoscreator 搭建小游戏的主要内容,如果未能解决你的问题,请参考以下文章

CocosCreator背景图循环播放

(转)CocosCreator零基础制作游戏《极限跳跃》添加游戏主场景控制脚本

cocos creator见缝插针源码游戏结束的代码逻辑

(转)CocosCreator零基础制作游戏《极限跳跃》十游戏打包发布,游戏复总结

CocosCreator + JavaScript游戏开发

(转)CocosCreator零基础制作游戏《极限跳跃》游戏分析