设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 75109|回复: 148
打印 上一主题 下一主题

[原创发布] 【请大家移步新教程,20220201】基于RPGMakerMV的JavaScript基础

  [复制链接]

Lv1.梦旅人

梦石
0
星屑
220
在线时间
161 小时
注册时间
2015-11-23
帖子
92
跳转到指定楼层
1
发表于 2016-8-15 16:22:17 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 aasll 于 2022-5-7 15:50 编辑

把我以前写的一个教程再发一遍
如有谬误,尽请指教,不胜感激。
我尽量,慢慢更新吧,毕竟水平也不高。
另外,请大家多回复,争取把帖子一直顶在最前面。。。图书馆不肯收录我

想要小修一下以前的错误,2019/04/08。。。{:2_264:}

几年的功夫下来,RPGMaker的版本更新了好多,甚至都已经更新到MZ了,但是我自己还有由于各种各样的原因,没能正常的继续更新,维护此教程,实在感到愧对各位同仁。
还好我们有一位热心人愿意在我的基础上继续为大家带来新的教程,真是非常感谢,本人完全同意能够由 @RuanZhongNan 来继续接手维护这个系列教程。
新维护的教程链接:

https://hechicollegecomputerassociation.gitee.io/rpgmv-dev-notes/

另外接着新年之际,也希望社区能够越来越好,大家都能够作出自己心仪的游戏,生活顺利,事业有成!
2022/02/01


评分

参与人数 28星屑 +339 +17 收起 理由
石林尘影 + 1
dumpiel + 1 精品文章
yuyering + 1 精品文章
x18489 + 1 精品文章
A.Grothendieck + 1 精品文章
lonelyzhang + 1 我很赞同
emshupisim + 1 塞糖
kano521241 + 1 精品文章
shouhuangzhua + 1 大佬大佬!
mr-ruirui + 1 精品文章

查看全部评分

自天地未辟混沌未开时就已经开始装逼的神奇人物
MV的魔塔模板::托管在github上的游戏,可以直接运行
基于RPGMakerMV的JavaScript基础

Lv1.梦旅人

梦石
0
星屑
220
在线时间
161 小时
注册时间
2015-11-23
帖子
92
2
 楼主| 发表于 2016-8-15 16:33:56 | 只看该作者
第一章        RPG Maker MV以及JavaScript

第一节        RPG Maker MV简介

制作游戏需要专业的游戏引擎,这样可以事半功倍,若要想制作RPG类型的游戏,那么RPG Maker MV是一个不错的选择。


RPG Maker,又名RPG制作大师、RPGツークル、RPG Tsukuru。是一款Enterbrain Incorporation公司出品的RPG游戏制作工具,分为RPG Maker 2000,RPG Maker 2003,RPG Maker XP,RPG Maker VX,RPG Maker VX Ace,RPG Maker MV。


我们现在要介绍的是最新版的RPG Maker MV,这个版本可以实现的功能与前作基本一致,但最大的不同在于使用的语言由Ruby变成了JavaScript,以及由此带来的与html5结合的便利。


现在,我们可以借助html5+JavaScript,将制作的游戏部署到PC端,Android端,IOS端。通俗来讲,凡是可以浏览网页的设备,只要配置足够,都可以运行MV制作的游戏。


第二节        JavaScript简介

JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。


实际上,我们的RPG Maker MV游戏本身就可以看做一个html组成的网站,因此,MV的游戏也需要使用JavaScript来实现其功能。可以说,网页制作使用的JavaScript和MV游戏制作使用的JavaScript没有什么不同。


但是,若要问JavaScript和java有什么关系,请参考雷锋与雷峰塔。记住这一点,不要把两者混用。


它最初由Netscape的Brendan Eich设计。 Netscape在最初将其脚本语言命名为LiveScript,后来Netscape在与Sun合作之后将其改名为JavaScript。JavaScript最初受Java启发而开始设计的,目的之一就是“看上去像Java”,因此语法上有类似之处,一些名称和命名规范也借自Java。但JavaScript的主要设计原则源自Self和Scheme。JavaScript与Java名称上的近似,是当时Netscape为了营销考虑与Sun微系统达成协议的结果。为了取得技术优势,微软推出了JScript来迎战JavaScript的脚本语言。为了互用性,Ecma国际(前身为欧洲计算机制造商协会)创建了ECMA-262标准(ECMAScript)。两者都属于ECMAScript的实现。尽管JavaScript作为给非程序人员的脚本语言,而非作为给程序人员的脚本语言来推广和宣传,但是JavaScript具有非常丰富的特性。


发展初期,JavaScript的标准并未确定,同期有Netscape的JavaScript,微软的JScript和CEnvi的ScriptEase三足鼎立。1997年,在ECMA(欧洲计算机制造商协会)的协调下,由Netscape、Sun、微软、Borland组成的工作组确定统一标准:ECMA-262。


我们使用JavaScript,也应当遵守标准。目前,js的最新标准是es6。


第三节        RPG Maker MV中使用插件

首先打开RPG Maker MV,打开一个工程,进入其根目录后可以看到,工程的结构如图1-1所示。



图1-1

其中,js目录下即是JavaScript所在的地方,打开js,我们可以看到如图1-2,libs是MV的库,系统所用到的一些配置都在其中。plugins是游戏的插件所在地,放在这里面的js文件才能被当做插件加载。
其余的文件都是游戏的系统脚本,游戏程序的实现全靠这几部分。


  • main.js是主文件,游戏的入口。
  • plugins.js是一个表,里面是对插件使用的配置情况。
  • rpg_core.js是游戏的核心,里面有游戏对图形等等的处理方法。
  • rpg_managers.js是游戏对数据的管理。
  • rpg_object.js是游戏中所用到的对象。
  • rpg_scenes.js是游戏中所显示的场景。
  • rpg_sprites.js是游戏中的精灵。
  • rpg_windows.js是游戏中的窗口。



