由于这近三次开会以来我的任务主要就是研究JavaScript代码并且学着撰写一些简单的插件代码,所以呈现在博客上的也一直没有更新。特别的一项艰巨而重要的任务就协助宋从智研究战旗插件,截止今天我们仅能够做出中文的demo实现基本功能但一直未能解决移植到我们大的工程里面,有些丧气吧。(多达3000多行,出自一位葡萄牙JS大神MOG)所以我将我这近一个月来研究JS代码的成果集中展示如下:

PS:总结一下这次软工的体会是真的多,尽管似乎许多方面没有完全按照老师的要求来,但我觉得我们软工小分队整个团队分工明确,PM和副PM(好吧,就是刘帅和宋从智两位)都尽职尽责,最后展现的作品alpha版本也能基本实现当初需求分析文档中的基本功能(希望大家喜欢~)除了很多时候时间很紧任务进度有些迟滞,总体来说还是遵循着软件开发的流程,最终基本达到了学习软件工程这门课的目的,这种就像是真正到了一个公司,作为一个团队里的一员为共同的目标努力的感觉真的很好!

 

 

一、2018.6.4的学习JS笔记

2018.6.4本周主要研究了几千行代码的战旗插件,对大部分模块的实现功能有了初步的了解,之后如果相对战旗插件作出修改可以只需在对应模块进行细致地详细修改。另外就是js的基础部分。
tmsrpg.js :

633行显示敌人信息
684行地图设置
1284行 游戏事件实现
1632行对插件指令的处理
1800行对于在战旗运行过程中命令的实现
2092行结果预测文本,需要将代码中的日文改成中文进行汉化。
2434行。只要带有红色的字符串都是与游戏相关的参数、显示的字符串,就是与它相关的内部实现。
2682行开始带【XX】就是srpg命令,战旗关键。 2682-3109

而san_tiletoner.js主要是战旗中那些瓷砖块进行设置。
1.
@plugindesc 插件名称
@author 插件作者
@help 从help之后直接注释块结束,都是插件帮助
2.
定义作者与帮助信息之间:
@param 参数
* @desc 描述
* @default 初始值如:hello world
3.
重写系统js方法!!
4.
插件指令与脚本。
获得注释内容与IIFE(未成功)
游戏数据在官方代码中的rpg_managers.js。
$data开头的是我们在RM编辑器中定义的数据,而$game开头的则表示在游戏运行过程中产生的实时数据。
5.
F8调试很方便!!!

 

