毕业设计:移动端的游戏开发

前言

  这个月要完成毕业设计,时间非常的紧迫,但是我打算写一篇博客记录下开发过程。总结会令写一篇博客。
  毕设同时也是我的学习科技项目,所以难度还是有的,并且里面还有一些非技术类的问题,比如如何实现该游戏完成教育意义?

题目的意义与要求

意义

  题目的意义简明的说,就是作为一款游戏,它具有寓教于乐的功能。可以帮助大学生以及初高中生更深入的了解编程。

要求

  1. 移动端双平台,iOS和Android皆可以运行。
  2. 寓教于乐(这点当然是最后才做的)
  3. 游戏具有用户数据库、可以保存用户的某些数据。
  4. 可以自定义关卡(自己坑自己)

  大概就是这样的一款游戏:用户通过一系列指令,让一个物体移动起来,完成制定任务,获得成功。

由于我使用的是Mac,所以下面的部分内容可能不适用于Windows环境,如有错误请及时指正。

时间紧迫,所以文章中的知识点以及问题,大多数都是标题,没有补充进来。等时间轻松下来,毕设基本完成时我会做补充。


目录

    • 前言
    • 题目的意义与要求
      • 意义
      • 要求
    • Day01 开发环境的选择&配置
      • 开发环境的选择
      • 配置开发环境
    • Day02 熟悉界面&编写Demo
    • Day03 查阅资料&制定计划
      • 查阅资料:
      • 计划:
    • Day04 完成计划之一:让物体移动
      • 知识点:基本操作
      • 代码
      • 问题:this.node不存在
      • 计划:
    • Day05 完成计划之二:通过按钮提交动作
      • 知识点:require
      • 知识点:RichText
      • 代码
      • 问题:Creator打不开项目
      • 计划:
    • Day06 完成计划之三:实现到达目的地弹出窗口
      • 知识点:导入prefab文件
      • 知识点:导入为插件
      • 问题:愚蠢的导入资源操作
    • Day07-Day11:(傻哔–)碰撞体
      • 知识点:碰撞体
      • 知识点:AAbb
      • 知识点:Update
      • 知识点:再谈this
      • 问题:动作不连贯
      • 问题:碰撞体的碰撞面积问题
      • 计划:
    • Day12:(傻哔–)碰撞体 续集
      • 知识点:数组
      • 知识点:以this的方式在对象中添加属性
      • 问题:关于碰撞体的小bug
        • 描述
        • 解决
      • 计划:
    • Day13:弹窗
      • 问题1:场景内的Canvas重复
      • 问题2:第二次无法正确弹出窗口
      • 知识点:undefined与null
    • Day14:拖拽控件,以及RichText,还有潜在的问题
      • 问题1:RichText追加字符串时第一行的固定
      • 问题2:Prefab无法加载
      • 问题3:Prefab修改后无效
      • 问题4:不同尺寸的设备,碰撞体失效的问题
      • 关键代码
    • Day15:想弄个编译器?做梦吧
      • 问题1:require获取不到cc.class
      • 问题2:同一个函数无法执行两次??
      • 问题3:Prefab生成后位置错了
      • 知识点:require
      • 知识点:组件的初始化顺序
    • Day16:游戏逻辑
      • 问题1:Prefab无法对应修改Label.String
      • 问题2:cannons.string = self.node.string?
      • 知识点:访问其他节点的方式
    • Day17:游戏逻辑 节点动过逻辑语句驱动
      • 问题1:cc.class不能通过构造函数传参数
      • 知识点1:cc.class
    • Day18:游戏逻辑 模拟For语句
      • 问题1:return的返回
      • 问题2:this.schedule()的停止与递归的关系
      • 知识点1:计时器
    • Day19:补充逻辑,UI的热身操作
      • 问题1:cocoscreator的 节点层级与画布z轴的关系
      • 问题2:编辑器运行程序加载界面的异常
      • 问题3:不同设备下的碰撞体失误
      • 知识点1:string的拆分操作


Day01 开发环境的选择&配置