图1-2

libs文件夹下,其内容如图1-3所示。其中,fpsmeter.js用于帧数测试。lz-string.js用于大量数据存储。pixi.js用于HTML5 2D渲染。



图1-3

我们用到最多的就是plugins文件夹,此文件夹下所有的文件都会反映在RPG Maker MV的插件管理器中,如图1-4,1-5所示。



图1-4

图1-5

这里,我们选择一个插件,EnemyBook,此插件的帮助文档显示了作者对使用者的提示,如图1-6。在我们自己写给自己用时,虽然当时不需要提示,但日子久了仍然会忘记一些功能的具体实现,因此,帮助文档是必不可少的。



图1-6

双击parameters参数表中的项目,就可以配置插件的参数,如图1-7。这也是由插件制作者设计好的。可以依据提示自行设置插件允许的功能。



图1-7

设置好之后,别忘了将status状态设置为on开启状态。这样,我们就可以使用该插件了。


现在,我们设置一个老爷爷,通过与他对话来打开EnemyBook怪物图鉴。其事件页面使用Plugin Command,在其中输入我们刚才在帮助文档中看到的命令。此处应该用打开怪物图鉴的命令EnemyBook Open,设置如图1-8。


测试游戏,可以看到,效果如图1-9所示,??????的符号正是我们刚才设置的不知道的怪物的显示名字。


现在,我们进行一次战斗,之后再看看会发生什么,如图1-10。


战斗之后再打开EnemyBook,然后会发现,其中的Bat已经可以查看了,如图1-11。


这就是插件的用法示例,通过学习,我们自己也可以设计并制作自己的插件。如果不想制作插件,学习JavaScript也有助于我们理解和使用插件,因为并不是每个制作者的帮助文档都写的简单明了。



如果我们要自己创建插件,只需要在pulgins文件夹下创建一个新的文本文件,将扩展名改为js,然后就可以调用了。



图1-8

图1-9

图1-10

图1-11
第四节        如何编辑JavaScript

事实上,任何文本编辑器都可以打开并编辑后缀名为.js的JavaScript的脚本文件,但笔者在这里推荐使用专业的编辑器,比如notepad++,以及笔者用的visual studio code,如图1-12所示。
一个好的编辑器可以帮助你完成一些繁琐的任务,使得编程事半功倍。



图1-12
第五节        在事件中使用脚本

事实上,我们在事件中除了可以使用插件定义好的插件命令外,还可以直接在事件中嵌套入JavaScript语句。如图1-13所示,在事件中插入脚本,即JavaScript语句,之后在游戏中可以通过事件来触发,如图1-14。



图1-13

图1-14

评分

参与人数 3星屑 +230 +1 收起 理由
武不凡 + 1 精品文章
长宁居士 + 30 精品文章
鑫晴 + 200 塞糖

查看全部评分

自天地未辟混沌未开时就已经开始装逼的神奇人物
MV的魔塔模板::托管在github上的游戏,可以直接运行
基于RPGMakerMV的JavaScript基础
回复 支持 9 反对 0

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
220
在线时间
161 小时
注册时间
2015-11-23
帖子
92
3
 楼主| 发表于 2016-8-15 17:05:09 | 只看该作者
本帖最后由 aasll 于 2019-4-8 19:36 编辑

第二章        JavaScript基础知识

第一节        基本语法
区分大小写

JavaScript是区分大小写的,也就是说,大写字母和小写字母会被认为是不同的部分,例如变量名rename,Rename以及RENAME是不同的三个变量,虽然它们看起来含义相同。


空白

大多数情况下,JavaScript是忽略空白部分的,所以你可以使用空格键、制表键等来缩进代码,使其变得好看许多。例如图2-1中的两端代码,虽然功能是一样的,但是下面的部分明显比上面的部分简洁、清晰。要是隔两天你再来看,那么你愿意看哪一种呢?


注释

注释必须好好写,注释必须好好写,注释必须好好写。(重要的事情说三遍)注释是帮助你理解的一部分文字,并不在代码中起作用。


c式的/*与*/,或者c++式的//都可以,其中/*和*/可以跨行注释其中的所有内容,//只能注释在它后面的这一行的内容。



图2-1
分号

分号对于JavaScript虽然不是必要的(事实上解释器会自动补全),但是这里推荐你老老实实的每句话后面加分号,否则会出现一些稀奇古怪的事情。


换行

换行用于把两条语句隔开,以增加可读性,一样推荐你老老实实的换行,不要偷懒。另外,不要把一句话拆开两行。


第二节        JavaScript语句

JavaScript有两种语句,简单语句和复合语句。


简单语句就是看着简单的,例如


  1. x=5;
复制代码

复合语句就是看着很复杂的,包含了多个结构的,例如。


  1. if(con==1){
  2.         x=5;
  3. }else{
  4.         x=8;
  5. }
复制代码

事实上这两者没什么本质不同,你也不必要区分的那么仔细,我也不打算详细区别这两个东西。


第三节        JavaScript的保留字

ECMA-262 描述了一组具有特定用途的关键字。这些关键字可用于表示控制语句的开始或结束,或者用于执行特定操作等。按照规则,关键字也是语言保留的,不能用作标识符。以下就是ECMAScript的全部关键字(带*号上标的是第5 版新增的关键字):


  • break       do        instanceof        typeof
  • case        else        new        var
  • catch        finally        return        void
  • continue        for        switch        while
  • debugger*        function        this        with
  • default        if        throw        delete
  • in        try