var Class = {
create: function() {
return function() {
this.initialize.apply(this , arguments);
}
}
}
// Class使用方法如下
var A = Class.create();
A. prototype={
initialize:function(v){
this .value=v;
}
showValue:function(){
alert(this.value);
}
}
var a = new A(‘helloWord!');
a. showValue();//弹出对话框helloWord!

l initialize是什么?
l apply方法是干什么的?
l arguments变量呢?
l 为什么new A后就会执行initialize方法?

笔记如下:
initialize是个变量,代表一个方法,用途是类的构造函数。其具体功能靠js的面向对象支持,JS中所有function都是一样的,但是用途可能是不同的(用作构造对象或是执行一个过程)。
下面该回到主题了initialize是干什么的?
当使用构造函数来构造对象的时候,让构造出来的这个对象的initialize变量执行apply() 方法,这样在初始化对象的时候会联系到initialize(通过apply,见下面)
那么

代码如下:
A.prototype={
initialize:function(v){
this .value=v;
}
showValue:function(){
alert(this.value);
}
}

是什么意思呢?
Prototype是“原型”的意思。A是一个function(),那么A. prototype,这个对象拥有什么方法,那么function产生的对象就拥有什么方法

call()和 apply()的功能。功能基本一样,function().call(object,{},{}……)或者function().apply (object,[……])的功能就是对象object调用这里的funciton(),不同之处是call参数从第二个开始都是传递给funciton 的,可以依次罗列用“,”隔开。而apply只有两个参数,第二个是一个数组,其中存储了所有传递给function的参数。

this.initialize.apply(this , arguments);
这里的第一个this,是指用new调用构造函数之后生成的对象,也就是前面的a,那么第二个this也当然应该是指同一个对象。那这句话就是this(也就是a)调用initialize方法,参数是arguments对象(参数的数组对象),所以在构造函数执行的时候,对象a就会去执行 initialize方法来初始化,这样就和单词“initialize”的意思对上了。
那么执行initialize方法的参数怎么传递进去的呢?

四、 Arguments对象
这段代码能说明一切了:

代码如下:
function test(){
alert(typeof arguments);
for(var i=0; i<arguments.length; i++){
alert(arguments[i]);
}
}
test("1","2","3");
test("a","b");

执行后alert(typeof arguments);会显示object,说明arguments是对象。然后会依次打出1、2、3。说明arguments就是调用函数的实参数组。

代码如下:
var Class = {
create: function() {
return function() {
this.initialize.apply(this , arguments);
}
}
}

arguments 就是create返回的构造函数的实参数组,那么在
var a = new A(‘helloWord!');
的时候‘helloWord!'就是实参数组(虽然只有一个字符串),传递给方法apply,然后在调用initialize 的时候作为参数传递给初始化函数initialize。
------------------------------------------------------------------------------------------------------------------------------------------
2018.6.11
首先本周我主要进一步学习了js中具体编写插件过程的诸如读取插件参数、插件指令实现和调用等。对于我们达拉崩吧中用到的js源码进行了分析,增加了一部分注释,对源程序的很多地方有了新的理解(更清晰了),如下:
1.在分析MOG_TimeSystem_Hud.js时
①alias就如同别名一样,只要带有这个的就相当于取了一个名字,后面的才是关键,比如:
var _alias_mog_timeSystem_pluginCommand = Game_Interpreter.prototype.pluginCommand
Game_Interpreter.prototype.pluginCommand = function(command, args) { _alias_mog_timeSystem_pluginCommand.call(this,command, args)
实际上就是利用_Game_Interpreter.prototype.pluginCommand在重写时调用原始方法,其中的command 是调用的指令名,之后可以用if()或者switch()判断插件指令。
②系统中提供的许多原始的属性(变量)如initialize、setup、loadImages后面直接跟=function()可理解为调用这些原始方法,有些复杂不好改动。
2.要分析每一个js代码并自己加以修改完善需要先对rpgmaker mv中,大多数全局变量以$开头,$data开头变量代表数据文件的实体。
rpg框架的核心功能文件有rpg_managers.js(负责数据的读写、游戏场景切换、处理战斗等),rpg_objects.js(里面的Game_Interpreter很重要,它主要负责对事件指令的解析与处理),rpg_scenes.js(定义游戏中的所有场景),rpg_sprites.js(定义图块精灵),rpg_windows.js(定义窗口)
这些都可以在js_help每一部分的源码中看到。
3.关于function MNH() {
this.initialize.apply(this, arguments);
};
就想象成用字符串arguments作为参数初始化new的一个对象,apply()和call()功能相同,this即指向new的那个对象。
4.关于一个function如MNH,当使用MNH.prototype.XX
理解如下:Prototype是“原型”的意思,表示function中的一个变量,其实是个对象。这个对象拥有什么方法,那么function产生的对象就拥有什么方法
5.另外关于注释或者一些指令在源代码中的体现就是notes,command以及一些“”特定字符串。
如在MOG_ActionName.js中关于注释的部分(正则表达式就是形式)
BattleManager.setSkillName = function() {
if (!this._subject.currentAction() || !this._subject.currentAction().item()) {return};
var item = this._subject.currentAction().item();
var notes = item.note.split(/[\r\n]+/);
var enableName = true;
notes.forEach(function(note) {
if (note == "Disable Name" ) {enableName = false};
},this);
if (enableName) {$gameTemp._skillNameData = [true,item,true]};
};

 

 

 

二、JS插件汇总以及编写的测试JS代码和最终的以ZC_开头的我注释和修改过的JS代码(第一个文档太大,不好复制粘贴)

截图如下:

其中的testPlugin的知识点为:

1.rpg_scene.js&rpg_window.js区别
scene是用作每个操作的单屏,SceneManager.goto是代表直接跳转到这个屏,不压入栈堆,SceneManager.push是代表将本屏压入栈堆,(栈堆这里大家可以简单理解为保存我们用过的屏的存储地方)
举个栗子,游戏主页面(Scene_Map)中,按esc按钮进入菜单页(Scene_Menu),再选择道具页(Scene_Item),他这一个流程全部都是用的push,压入到栈堆里面的,当我们在道具页(Scene_Item)取消的时候,再调用SceneManager.pop来剔除当前屏,回到栈堆中的上一屏。
2.精灵(Sprite)元素很重要
rpgmaker来说,里面大大小小的东西都可以算作是精灵。
游戏中几乎所有看到的东西动起来,仅仅是精灵单元改变自己的图片而已,由于游戏的fps(帧)刷新得比较快,所以我们看到的就是一个连贯动作的精灵
常常会new Sprite.XX(),把精灵直接理解为一个图片就行
3.ImageManager,里面的每个loadxxxx的方法都直接对应到的是项目文件下img文件里的每个文件夹
4.一般都是复制系统源码调用完(call this)之后进行自己函数的定义。而有些系统函数里的参数需要查官方文档


其他具体还有很多插件的例子,讲的比较清楚只是需要时间进一步研究。附上参考CSDN链接:https://blog.csdn.net/ztsghjls/article/details/77966461

 

 

 

三、最后贴一个这一学期来我们软工小分队群里我那一部分传的文件(应该比较全了),当然具体的工程随后可以整理都发至github作为永久的纪念!

 

posted on 2018-06-20 14:15  Scientific_ZEAL  阅读(272)  评论(0编辑  收藏  举报