2017.10.xx 耗时:4h

开发环境的选择

  开发环境选择的是Cocos Creator,查了一下资料,在Unity和Cocos Creator之间选择了后者,Cocos Creator的可兼容性很强,适用于iOS、Android、Web,开发的难度也不是很高。至于两者之间具体的比较,请查看文章。

配置开发环境

Cocos Creator下载:官网
Cocos Creator配置:安装及配置教程
同时我使用了VS作为开发工具,在安装配置教程里有相关说明。


Day02 熟悉界面&编写Demo

2017.12.21 耗时:4h

  熟悉界面,编写demo。
  demo是官网教材中的。
  注:demo的最后部分官网给出的代码有误,下载官网做好的demo替换错误代码即可。


Day03 查阅资料&制定计划

2018.1.29 耗时:3h

查阅资料:

  看了一下用户手册,基本了解了一下JavaScript及CC.class:脚本开发指南

计划:

  接下来的几天主要完成,越快越好:

  1. 实现点击button可以移动一个物体(节点)移动。
  2. 当节点移动的制定位置时,弹出成功label。
  3. 点击commit,执行红色的节点动作。实现user节点移动到target,弹出成功按钮。
    毕业设计:移动端的游戏开发_第1张图片

PS:我觉得这个毕设,以我的能力非常难做完。


Day04 完成计划之一:让物体移动

2018.1.30 耗时:4h

毕业设计:移动端的游戏开发_第2张图片

  这就是今天的结果(我也不想做的这么丑)。

知识点:基本操作

代码

  新建两个节点,用户控件(鸟头),以及按钮(left…right…)

//leftbutton.js
cc.Class({
    extends: cc.Component,
    properties: {
    //用户节点,点击按钮时移动用户节点。
        user:{
            default: null,
            type: cc.Node
        }
    },
    onLoad: function () {
        var usernoed = this.node;//获取按钮节点
        var userb = this.user;//获取用户节点
        //注册事件:点击按钮后移动用户节点
        usernoed.on('touchstart',function(){
            userb.runAction(cc.moveBy(0.1,-10,0));
        });
    },
});

  将leftbutton.js拖拽至scene中的button 中。
毕业设计:移动端的游戏开发_第3张图片
  将用户节点拖拽至user处。运行程序即可。
  今天的代码和day05是一样的(昨天没想起来发),今天只需要看leftbutton.js,并保持scene中有一个节点和button即可。
  具体代码:代码

问题:this.node不存在

  注册了事件后,发生了一个错误,代码如下:

cc.Class({
    extends: cc.Component,

    properties: {   
        user:{
            default: null,
            type: cc.Node
        }
    },

    // use this for initialization
    onLoad: function () {
        //有错误
        this.node.on('mouseup',function(){
            this.node.runAction(cc.p(50,50));
            console.log("move!");
        });
},
});

  错误懒得贴了,大概意思是:找不到node节点。
  作为一个没学过Js的人,我询问了一下大神,他给出的结论是:

this指的是当前的脚本,脚本继承的是组件(extends:cc.Component),所以this指的是当前组件。this.node则是这个脚本组件的节点。当在不同的环境下调用的时候(this.node)他的返回值是不一样的。

  其实我没看懂。

  关于this很基础,印象中老师在课上讲过this的用法,在不同的类中当然是不同的结果。但是我并不知道不同函数中,也会呈现不同的结果(function和onload中)。其实我还是不太明白两个不同的函数使用this为什么也会出现这种差异。

  后来又出现了一个问题。

 onLoad: function () {
        this.node.on('touchstart',function(){
            this.user.runAction(cc.moveBy(0.1,10,0));
        });

  改为下面的代码则正常运行:

 onLoad: function () {
        var usernoed = this.node;
        var userb = this.user;
        usernoed.on('touchstart',function(){
            userb.runAction(cc.moveBy(0.1,10,0));
        });

  查看了一下开发手册,找到了一篇参考文章this 的值到底是什么?一次说清楚:

  在Js中,函数调用只有一种形式:

func.call(context, p1, p2)

  其他两种都是语法糖,可以等价地变为 call 形式:

func(p1, p2) 等价于func.call(undefined, p1, p2) obj.child.method(p1, p2)
等价于obj.child.method.call(obj.child, p1, p2)

  所以,this其实就是指context。call 一个函数时,传入的 context。
  另外:

如果你传的 context 就 null 或者 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)

  在网页中是window对象,在我出现的问题里,他是严格的 undefined。

  而unload和function的context是不同的,所以this当然会不用,并且,在function中context为默认,所以就出现了undefined的错误。

  这里还有一个问题,就是我并不知道context是什么,虽然有印象但是都忘光了。(基础有多差可见一斑),看了这篇文章,大体了解了什么是context,编程中什么是「Context(上下文)」?对于我刚刚出现的错误,在onload里就是该对象,而在监听事件里,context就是undefined(因为没有定义)。

  关于this,以后会单独整理出来:待续

计划:

  Day2中的三个目标目前完成:

  1. 实现点击button可以移动一个物体(节点)移动.
  2. 当节点移动的制定位置时,弹出成功label。
  3. 点击commit,执行用户节点动作。实现user节点移动到target,弹出成功按钮。

  还需要多学习,今天询问this的时候被无情的嘲讽了一番。

  关于this,还有一篇进阶的文章:你怎么还没搞懂this


Day05 完成计划之二:通过按钮提交动作

2018.1.31 耗时:4h

毕业设计:移动端的游戏开发_第4张图片

  点击了down一会,将down提交至右边的richtext中。
  今天主要是学习知识,require和数组之类的基础知识。实现了如图所示的功能,将操作保存至数组,点击commit就执行。

知识点:require

知识点:RichText

代码

  需要三个节点,用户节点,两个button,分别用来选择操作和提交用户选取的操作。

//op.js 存储用户选择的操作。
var cfg =  new Array(3);
cfg[0] = 0;
cfg[1] = 0;
cfg[2] = 0;
module.exports = cfg;
//commit.js 提交按钮,读取op中的操作。
cc.Class({
    extends: cc.Component,
    properties: {
        user:{
            default: null,
            type: cc.Node
        },
    },

    onLoad () {
        var commit = this.node;
        var oprate = require("op");
        var userb = this.user;
        commit.on('touchstart',function(){  
         if(oprate[0]=="down")
         {
            userb.runAction(cc.moveBy(0.1,0,-10));
         }
        });
    },
});
//downbutton.js
cc.Class({
    extends: cc.Component,
    properties: {
    //用户节点
        user:{
            default: null,
            type: cc.Node
        },
        //richtext 用来显示用户选取的操作
        textboard:{
            default: null,
            type: cc.RichText
        }
    },

    // use this for initialization
    onLoad: function () {
        var usernoed = this.node;
        var userb = this.user;
        var textboard = this.textboard;
        var oprate = require("op");
        usernoed.on('touchstart',function(){
            userb.runAction(cc.moveBy(0.1,0,-10));
            oprate[0] = "down";
            textboard.string += ""+ oprate[0]+"\n";  
        });
    },
});

将commit.js downbutton.js分别添加至各节点的组件中。op用来保持数组,不用添加。
具体代码:这里写链接内容

问题:Creator打不开项目

  为什么打不开?

计划:

  Day2中的三个目标目前完成:

  1. 实现点击button可以移动一个物体(节点)移动.
  2. 当节点移动的制定位置时,弹出成功label。
  3. 点击commit,执行用户的节点动作。实现user节点移动到target,弹出成功按钮。

Day06 完成计划之三:实现到达目的地弹出窗口

2018.2.1 耗时:3h

毕业设计:移动端的游戏开发_第5张图片

  今天真是起起伏伏,在询问大神,发帖子等一系列救助措施无果后,绝望的我硬着头皮排查到了错误。真的是差点哭出来。本来已经困的已经睁不开眼,现在彻底精神了。

  还是有些困,睡醒回来写

知识点:导入prefab文件

知识点:导入为插件

问题:愚蠢的导入资源操作

  网友的弹窗插件,


Day07-Day11:(傻哔–)碰撞体

2018.2.6 耗时:10h

这里写图片描述
失败1

毕业设计:移动端的游戏开发_第6张图片
失败2

毕业设计:移动端的游戏开发_第7张图片
成功1

  这些天我的心路历程应该可以拍部电影了。把官方例子套进去一切正常,改为通过按键运动以后就无法实现障碍物的设计。折腾了三四天才弄好。其实是一件很简单的事。

  关于碰撞体,我下载了官网的demo。测试全部正常,包含各种情况,有需求的同学可以去 GitHub官方Demo 下载。

知识点:碰撞体

  碰撞体的设置与实现并不难,只需实现几个函数,困难的是如果你想实现触碰以后的操作,如障碍物、反弹等等效果需要自己写出来,并不能通过物理引擎来直接使用。

知识点:AAbb

知识点:Update

知识点:再谈this

问题:动作不连贯

问题:碰撞体的碰撞面积问题

计划:

  Day2中的三个目标已完成,接下来是:

  1. 搭建一个类似迷宫的场景,节点在运动时不会穿墙的反人类动作。
  2. 到达目标点,游戏结束。返回主界面
  3. 点击开始进入游戏。
  4. 节点的动作通过按钮执行。

  这两天沉迷拍立得不能自拔,耽搁了两天,今天的日志更新其实是12号写的,也就是说我整整一个礼拜没有写了。
  其实写到今天,并没有受到太多帮助。写整个程序,更多的是磨练了我的耐心。
  重要的是学习能力以及耐心和虚心,编程的能力排在后面。
  更重要的:有轮子就用,别自己写。

代码:点这里,以后只发下demo吧,只发代码好像没什么意义。


Day12:(傻哔–)碰撞体 续集

2018.2.14 耗时:6h

  为什么还在写碰撞体,因为昨晚我发现了一个问题,这个问题是由于我并不熟悉物理机制已经js代码的编写造成的。其实是一个很简单的bug,最后再讲。先上图:

毕业设计:移动端的游戏开发_第8张图片
失败1
毕业设计:移动端的游戏开发_第9张图片
失败2
毕业设计:移动端的游戏开发_第10张图片
成功

知识点:数组

知识点:以this的方式在对象中添加属性

  这个很重要,直接解决了图中的bug。

问题:关于碰撞体的小bug

描述

  如图中所示,当蓝色的滑块位于红色障碍之间时,竟然穿过了障碍。原因其实很简单,先说一下原理。
   当蓝块碰撞红块时,碰撞的方向的Button会对蓝块的speed赋值为0。这样就实现了碰撞的效果。但是当蓝块离开碰撞位置时,应该将speed赋值为正常的值。所以在离开碰撞区域时执行的函数 onCollisionExit(other)中添加恢复speed的函数。
   问题就在这里,bug代码由于我的失误没有记录,大概就是:onCollisionExit(other)函数执行的时,我将四个方向(上下左右)的speed全部恢复了,但其实我只离开了一个方向的触碰区域(如失败图1)。
   所以就是:蓝块同时碰撞了下方和右方的红块,当我离开下方触碰区域的时候,onCollisionExit(other)将右方的speed也恢复了,导致了“穿墙”。

解决

  解决方法也很简单,我忽略了传入的参数other,以及用other.name的方式在other对象中添加一个属性的方式。只要在发生触碰时的障碍中标记触碰的方向,根据标记的方向来对相应的方向恢复speed即可。

计划:

  Day11的目标:

  1. 搭建一个类似迷宫的场景,节点在运动时不会穿墙的反人类动作。
  2. 到达目标点,游戏结束。返回主界面
  3. 点击开始进入游戏。
  4. 节点的动作通过按钮执行。

代码:这里写链接内容


Day13:弹窗

2018.2.18 耗时:5h

毕业设计:移动端的游戏开发_第11张图片
  失败1
毕业设计:移动端的游戏开发_第12张图片
  成功1

  每一天,每一天都是煎熬。
  被各种琐事烦扰,奇怪的梦,莫名的白眼以及来自各处的嘲讽。
  说正事,今天完成的是通过路径点的弹窗,问题是第二次加载界面后,弹窗无法初始化。以及一个简单的错误。

问题1:场景内的Canvas重复

  出现了以下的提示:

Can’t init canvas ‘Canvas’ because it conflicts with the existing
‘UI’,the scene should only have one active canvas at the same time

  大概意思是Canvas重复了,只能有一个。Canvas的API

  摘自官方API文档:

instance Canvas 当前激活的画布组件,场景同一时间只能有一个激活的画布。

  这个问题算是结束了,以后可以随时补充。

问题2:第二次无法正确弹出窗口

  继续上次论坛上写好的弹窗,第二次加载场景后无法在弹出窗口(失败1)。

var Alert = {
    _alert: null,           // prefab
    _detailLabel:   null,   // 内容
    _cancelButton:  null,   // 确定按钮
    _enterButton:   null,   // 取消按钮
    _enterCallBack: null,   // 回调事件
    _animSpeed:     0.3,    // 动画速度
};

/**
 * detailString :   内容 string 类型.
 * enterCallBack:   确定点击事件回调  function 类型.
 * neeCancel:       是否展示取消按钮 bool 类型 default YES.
 * duration:        动画速度 default = 0.3.
*/
Alert.show = function (detailString, enterCallBack, needCancel, animSpeed) {
    console.log("1.alert初始化");
    // 引用
    var self = this;

    // // 判断
     if (Alert._alert != undefined)
    {
        console.log("1.2alert无定义。");
        return;

     }
    // console.log("2.判断");


    // 
    Alert._animSpeed = animSpeed ? animSpeed : Alert._animSpeed;

    // 加载 prefab 创建
    cc.loader.loadRes("Alert", cc.Prefab, function (error, prefab) {
        if (error) {
            cc.error(error);
            return;
        }

        // 实例 
        var alert = cc.instantiate(prefab);

        // Alert 持有
        Alert._alert = alert;

        // 动画 
        var cbFadeOut = cc.callFunc(self.onFadeOutFinish, self);
        var cbFadeIn = cc.callFunc(self.onFadeInFinish, self);
        self.actionFadeIn = cc.sequence(cc.spawn(cc.fadeTo(Alert._animSpeed, 255), cc.scaleTo(Alert._animSpeed, 1.0)), cbFadeIn);
        self.actionFadeOut = cc.sequence(cc.spawn(cc.fadeTo(Alert._animSpeed, 0), cc.scaleTo(Alert._animSpeed, 2.0)), cbFadeOut);

        // 获取子节点
        Alert._detailLabel = cc.find("alertBackground/detailLabel", alert).getComponent(cc.Label);
        Alert._cancelButton = cc.find("alertBackground/cancelButton", alert);
        Alert._enterButton = cc.find("alertBackground/enterButton", alert);

        // 添加点击事件
        Alert._enterButton.on('click', self.onButtonClicked, self);
        Alert._cancelButton.on('click', self.onButtonClicked, self);

        // 父视图
        Alert._alert.parent = cc.find("Canvas");

        // 展现 alert
        self.startFadeIn();

        // 参数
        self.configAlert(detailString, enterCallBack, needCancel, animSpeed);
        console.log("3.实例化");

    });

    // 参数
    self.configAlert = function (detailString, enterCallBack, needCancel, animSpeed) {

        // 回调
        Alert._enterCallBack = enterCallBack;

        // 内容
        Alert._detailLabel.string = detailString;
        // 是否需要取消按钮
        if (needCancel || needCancel == undefined) { // 显示
            Alert._cancelButton.active = true;
        } else {  // 隐藏
            Alert._cancelButton.active = false;
            Alert._enterButton.x = 0;
        }
    };

    // 执行弹进动画
    self.startFadeIn = function () {
        console.log("4.弹进动画");
        cc.eventManager.pauseTarget(Alert._alert, true);
        Alert._alert.position = cc.p(0, 0);
        Alert._alert.setScale(2);
        Alert._alert.opacity = 0;
        Alert._alert.runAction(self.actionFadeIn);
    };

    // 执行弹出动画
    self.startFadeOut = function () {
        console.log("5.˙执行弹出动画");
        cc.eventManager.pauseTarget(Alert._alert, true);
        Alert._alert.runAction(self.actionFadeOut);
    };

    // 弹进动画完成回调
    self.onFadeInFinish = function () {
        console.log("6.弹进动画完成回调");
        cc.eventManager.resumeTarget(Alert._alert, true);
    };

    // 弹出动画完成回调
    self.onFadeOutFinish = function () {
        console.log("7.弹出动画完成回调");
        self.onDestory();
    };

    // 按钮点击事件
    self.onButtonClicked = function(event){
        console.log("8.按钮点击事件");
        if(event.target.name == "enterButton"){
            if(self._enterCallBack){
                self._enterCallBack();
            }
        }
        self.startFadeOut();
    };

    // 销毁 alert (内存管理还没搞懂,暂且这样写吧~v~)
    self.onDestory = function () {
        console.log("9.销毁 alert");
        Alert._alert.destroy();
        Alert._enterCallBack = null;
        Alert._alert = null;
        Alert._detailLabel = null;
        Alert._cancelButton = null;
        Alert._enterButton = null;
        Alert._animSpeed = 0.3;
    };
};

  咨询了一下群里的大神(我又加了新群),他告诉我将:

  if (Alert._alert != undefined)
    {
        console.log("1.2alert无定义。");
        return;

     }

  这段注释掉即可。
  但是只知道怎么做不知道为什么肯定是不够的,这个问题的原因在于 self.onDestory 将 Alert._alert 赋值为了null。而这个判断发现prefab不等于undefined的时候就会return,导致弹窗无法弹出。
  关于这个问题,我还是有些疑惑。以后补充。

知识点:undefined与null

问问

  Day11的目标:

  1. 搭建一个类似迷宫的场景,节点在运动时不会穿墙的反人类动作。
  2. 到达目标点,游戏结束。返回主界面
  3. 点击开始进入游戏。
  4. 节点的动作通过按钮执行。

  很绝望,看不到希望。
  以后的资源全部发网盘,不需要积分下载。


Day14:拖拽控件,以及RichText,还有潜在的问题

2018.2.19 耗时:6h
  今天相对前几天还是很顺利的,马上就要回北京,很舍不得离开家,哪怕我是蹲在沙发上写代码。
  今天实现的是拖拽控件,扔到richbox中变成字符串。实现原理是点击按钮时触发touchmove事件,使节点跟随手指(鼠标)移动,如果移动至左边的区域就变成字符串或在其他区域松手,则调出destroy()删除节点。拖动的过程中,一旦离开原节点位置,便生出一个prefab在原位。这样就实现了入图成功中描述的样子。(图片快进了,有点看不出来,仔细看一下确实是这样的)。
毕业设计:移动端的游戏开发_第13张图片
  失败1
毕业设计:移动端的游戏开发_第14张图片
  成功

问题1:RichText追加字符串时第一行的固定

  其实很简单,将锚点更改为1,1即可。

问题2:Prefab无法加载

if (user.node.x != x && user.node.y != y)
{
        var scene = cc.director.getScene();
        console.log(scene);
        var node = cc.instantiate(user.target);
        node.parent = scene;
        node.setPosition(x, y);
        console.log("成功执行if,node:"+node.x);
}

  如果这样加载,会显示prefab为空。
  改为:

var scene = cc.find("Canvas/Commit");

  就可以
  不知道为什么,留个坑日后研究。

问题3:Prefab修改后无效

  当前场景内的Prefab修改了js后依然执行的是未修改的,是因为没有同步的原因,手动或自动同步一下即可。

问题4:不同尺寸的设备,碰撞体失效的问题

  由于碰撞的模拟是按相对坐标算的,所以有不同尺寸会有问题。
毕业设计:移动端的游戏开发_第15张图片
  但是将这两个勾选就可以。但是奇怪的是,第一次勾选这两个的时候,重新加载场景,会发生布局错位的问题。

关键代码

 onLoad() {
        var user = this;
        var x = user.node.x;
        var y = user.node.y;
        console.log(this.target);
        //拖拽
        user.node.on("touchmove", function (event) {
            console.log("进入拖拽事件");
            user.opacity = 255;
            var delta = event.touch.getDelta();
            user.node.x += delta.x;
            user.node.y += delta.y;
            if (user.node.x != x && user.node.y != y)
            {
               // var scene = cc.director.getScene();
               var scene = cc.find("Canvas/Commit");
                console.log(scene);
                console.log("测试:"+cc.director.getScene());
                var node = cc.instantiate(user.target);
                node.parent = scene;
                node.setPosition(x, y);
                console.log("成功执行if,node:"+node.x);
            }
        });
        //结束拖拽
        user.node.on("touchend", function (event) {
            if (user.node.x != x && user.node.y != y) {
                user.node.destroy();
                console.log("离开拖拽区域");
            }
        });
    },

  Day11的目标:
  已经基本完成,下面几天完成将左侧的文本框中的数据转换为可执行的语句,类似于编译器。

  马上要回北京愈发的烦躁,总有心事。但愿不打扰我完成这个程序。


Day15:想弄个编译器?做梦吧

2018.2.24 耗时:5h

毕业设计:移动端的游戏开发_第16张图片
  今天的成果。
毕业设计:移动端的游戏开发_第17张图片
  今天的成果2。

  现在最大的麻烦就是这个编译器。怎么做是个问题。

问题1:require获取不到cc.class

问题2:同一个函数无法执行两次??

问题3:Prefab生成后位置错了

 node.parent = scene;
 node.setPosition(x, y);

  将这两句调换位置即可,先设置节点位置,然后在寻找scene。因为prefab也有一个默认位置,是根据父坐标来定位的。生成时他会位于0,0点。所以先调节好他的位置,在显示出来。

知识点:require

知识点:组件的初始化顺序

  过几天就要答辩,所以目标是:

  1. 完成类编译器的编写
  2. 动画的制作
  3. 如果可以的话,连接数据库
  4. 装备系统

  因为要中期答辩,所以先只做一个关卡。


Day16:游戏逻辑

2018.2.25 耗时:6h
毕业设计:移动端的游戏开发_第18张图片
  成功1
  今天任务较少,补充动画。没有编写逻辑。并且把Day15的读取用户输入命令区域重写。

问题1:Prefab无法对应修改Label.String

  当生成一个Prefab的时候,无法动态修改string,控制台显示其实已经是修改完毕的。但是界面不显示。
  prefab中的labe内容设置无效的BUG,16年有人提出过这个问题,但是我并不知道有没有修改。
  错误的写法我没有记录,已改为:

     var cannons = cc.Op.TouchNode.getChildByName("Text").getComponent(cc.Label);

  这样可以获得Prefab的值。

问题2:cannons.string = self.node.string?

cannons.string = self.node.string

  此句无效,无法获得Label的值。(Self为label控件的this)
  改为:

 cannons.string = self.node.getComponent(cc.Label).string;

  暂时不知道为什么

知识点:访问其他节点的方式

//待补充

  下面几天完成主要的逻辑编写。


Day17:游戏逻辑 节点动过逻辑语句驱动

2018.3.5 耗时:5h
毕业设计:移动端的游戏开发_第19张图片
  通过标签使节点动起来了。

问题1:cc.class不能通过构造函数传参数

cc.OpPerNode = cc.Class({
    properties: {
        commad: "null",
        untilltag: "null",
    },
    __ctor__: function (untilltag,commad) {
        this.untilltag=untilltag;
        this.commad = commad;
    }
});

  不能通过ctor传参数来实现构造函数,需使用_ ctor _

知识点1:cc.class

//待补充

  抽时间我会回来补充游戏的逻辑,我现在才明白,写代码之前先构思在画er图以及等等的计划有多重要,由于我基本处于看一步走一步的状态,重写了很多代码。目前的代码以及和前几天的完全不一样了,大部分函数基本重写。估计未来几天还会这样,所以我以后的任务将是注重思考如何将程序的耦合度降到最低以及如何贯彻面向对象的思想。

  Day15的目标已完成一个,当前目标是:

  1. 完成类编译器的编写
  2. 动画的制作
  3. 如果可以的话,连接数据库
  4. 装备系统
  5. 补充:修补程序的不足。如:reset按钮的bug,大多数的重置未清空等等。

Day18:游戏逻辑 模拟For语句

2018.3.6 耗时:10h
毕业设计:移动端的游戏开发_第20张图片
  失败1
毕业设计:移动端的游戏开发_第21张图片
  失败2
毕业设计:移动端的游戏开发_第22张图片
  成功

  起初想用递归来实现For的模拟,后来发现无法正确退出当前的函数切递归的空间复杂度较高,程序的负担较大,所以采用了更为简单的办法:

   var timeCallback = function (dt) {
            if (StartCount > EndCount) {
                console.log("进入退出判断");
                console.log("StartCount:" + StartCount + " end:" + EndCount);
                this.unscheduleAllCallbacks();
                return;
            }
            var key = cc.Op.OpObeject[StartCount].commad;
            var UntillTag = cc.Op.OpObeject[StartCount].untilltag;
            console.log("当前执行的命令:" + StartCount + cc.Op.OpObeject[StartCount].commad);
            switch (key) {
                case "MoveUp();": self.ActionMoveY("Up", UntillTag); break;
                case "MoveDown();": self.ActionMoveY("Down", UntillTag); break;
                case "MoveLeft();": self.ActionMoveX("Left", UntillTag); break;
                case "MoveRight();": self.ActionMoveX("Right", UntillTag); break;
                case "#Cycle":
                    if (cc.Op.OpObeject[StartCount].untilltag == cc.user.color[0]) {
                        StartCount = cc.Op.OpObeject[StartCount].end+1;
                        console.log("循环结束");
                        break;
                    }
                    else
                    {
                        StartCount = cc.Op.OpObeject[StartCount].start + 1; 
                        break;
                    }
                case "#End": StartCount = cc.Op.OpObeject[StartCount].end; break;
                default: console.log("Do Noting!");
                    this.unscheduleAllCallbacks();
            }
            if (cc.Op.Opnext && key != "#End") {
                StartCount++;
                console.log("由谁请求:" + key);
                console.log("进入下一语句判断StartCount的值:" + StartCount);
                cc.Op.Opnext = false;
                // OperateString[count] = null;
            }
        }
        this.schedule(timeCallback, 1);

  手动设置一个指针,如果不加限定条件,该回调函数一直在for中的语句无限次执行。

问题1:return的返回

问题2:this.schedule()的停止与递归的关系

知识点1:计时器


Day19:补充逻辑,UI的热身操作

2018.3.7 耗时:11h

  成功
  今天都是一些修修补补,以及ui的问题。

问题1:cocoscreator的 节点层级与画布z轴的关系

问题2:编辑器运行程序加载界面的异常

  非常重要,加载界面时出现了我已删除的场景。也就是该场景已无法找到,确又重新生成。清空缓存后该问题解决。

问题3:不同设备下的碰撞体失误

知识点1:string的拆分操作

//待续

  今天的任务不多,但是很繁琐也很麻烦。大多数都是自己编写的bug。找了很久。

  Day15的目标已完成一个,接下来的目标是:

  1. 完成类编译器的编写
  2. 动画的制作
  3. 如果可以的话,连接数据库
  4. 装备系统
  5. 补充:修补程序,完善功能。

你可能感兴趣的:(日记)