ECMA-262 还描述了另外一组不能用作标识符的保留字。尽管保留字在这门语言中还没有任何特定的用途。但它们有可能在将来被用作关键字。以下是ECMA-262 第3 版定义的全部保留字:


  • abstract        enum        int        short
  • boolean        export        interface        static
  • byte        extends        long        super
  • char        final        native        synchronized
  • class        float        package        throws
  • const        goto        private        transient
  • debugger        implements        protected        volatile
  • double        import        public
  

第5 版把在非严格模式下运行时的保留字缩减为下列这些:


  • class        enum        extends        super
  • const        export        import
      

在严格模式下,第5 版还对以下保留字施加了限制:


  • implements        package        public        interface
  • private        static        let        protected
  • yield
                  

总之,这些词都不要使用做自己的变量名字就好,否则会跟系统预定义的功能起冲突。


第四节        变量和数据类型
变量是储存信息的容器。

变量需要起一个变量名。变量名须以字母、 $ 或 _ 符号开头,而且对大小写敏感。


建议大家平常都用字母开头,我个人比较讨厌美元和短命鬼。


使用变量前需要声明这个变量,我们使用var来声明一个变量,例如:


  1. var a=5;
  2. var b=10;
  3. var c=a+b;
  4. var pi=3.14;
复制代码

就像这样,我们就声明了一系列的变量,并且给他们赋了相应的值。也可以不赋值来声明一个变量,在后面的使用中再给它赋值,例如:


  1. var m;
  2. m=250;
复制代码
  1. 赋值要使用=,叫做赋值号,注意,这东西不是等号,不表示两个相等,只是把右边的值给左边,或者说把左边的变量设置成和右边一样的。
复制代码


数据类型就是数据的类型。

JavaScript有字符串、数字、布尔、数组、对象、Null、Undefined这样几种基本数据类型。


而且,JavaScript拥有动态的数据类型,这意味着相同的变量可用作不同的类型,例如,前一刻它还是个数字,后面就变成字符串了:


  1. var a;//声明一个变量a
  2. a=5;//给a赋值5,此时a是个数字类型
  3. a="hehe";//给a赋值“hehe”,此时a是个字符串类型
复制代码


字符串

一种比较特殊的(我不喜欢特殊……)类型,用引号包裹着的内容来表示。单引号可以,双引号也可以,例如:


  1. var carname="Bill Gates";
  2. var carname='Bill Gates';
复制代码

也可以用引号包裹引号,这种字符串是里面有引号的字符串,例如:


  1. var answer="Nice to meet you!";
  2. var answer="He is called 'Bill'";
  3. var answer='He is called "Bill"';
复制代码

数字

这就是表示一个数字,没什么好说的,例如:


  1. var x1=34.00;      //使用小数点来写
  2. var x2=34;         //不使用小数点来写
复制代码

还可以用科学计数法,例如:


  1. var y=123e5;      // 12300000
  2. var z=123e-5;     // 0.00123
复制代码

布尔

布尔类型是逻辑运算的,只有两个值:true和false。


数组

数组就是一些变量的顺序组合,JavaScript中这样来创建一个数组:


  1. var cars=new Array();
  2. cars[0]="Audi";
  3. cars[1]="BMW";
  4. cars[2]="Volvo";
复制代码

或者 (condensed array):


  1. var cars=new Array("Audi","BMW","Volvo");
复制代码

或者 (literal array):


  1. var cars=["Audi","BMW","Volvo"];
复制代码

数组的下表是从0开始的,你可以用[]里面加数字的形式来访问数组里面存储的数据。


对象

对象由花括号分隔。在括号内部,对象的属性以名称和值对的形式 (name : value) 来定义。属性由逗号分隔:


  1. var person={firstname:"Bill", lastname:"Gates", id:5566};
复制代码

上面例子中的对象 (person) 有三个属性:firstname、lastname 以及 id。


空格和折行无关紧要。声明可横跨多行:


  1. var person={
  2. firstname : "Bill",
  3. lastname  : "Gates",
  4. id        :  5566
  5. };
复制代码

对象的访问有两种形式,一种是使用.来访问,一种是使用[]来访问,例如:


  1. name=person.lastname;
  2. name=person["lastname"];
复制代码

undefined和null

undefined 这个值表示变量不含有值,可以通过将变量的值设置为 null 来清空变量,例如:


  1. cars=null;
  2. person=null;
复制代码


声明指定类型的变量时,可以使用new来声明,例如:


  1. var carname=new String;
  2. var x=      new Number;
  3. var y=      new Boolean;
  4. var cars=   new Array;
  5. var person= new Object;
复制代码


另外,JavaScript中的所有变量都是对象。


第五节        对象

事实上,JavaScript中所有事物都是对象,对象就是拥有属性和方法的数据。


属性和方法

属性是与对象相关的值,与游戏人物的属性类似。


方法是能够在对象上执行的动作,与游戏人物的技能类似。


举例:汽车就是现实生活中的对象。


汽车的属性:


  1. car.name=Fiat
  2. car.model=500
  3. car.weight=850kg
  4. car.color=white
复制代码

汽车的方法:


  1. car.start()
  2. car.drive()
  3. car.brake()
复制代码

同样,游戏中的人物也有生命值,攻击力等属性,也有攻击,防御,放火球等方法。这样,我们就可以把游戏中的人物当做一个对象来设计。


当你像这样声明一个 JavaScript 变量时:


  1. var txt = "Hello";
复制代码

你实际上已经创建了一个 JavaScript 字符串对象。字符串对象拥有已经按标准定义好的属性 length。对于上面的字符串来说,length 的值是 5。字符串对象同时拥有若干个内建的方法。


属性:


  1. txt.length=5
复制代码

方法:


  1. txt.indexOf()
  2. txt.replace()
  3. txt.search()
复制代码

除了使用JavaScript内建的几种对象外,我们还可以自己定制自己的对象,例如刚才说到的游戏人物,就可以像这样定义:


  1. var person=new Object();
  2. person.name="Xiao Rou"
  3. person.hp=500;
  4. person.atc=10;
  5. person.def=5;
  6. person.attack=function(){//……具体动作}
复制代码

访问对象的属性和方法都要使用.来访问,例如:


  1. person.attack()//执行person的attack方法
  2. var a=person.atc//给a赋值person的atc属性
复制代码

第六节        函数
函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。

在JavaScript中,函数用function来表示,是一种可以被调用的代码块,当你调用一个函数的时候,就会执行其中的代码。我们一般把会多次使用的语句组合在一起,形成一个函数,方便重复使用。


以下例子都可以采取事件中插入脚本的方法进行实际测试,定义好函数之后,一定要进行调用(请参看alert函数是怎么调用的)。


函数的定义如下所示:


  1. function hello(){
  2.         alert("Hello Xiao Rou!");
  3. }
复制代码

由function打头,后面跟着给这个函数起的名字,之后是小括号,大括号里面是函数的内容,可以是任意的语句。例子中的alert也是一个函数,这个函数是js自带好的(准确的说是由浏览器标准BOM规定的,RPG Maker MV也支持),跟那些数据类型相似,我们可以直接使用它,用途就是弹出一个对话框,对话框里面显示的是小括号里面的内容,在这里是一个字符串"Hello Xiao Rou!"。


函数还可以向里面传入参数,函数里面可以调用传入的参数,像alert函数,它所要传入的参数就是一个字符串。我们可以像这样定义一个带参数的函数:


  1. function square( x ){
  2.         var r=x*x;
  3.         alert(x+"’s square is"+r);
  4. }
复制代码

这个例子是一个square函数,它有一个参数x,功能就是求x的平方,并且用alert显示出来。参数可以有多个,它们之间用逗号隔开。


函数还可以有返回值,所谓返回值,可以看做函数运行结束后就变成了一个值,用法如下:


  1. function power( x , n ){
  2.         var r=1;
  3.         for(var i=1;i<=n;i++){
  4.                 r=r*x;
  5.         }
  6.         return r;
  7. }
复制代码

函数用return来传出返回值,同时return也是函数的终点,函数内部的语句执行的return的时候就会退出来。这个例子中传入了两个参数x和n,在函数内完成了幂运算,计算出来x的n次幂并储存在了r中,最后返回了r的值。


没有返回值的时候,return也可以单独使用,只起到使函数结束的作用。


另外要注意,函数内部定义的变量在别的地方是不能使用的,这种变量叫做局部变量。同样还有全局变量,是在函数外面定义的,在函数里面也可以使用。


事实上,函数是Function类型的对象。


第七节        运算符
JavaScript 算术运算符

算术运算符用于执行变量与/或值之间的算术运算。


给定 y=5,下面的表格解释了这些算术运算符:


  • 运算符        描述        例子        结果
  • +        加        x=y+2        x=7
  • -        减        x=y-2        x=3
  • *        乘        x=y*2        x=10
  • /        除        x=y/2        x=2.5
  • %        求余数 (保留整数)        x=y%2        x=1
  • ++        累加        x=++y        x=6
  • --        递减        x=--y        x=4

JavaScript 赋值运算符

赋值运算符用于给 JavaScript 变量赋值。


给定 x=10 和 y=5,下面的表格解释了赋值运算符:


  • 运算符        例子        等价于        结果
  • =        x=y                 x=5
  • +=        x+=y        x=x+y        x=15
  • -=        x-=y        x=x-y        x=5
  • *=        x*=y        x=x*y        x=50
  • /=        x/=y        x=x/y        x=2
  • %=        x%=y        x=x%y        x=0

特别的(我讨厌特别的),+可以连接两个字符串,而且,如果把数字和字符串相加会发生什么呢?可以试试(前面的例子中好像用到了)。


比较运算符

比较运算符在逻辑语句中使用,以测定变量或值是否相等,它们的返回值是一个布尔型的数据。


给定 x=5,下面的表格解释了比较运算符:


  • 运算符        描述        例子
  • ==        等于        x==8 为 false
  • ===        全等(值和类型)        x===5 为 true;x==="5" 为 false
  • !=        不等于        x!=8 为 true
  • >        大于        x>8 为 false
  • <        小于        x<8 为 true
  • >=        大于或等于        x>=8 为 false
  • <=        小于或等于        x<=8 为 true

逻辑运算符

逻辑运算符用于测定变量或值之间的逻辑,它们的返回值是一个布尔型的数据。


给定 x=6 以及 y=3,下表解释了逻辑运算符:


  • 运算符        描述        例子
  • &&        and        (x < 10 && y > 1) 为 true
  • ||        or        (x==5 || y==5) 为 false
  • !        not        !(x==y) 为 true

总之,这两种都是用来进行逻辑判断的。


最后,还有一种~特~殊~的~运算符,? : 。


  1. variablename=(condition)?value1:value2
复制代码

这个格式很,,,总之我不经常使用,因为它的功能完全可以用if else来代替,例如:



  1. greeting=(visitor=="PRES")?"Dear President ":"Dear ";
复制代码

如果变量 visitor 中的值是 "PRES",则向变量 greeting 赋值 "Dear President ",否则赋值 "Dear"。

不过这东西形式短小精悍,特别适合用在填空的地方,(比如游戏的伤害公式里面,有人这么用过)。


第八节        判断语句
if...else...语句

上一节的最后的例子,实际上可以写成if else形式的,如下所示:


  1. if(visitor=="PRES"){
  2.         greeting="Dear President ";
  3. }else{
  4.         greeting="Dear ";
  5. }
复制代码

如果if后面的小括号里面的条件满足的话(实际上是条件结果是true的话)就执行后面的大括号里面的部分,否则就执行后面的else大括号里面的部分。


如果我们不需要考虑否则的结果,那么可以只写if部分,例如:


  1. if(visitor=="PRES"){
  2.         greeting="Dear President ";
  3. }
复制代码

或者,我们还想再加一种条件,我们就可以在中间在添加else if部分,例如:


  1. if(visitor=="PRES"){
  2.         greeting="Dear President ";
  3. }else if(visitor=="CHAI"){
  4.         greeting="Dear Chairman ";
  5. }else{
  6.         greeting="Dear ";
  7. }
复制代码

else if后面也可以不加else,直接结束。


如果,我们还想再加一种条件,我们还可以在中间添加else if部分,例如:


  1. if(visitor=="PRES"){
  2.         greeting="Dear President ";
  3. }else if(visitor=="CHAI"){
  4.         greeting="Dear Chairman ";
  5. }else if(visitor=="MANA"){
  6.         greeting="Dear Manager ";
  7. }else{
  8.         greeting="Dear ";
  9. }
复制代码

如果我们还想再添加条件,就可以再继续添加else if部分。


switch语句

不断的添加else if虽然也可以解决问题,但是还是显得太繁琐。而且,我们的这些条件都是对同一个变量的值进行判断,那么我们就可以使用switch语句了,上面的例子可以这样写:


  1. switch(visitor)
  2. {
  3. case "PRES":
  4.   greeting="Dear President ";
  5.   break;
  6. case "CHAI":
  7.   greeting="Dear Chairman ";
  8.   break;
  9. case "MANA":
  10.   greeting="Dear Manager ";
  11.   break;
  12. default:
  13.   greeting="Dear ";
  14. }
复制代码

switch会将变量与每个case后面的值进行比较,如果相同就执行这个case后面的语句,其中的break的作用是阻止自动的执行下一个case,可以去掉,但是建议不要乱去掉。最后的default也像是最后的else,如果前面的case都不成立,就执行这部分的语句,我们可以删去default,这样前面都不成立的时候会直接退出switch,执行后面的语句。


同样case可以有很多个。


第九节        循环

循环,可以帮你重复相同的工作。


for循环

JavaScript里面最常用的一种循环就是for循环,如果我们要依次输出一个数组里面的值,那么我们当然可以依次使用alert语句,如下所示:


  1. var ary=[5,6,7,8,9];
  2. alert(ary[0]);
  3. alert(ary[1]);
  4. alert(ary[2]);
  5. alert(ary[3]);
  6. alert(ary[4]);
复制代码

这样就可以完成目标了,但是,如果这个数组里面有100个对象,这样几乎就是不可能完成的(我是不会干这种傻事的,但是录入数据的人,,,可能经常干这种事,请不要对人家说这句话,更不要说是我说的)。


对于这种情况,我们用for语句来完成,如下:


  1. for(var i=0 ; i<5 ; i++){
  2.         alert(ary[i]);
  3. }
复制代码

我们可以看到,for里面有三个语句,用分号隔开。第一句是在循环开始前执行的。中间一句是在每次循环前判断是否满足条件的,如果满足这个条件,就进行此次循环,否则退出。最后一句是在每次循环结束后进行的语句。


也就是说,可以这样来写:


  1. var i=0;
  2. for( ; i<5 ; ){
  3.         alert(ary[i]);
  4.         i++;
  5. }
复制代码

此处注意这么一点,大括号内声明的变量都算是局部变量,外面是不可以直接使用的,而且像上一个例子,for后面的小括号里面声明的var i=0也是局部变量,外面不能用。而这个例子的i是在外面声明的,所以可以用。这种情况叫做变量的作用域,变量只在声明的作用域内有效。


还有,什么也没有的语句是空语句,也算是一个语句;;;;;;;;;;


中间的i<5,这个语句其实也可以省略掉的,那么就会变成这样的情况:


  1. var i=0;
  2. for( ; ; ){
  3.         if(i<5){
  4.                 alert(ary[i]);
  5.                 i++;
  6.                 continue;
  7. }else{
  8.         break;
  9. }
  10. }
复制代码

遇到break语句会直接跳出循环,遇到continue语句会直接开始下一次循环。嗯,这样的话,for就成了一个单纯的循环节。尽量不要这么自找麻烦的使用for循环……


这种依次访问一个数组的每个数据的行为,我们叫做遍历,还可以使用这样的语句:


  1. for(var i in ary){
  2.         alert(ary[i]);
  3. }
复制代码

注意,这东西虽然看着简单,但是实在不太靠谱,尽量不要用。


while循环

while 循环会在括号内条件为真时循环执行里面的代码,用法如下:


  1. var i=0;
  2. while (i<5){
  3.   alert(ary[i]);
  4.   i++;
  5. }
复制代码

一样可以达到上面的效果。


另外,还可以先循环一次,再判断条件,这就是do while循环,和while循环一样,也是括号内条件成立的话就执行循环里面的代码,用法如下:


  1. var i=0;
  2. do{
  3.   alert(ary[i]);
  4.   i++;
  5. } while (i<5);
复制代码

注意,这里的while结束后要加分号。


break语句和continue语句一样可以使用在这两种循环里面。


第十节        错误

当 JavaScript 引擎执行 JavaScript 代码时,会发生各种错误:可能是语法错误,通常是程序员造成的编码错误或错别字。也可能是拼写错误或语言中缺少的功能(可能由于浏览器差异)。还可能是由于来自服务器或用户的错误输出而导致的错误。


当然,也可能是由于许多其他不可预知的因素。


总之,错误是不可避免的,我们需要考虑一种能够抛出错误的手段,就像电脑坏了会显示蓝屏的错误信息,计算器除以零的时候会报错一样。


我们用throw抛出错误信息,看下面的这个例子:


  1. function divide(arg1 , arg2){
  2.         if(arg2==0){
  3.                 throw "divided by zero is not allowed";
  4. }else{
  5.         return arg1/arg2;
  6. }
  7. }
复制代码

throw会抛出错误信息,并且立即退出函数。


我们知道了错误信息,还需要把它显示出来。我们使用try catch语句来处理捕捉到的错误,如下:


  1. var r;
  2. try{
  3.         r=divide(50,0);
  4. }catch(err){
  5.         alert(err);
  6. }
  7. if(r!=null) alert(r);
复制代码

这里使用try catch捕捉到了错误信息,并且放在了err里面,然后由alert输出了错误信息。



另外,try catch的使用,永远应该放在你的控制范围之内,而不应该防范未知的错误。也就是说你很清楚知道这里是有可能出错的,而且你很清楚知道什么前提下会出错,你就是要故意利用报错信息来区分错误,后续的程序会解决所有的出错,让程序继续执行。


简而言之,这个东西是用来区分错误的类型并且处理它的,其他情况下,有些不是很需要用这个语句。





自天地未辟混沌未开时就已经开始装逼的神奇人物
MV的魔塔模板::托管在github上的游戏,可以直接运行
基于RPGMakerMV的JavaScript基础
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
220
在线时间
161 小时
注册时间
2015-11-23
帖子
92
4
 楼主| 发表于 2016-8-15 20:57:39 | 只看该作者
第三章        插件及插件参数和命令

第一节        先做一道练习题

好了,现在我们就要正式开始了,首先先测试一下自己的水平,也可以帮着回忆一下学到的知识。请听题:


咪咪是一只聪明的小老鼠(什么什么?谁规定老鼠就不能叫咪咪了?真是!),她正在四处找水喝呢……她发现了一些水罐,里面都有水。她趴在每个水罐口上都试了一遍,结果仍然一口水没喝到——这些水罐里的水都很少,水面距离罐口太远,她用嘴够不着。这可怎么办呢?



如果是你,你是不是会想把水罐打翻?只可惜,咪咪只是一只小老鼠,没那么大力气呢。不过,这也难不倒她,聪明的咪咪自然有办法:她转过身来,把尾巴放进去浸湿,再喝尾巴上的水就好了,够聪明吧?


我们已知每个水罐里水面到水罐口的距离,还知道咪咪的尾巴最多可以伸进水罐口t 厘米。



根据这些条件,请你判断一下:有多少个水罐中的水可以被咪咪喝到?


要求:写一个函数,参数有两个值,一个是咪咪的尾巴长度t,一个是储存有水罐高度信息的数组,函数的返回值是可以被咪咪喝到的水罐的数量。


在事件的中插入脚本,并输入如下代码。


  1. function ifDrink(t,pitcher){
  2. //input your code
  3. };
  4. var t=10;
  5. var pitcher=[8,7,13,5,12];
  6. alert(ifDrink(t,pitcher));
复制代码

如果感觉脚本的编辑框太小,放不下的话,可以写好后去掉一些换行,或者直接把ifDrink函数放到一个插件里面,然后在事件中的插入脚本输入剩余部分。


另外,一些格式上的问题,或者语法上的问题,(数组的长度该如何获取呢?)这些都可以百度搜索到的。


百度是个好工具。百度是个好工具。百度是个好工具。



好了,这个题目自己就可以多用几个算例自己测试一下,下面我给出我的代码,放在图3-1里面,别想ctrl+c,ctrl+v,自己照着一个个的敲一遍,也是很有成就感的。


另外,写在js文件里面然后开启插件的方式也可以,这样你可以试试把后面几句也直接放在js里面有什么不同,如图3-2。


注意,插件里面的代码是会在游戏开始的时候就开始执行的,这点需要特别注意,这个特性如果把握不好就很酸爽了。



图3-1

图3-2
第二节        开始黑魔法-随机购买装备

如果前面的例子完成了,那就来看我的黑魔法吧。这次我们来做一个随机购买装备的插件。


就像这样,使用1000元钱,然后随机从设置好的装备列表获得一件装备,主要看运气,有可能获得一件小木剑,也有可能获得屠龙刀。


首先,我们得先搞清楚这几点,这样才能完成我们的工作。


所有装备的列表在哪里呢?

所有装备的列表,是在data文件夹下面以json的形式记录着,在游戏进行的时候,会依照着json文件中的数据创建一个一样的对象,各个对象的对应关系可以从rpg_manager.js中看到,如图3-3。我们可以调用$dataWeapons来获得武器的信息。



图3-3
怎么获得装备呢?

通过在各个核心js文件中搜索gain item、 change item等关键词,我们找到了获得物品的函数是放在rpg_objects.js中的Game_Party.prototype.gainItem函数。这样的话,我们也可以调用这个函数来获取装备,如图3-4。



图3-4
怎么获得并且控制当前的金钱数量呢?

一样的对gold,money等进行搜索,我们找到了控制金钱数量的方法,Game_Party.prototype.gold等等,如图3-5。



图3-5
随机数怎么得到?

这里,我们介绍几个js自带的函数。


  • Math.random(); 结果为0-1间的一个随机数(包括0,不包括1)
  • Math.floor(num); 参数num为一个数值,函数结果为num的整数部分。
  • Math.round(num); 参数num为一个数值,函数结果为num四舍五入后的整数。

利用这三个函数,我们就可以获得我们想要的随机数。



这样对思路的初步考虑,我们发现了一些问题,然后找到了解决的办法,这样我们就可以开始编程了,代码如图3-6,3-7,看备注。



图3-6

图3-7

这样,我们的基本功能就完成了。


看看效果,如图3-8,这样简单的使用刚才的方法调用就好了。第一次使用后,来了一把弓,如图3-9。第二次使用后,又来了一把弓,如图3-10。第三次使用后,来了一把斧子,如图3-11。


试了试,感觉效果还不错,那么我们自己就可以简单的进行使用了。



图3-8

图3-9

图3-10

图3-11
第三节        插件参数和命令

现在,我们要让别人也能方便的使用这个插件,肯定要做一些说明,但是,单看注释对某些完全不懂js的人还是太费劲,mv特有的插件参数和命令可以让他们也能比较省力的学习使用插件。


我们也要把我们的这个随机买武器插件扩展出参数和命令功能来,该怎么办呢?


还是要对照着人家的代码来分析,再次翻出EnemyBook.js找找看有没有什么参数,命令相关的部分,如图3-12。



图3-12

好,在打头的注释里面,我们看到了help,这里面的内容和插件管理器的帮助显示的一样,上面还有个param,这和插件管理器的参数也是一样。我们可以猜测,这就是我们需要的部分。
事实上,插件管理器可以解析js的脚本中有特定的格式的部分,把它们当做一些有特定含义的内容表示出来,但是这些东西在js里面确实是不起作用的。



好了,我们也复制一份到我们的RandomWeapon.js里面。再改改,如图3-13。



图3-13

像这样,我们也有了一个参数,但是,js是不能识别注释里面的内容的,该怎么让它起作用呢?我们继续看EnemyBook.js。好,我们发现了Unknown Data,这个param后面的词,现在在这两句话里面出现了,那么,我们也一样抄下来就好了,如图3-14。



图3-14

事实上,这里面出现的PluginManager.parameters里面包含了对js插件文件中的参数解析结果,我们可以通过它来得到在插件管理器中输入的参数,另外,这些设置好的数组,都是储存在plugins.js里面的,可以打开看看哦。


现在,参数的问题解决了,那么命令该怎么办呢?


我们继续找找在EnemyBook.js里面关于命令的部分,找到了这么两个部分,如图3-15。



图3-15

先把Game_Interpreter.prototype.pluginCommand放进了一个断头鬼里面,然后又给Game_Interpreter.prototype.pluginCommand赋值一个函数,最后在新的函数里面又调用了断头鬼的call方法。


先解释一下call方法,将a对象的方法加在b对象执行。简单来讲,这个过程就是一个扩展原来的Game_Interpreter.prototype.pluginCommand函数的功能的过程。


断头鬼相当于一个两个变量交换值的时候的临时变量,里面储存了没有被重新赋值过的原来的Game_Interpreter.prototype.pluginCommand函数的内容,然后重新定义Game_Interpreter.prototype.pluginCommand的时候调用临时变量的call方法,就可以让新的函数里面继承了原来久的函数的内容。总之,我们照着写就可以了,完成后,如图3-16。


这时候,我们调用的话,就可以用插件命令来调用了,如图3-17。

图3-16

图3-17





点评

最后一张图 "Plugin Command : RandomWeapon get" 中的 "RandomWeapon" 是插件(RandomWeapon.js)的名字还是命名空间(RandomWeapon)的名字?  发表于 2019-9-21 13:28
Math.ceil向上取整得到的索引从1开始,会导致拿不到第一把武器  发表于 2019-3-15 02:20

评分

参与人数 3星屑 +50 收起 理由
冲啊小笼包 + 30 精品文章
c123r123 + 10
chenyilindzh + 10 塞糖

查看全部评分

自天地未辟混沌未开时就已经开始装逼的神奇人物
MV的魔塔模板::托管在github上的游戏,可以直接运行
基于RPGMakerMV的JavaScript基础
回复 支持 13 反对 0

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
29 小时
注册时间
2016-8-11
帖子
8
5
发表于 2016-8-17 10:28:37 | 只看该作者
虽然我也是程序员。。但像你这样讲出来~~挺不容易的,加油楼主!
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
139 小时
注册时间
2014-6-12
帖子
128
6
发表于 2016-8-17 11:28:01 | 只看该作者
牛掰 可以集结出书了,打包成pdf都够了
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
220
在线时间
161 小时
注册时间
2015-11-23
帖子
92
7
 楼主| 发表于 2016-8-17 20:16:02 | 只看该作者
ab1113784831 发表于 2016-8-17 10:28
虽然我也是程序员。。但像你这样讲出来~~挺不容易的,加油楼主!

我这差远了,里面还有很多错误和含糊的地方,比不上专业的
自天地未辟混沌未开时就已经开始装逼的神奇人物
MV的魔塔模板::托管在github上的游戏,可以直接运行
基于RPGMakerMV的JavaScript基础
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1232
在线时间
1017 小时
注册时间
2011-4-30
帖子
1516
8
发表于 2016-8-18 06:56:10 手机端发表。 | 只看该作者
支持楼主,很好的教程
回复 支持 1 反对 0

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
245
在线时间
219 小时
注册时间
2015-9-24
帖子
166
9
发表于 2016-8-18 17:14:39 | 只看该作者
兹瓷!
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
220
在线时间
161 小时
注册时间
2015-11-23
帖子
92
10
 楼主| 发表于 2016-8-18 22:39:03 | 只看该作者
第四章        绘制窗口简介

第一节        变量进度条

感谢我们的好友墨汁的提议,我们现在考虑一个能够把变量以进度条的形式显示出来的插件。最终效果如图4-1所示。



图4-1

先来做一下简单的分析(软件工程还是很有用的):我们可以画一个新窗口,然后在新窗口里面显示文字,画一个黑色的矩形(当作变量条),然后窗口的每次更新都重新读取对应变量的值,然后重画一次。


确定了需求之后,我们就可以开始了。


第二节        创建新窗口

窗口,实际上来自于MV的一个对象Window_Base,从官方的文档中我们可以看到关于它的说明,直接查看源码也可以获得相关的知识(在rpg_window.js内)。我们要画一个新窗口,也需要继承Window_Base。



好了,首先,我们还是要来一个命名空间装个逼,如图4-2。



图4-2

然后,我们就可以创建一个新的窗口了,一般而言,我们这样创建一个窗口。(我也是跟着别人的样式学着写的,大家也可以先跟着写,不明的地方今后慢慢理解)



图4-3

前面两个如同上次的插件命令一样,我们仍然用的是call,将我们自己的窗口Window_Bar通过addChild方法加入到child里面,然后我们的窗口也可以随着游戏的其他窗口一起绘制出来了,这次是Scene_Map里面的createAllWindows函数。


后面是我们的Window_Bar窗口的定义,是一个function对象。这里面只有一句代码:


  1. this.initialize.apply(this, arguments);
复制代码

这个方法是当做构造函数的,即,我们可以把initialize当做构造函数。



图4-4

之后的代码如图4-4,Window_Bar.prototype是创建了一个Window_Base.prototype,这就相当于Window_Bar继承了Window_Base的prototype,原来Window_Base拥有的属性,现在Window_Bar也有了。


然后指明构造器constructor是上面的Window_Bar,这样我们就可以在此原型链上查找属性了。(此句可以看成Window_Base.prototype的属性也是Window_Bar的属性。关于原型链,就像是通过prototype来实现的属性和方法的继承,可以自行百度更多的信息。)


最后,是Window_Bar的初始化,initialize方法,这个方法在上面就用到了,此处正是他的具体内容。


简单来讲,在创建Window_Bar的时候,会先复制Window_Base里面的属性和方法,然后执行initialize方法,这样的话,我们就需要在initialize里面指明我们需要在初始化的时候额外进行的工作,比如说指定窗口的大小、位置等基本属性。


可以看到,我们仍然使用的call,将Window_Base的initialize方法先执行了一遍,Window_Base的initialize方法有四个参数,分别是x,y,width,height,指明了窗口的位置和大小。


然后,我们又设置了Window_Bar的透明度。


注意,这里的this意思就是这个对象,具体来讲,就是Window_Bar.prototype,所以我们可以使用this来调用Window_Bar.prototype里面的东西。


我们把要设置的这几个属性来封在函数里面(也假装个属性来),如图4-5,这样我们就可以像刚才那样来调用,并且在这几个函数里面读取了插件的参数。(就像上一章的设置方法)。



图4-5
第三节        绘制文字以及矩形

以上这些都是一些基础的设置,接下来是我们的核心代码,如何在窗口里面画出文字,还有矩形条,如图4-6。



图4-6

大致就像这样,通过传进来的id参数以及调用系统的变量(就是事件里面用到的那个变量)$gameVariables来获得变量的值,以及我们设置好的变量的上限。计算好比例,设置好宽度和长度。然后开始画矩形和矩形,(一条是背景,一条是已经有的部分),以及在上面写字。


这里要注意,窗口里面的图形都在contents里面储存着,要画图,也要调用contents里面的方法。比如我们所用到的fillRect,gradientFillRect以及drawText。


他们的参数大都相同,都需要由位置和大小。然后还要设置好颜色,用RGB的字符串就可以,drawtext还要有显示的位置(左对齐,右对齐,居中)以及显示的内容,都是字符串。


然后,我们还需要设置好窗口每次刷新时所进行的操作,即重写update方法,如图4-7所示。



图4-7

update方法,是在Window_Base里面设置好的每次刷新时调用的方法,我们把刚才写的show函数放在这里面调用,这样就可以每次刷新时都重新画一遍,以保证数据的更新。


这里用到了cotents里面的clear方法,用于清空窗口里面以前画上的内容,很显然,我们每次刷新都要重新再画,所以需要清空原来的东西。


然后是对储存了要显示的变量的id的数组的遍历,并且将他们的信息作为函数传到show里面。这样可以对id数组里面的所设置的所有变量进行绘制。


第四节        插件命令以及参数

以上部分用到了我已经设置好的插件命令和参数,他们如图4-8所示。



图4-8

id是用来储存需要显示的变量id的数组。


top是变量的上限,用参数的形式获得数值。


后面的命令有reset,add以及delete,都是通过对id数组以及参数数组args的遍历更改id数组的内容,从而改变显示的变量。


注意,此处对args的遍历使得这些命令支持许多个参数。


第五节        留个作业

好吧,我们再来留个测试,


请把top也改成个数组,与id数组一一对应,这样我们就可以对每个变量设置其上限了。



好吧,不要吐槽我混乱的代码风格了,毕竟只是v0.0.1。。。(低版本号是一切bug以及丑陋代码的借口,参考cf的版本号变革)





自天地未辟混沌未开时就已经开始装逼的神奇人物
MV的魔塔模板::托管在github上的游戏,可以直接运行
基于RPGMakerMV的JavaScript基础
回复 支持 2 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-21 18:24

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表