本帖最后由 Hueihuea 于 2021-2-15 19:49 编辑




因为本人后期偏爱使用Upload.cc图床 但是目前该图床屏蔽大 陆IP(疑似遭到攻 击?)
所以 在图片加载不出来时 可以尝试使用非大 陆梯 子
到底是什么玩意要审核 cao

本文于2020.3.18停止更新 总的来说 内容还是很充足且完整的
没什么可以留给大家 留下一点脚本的例子吧
全部都是1.7.10的
NPC脚本.zip (82.7 KB, 下载次数: 1104)
1.12.2的我没写多少
想要例子可以看看这些
点我

然后
你可以加入1022010897脚本交流QQ群
欢迎加入noppes粉丝群(雾)
有中文频道哦 https://discord.gg/Urkn986






1.安装nashorn与配置notepad




:nashorn是什么?

:nashorn是一个基于JVM的轻量高效的JS环境


:那nashorn能做什么?我们为什么要安装它?


:nashorn帮助我们快速的在CNPC构建一个JS脚本开发环境,

你可以把他当成一种语言自己安装在CNPC 而CNPC只有安装了语言才能编译运行我们所写脚本

(我这里对 nashorn 的定义与解释可能不是很准确 因为我也是一个萌新程序员)

(我叫JS大家可能更容易理解 但 nashorn 支持的是ECMA 5.1)

(只要实现了Java的脚本引擎都可以用,Luaj,Jython,JPHP,Scala 等等 但是我用的是js 语法可能有些不同 API一样)

注:nashorn是一个脚本引擎 可以理解为一个编译器 推荐使用nashorn 因为有个Java.type功能能导入java的类XD

:那nashorn在哪 我们要怎么安装它?

:嘿嘿嘿 别那么急 你听我慢慢给你说


其实安装了jre的同学很容易找到nashorn
(jre也就是大家平时下载的java 即java的运行环境)
但我这里以jdk为例
(jdk也就是开发者下载的java 即java的开发工具包)

jre路径:jre X.X.X_XXX\lib\ext\里的nashorn.jar
jdk路径:jdk X.X.X_XXX\jre\lib\ext\里的nashorn.jar
nashorn.jar和MOD一样放入mods即可

我改变主意了XHD萌,别用憨憨notepad++了 来用快乐的VScode吧!

安装了nashorn 然后我们要配置notepad++了
我们先要安装一个notepad++
(如果你不使用notepad++ 而是使用其他文本编辑器或IDE的话 那么你可以跳过本章后面的内容 看下去章了)

你可以百度notepad 来下载一个notepad++

而我要讲的是如何安装我配置好的语言文件
(notepad自带JavaScript的语言文件 对JS的关键字收入比较全面 但是没有关键字变大 可以自己选)

语言配置文件下载地址:https://pan.baidu.com/s/1md_dymYzKAYzyuDm-2OLxQ

打开notepad++ 菜单栏>语言(L)>自定义语言格式


弹出窗口 导入>选择语言文件>打开


重启notepad 菜单栏>语言>选择minecraft-CNPC-1.7.10




2.钩子与"hello world"

:钩子又是什么东西?

:钩子就是监听事件的存在 当钩子被触发时 钩子就会运行该钩子中的代码
不同的钩子监听不同的事件 每个钩子的代码互不影响

:我们先不急着认识钩子 先来看看如何让脚本运行

启动脚本:

确保黄框不是空的
确保红框不是"关"
就可以启动脚本
(如果红框是关 脚本就不会运行)

(这个黄色我用背景色中和了 不违规吧……)
色框 描述
黄框: 所使用的语言
红框: 钩子监听是否开启
橙框: 复制报错与清空报错
绿框: 过滤报错 选择某个钩子便只显示那个钩子的报错
篮框:      显示报错的地方

钩子:


黄框:
选项 描述
脚本: 脚本的编写界面
设置 : 脚本的设置界面 且 显示、复制 报错
网站 : 访问 CNPC的API网站

篮框:
选项 描述
清除 : 清空本钩子所有脚本
粘贴: 用剪贴板内容替换该钩子内容 可以粘贴§(Ctrl+V不能粘贴§)
复制 : 复制该钩子所有脚本的剪贴板
编辑 : CNPC自带的文本编辑器 但是使用后游戏会未响应
加载脚本 : 导入一个脚本文件(这个我也没用过)

至于 红框 和 篮框? 听我慢慢道来
篮框是写入脚本地方
如:


红框就是钩子了

钩子 描述
运行: 当NPC被加载或重生时触发
更新: 每10tick(半秒)触发一次
对话: 互动(右键)触发
对话: 打开对话框触发
伤害: 受到伤害触发
杀死: 被杀死触发
攻击: 攻击别人时触发
目标: 发现攻击目标时触发
冲突: 与其他实体发生碰撞时触发
死亡: 杀死其他人时触发
关闭对话框: 关闭对话框时触发

"hello world":
我给大家一个脚本
  1. npc.say("hello world")
复制代码
这个脚本被触发后 NPC会说出hello world
我们把它放在对话(互动)钩子里


然后我们与NPC进行互动看看效果(也就是右键NPC)


---------本章到此结束---------



3.认识变量、运算符与注释
看来今天不能更新多少了qwq



变量是什么?

:有个很常用也很形象的比喻 变量像一个盒子 而盒子里面的东西 就是变量的值
这和代数有点相似 如: X=1 而在编程语言中 我们把其中的“1”称为值 “X”称为变量名 “=”称为赋值符号

:语言的表达可能有点抽象 我举几个例子 写几个代码 你就懂了

声明变量:
  1. var 变量名;
复制代码
如上 我们要创建 使用一个变量 就需要声明
而声明的格式就是上面的 var 变量名;
(注:虽然CNPC对编写是否规范并没有太大的要求 但是因为这是教程 我会以规范的形式写代码)

而我们看看两行代码
  1. npc.say("hello world");
复制代码
  1. var str="hello world";
  2. npc.say(str)
复制代码
他们的效果都是


变量类型:

SO,变量可以储存某些数据
而JS有很多的数据类型
我们目前主要关注:
数字类型
文本类型
布尔类型

那他们具体都是什么东西呢?
数字类型就是1 2 3 这样子的
而且数字类型还包括 整数类型浮点数类型
如:1 2 3的是整数类型
而:1.00 2.01 3.745的是浮点数类型
也就是有点像我们平时说的小数 但
它并不是小数

那文本类型又是什么呢?
文本类型就是储存字符串用的
说简单点 就是储存 你 好 A B C 这样子的文字用的
而字符串是要用" "裹住的
如:
  1. var str = "你好 minecraft"
复制代码
那布尔类型又是什么呢?
布尔类型就是存储true和false的类型
而true和false就是布尔值
布尔值是什么? 也就是真与假 对与错 是与否
比如 1+1=2 那么就是true的
而  1+1=1 则又是false的




:对布尔值好像还是有点不理解

:没事 在我们学到逻辑判断的时候 我会更详细教你 布尔值 的

:那行 我们继续说 运算符 吧

:运算符有点多哦 我列个表 让你能够轻松了解吧awa

运算符:

我们目前主要认识算术运算符、赋值运算符和文本运算符

算术运算符:
运算符 描述 例子 结果
+ 加法 1+1 2
- 减法 1-1 0
* 乘法 10*10 100
/ 除法 100/10 10
% 取余(取模) 10%8 2(余数)
++ 自增 不是+1 是变大1 a=1; a++ 2
-- 自减 不是-1  是缩小1 a=-1; a -- -2


:对了 一定要弄清++a和a++这样子的区别哦!
比如:
  1. var a=1;
  2. npc.say(a++);
  3. npc.say(++a);
复制代码

:我知道~我知道! a++ 是后运行自增 ++a 是先运行自增

:先后运算应该没有什么区别吧……

:不不不 先运算和后运算的区别可大了

:我知道 我知道!

:别你知道了 一会被人说水就不好了
  1. var a=1;
  2. npc.say(a++);
  3. npc.say(++a);
复制代码

我们看a++和++a
a++在这段代码运行后NPC是说出的是"1"
而++a说出的是"2"
因为已经说出a才进行自增已经太晚了
要在说出a之前让a进行自增

:其实写成我这样不就好了吗
  1. var a=1;
  2. a++;
  3. npc.say(a);
复制代码
:你们事可真多……

:不知道为什么 但是我有点想打人的冲动


赋值运算符:
运算符 例子 相等于 结果
= a=b a==b
+= a=b=1;a+=b a=a+b a==2
-= a=b=1;a-=b a=a-b a==0
*= a=b=10;a*=b a=a*b a==100
/= a=b=10;a/=b a=a/b a==1
%= a=10,b=4;a%=b a=a%b a==2




:你看我上面写到的 a=b=10 这是一种给多个变量一起赋值的方法
还有上面的a=10,b=10这样子的是多声明 但是我没有写var
比如var a,b,c,d; 这样子我就可以一下子声明 a b c d 四个变量!

:知道了 知道了 我们还是继续说文本运算符吧!


文本运算符就是+ 但是和字符串在一起 它就不是算术运算符 而是文本运算符的串联符号

比如:
  1. npc.say("1"+2);
复制代码
npc说出的是"12"而不是3
这是因为"1"是先运算的 所以+变成了串联符号
2也就成了文本类型 所以是"12"


又比如:
  1. npc.say("你好 "+"中国!");
复制代码
npc说出的就是"你好 中国!"



:@ 问你个问题 你知道怎么修改以下代码能让NPC输出"这是:3"吗?只能修改蓝色部分哦~
var a=1;
var b=2;
npc.say("这是:"+a+b) ;
:我试试…… 是这样子吗?
  1. var a=1;
  2. var b=2;
  3. npc.say("这是:"+(a+b)) ;
复制代码
(npc输出):这是3

:是的没错 你答对了通过添加()改变权重以此改变运算顺序 这不止在这种情况有用 要记好哦~

:别那么多话了 赶紧教完注释下课

:好好好 猪大佬 您说的算qwq

注释:
我们在编写代码中经常会用到注释 比如介绍这段代码是做什么的 等等
还有一个功能 就是让展示不想让其运行代码 不运行
如:
  1. npc.say("hello world")
复制代码
(npc输出):hello world
  1. //npc.say("hello world")
复制代码
(npc输出):(没动静)

我们还可以用在介绍一段代码 比如这段:
  1. <blockquote>function sound(sound,volume,tone){
复制代码
//是单行注释(只能注释一行)

/*
是多行注释(可以注释包裹住的内容)
*/

自己试试吧awa
---------本章到此结束---------




4.认识三元运算符、逻辑判断与循环


:三元运算符又是什么呢?

:我们先不了解三元运算符是做什么的 我们先了解它的格式


  1. (表达式)? (表达式A):(表达式B)
  2. //三元运算符
复制代码
:三元运算符的作用就是 当表达式为true时 启用表达式A 而为false时 启用表达式B

:那怎么样是 true 怎么样是 false呢?

:不急 我们先来认识 关系(比较)运算符


关系运算符:



运算符 描述例子 布尔值
== 等于
1==1
1==2
1=="1"
true
false
true
!= 不等于
1!=2
1!=1
true
false
> 大于
2>1
1>2
true
false
< 小于
1<2
2<1
true
false
>= 大于或等于
2>=2
2>=1
2>=3
2>=4
true
true
false
false
<= 小于或等于
3<=3
3<=4
3<=2
3<=1
true
true
false
false


:为什么这个1=="1"会是true呢?
不是一个是整数类型 一个是文本类型吗

:这个问题问得好 除了==和!=外 还有 === 和 !==

他们分别是

绝对等于不绝对等于

一般的 == 和 !== 并不会考虑数据类型

但是===和!==会考虑数据类型

比如:


=== 绝对等于(考虑数据类型)
1===1
1==="1"
true
false
!== 不绝对等于(不考虑数据类型)
1!=="2"
1!==1
true
false



三元运算符:



:那三元运算符具体又要怎么用呢?


:我给你举个例子 如果1==1是对(true)的 NPC就会说出YES

  1. npc.say((1==1)? "YES":"NO");
复制代码
(npc输出):YES


逻辑判断-if:



:逻辑判断 和三元运算符有些相似 就是当条件全部为true时执行代码块的代码


:如果你还不明白的话 我写个例子给你看吧

  1. if(1==1){
  2. npc.say(1)
  3. }
复制代码
:1==1是true的情况下 npc 就会说"1"
根据以上代码 我们也知道了 逻辑判断的格式
  1. if(条件){
  2. 代码块
  3. }
复制代码
:对了 我们还要认识 逻辑运算符

:这运算符可真多呢(表格做的真累

逻辑运算符:

运算符 描述 例子 结果
&& 与运算
必须左右两边都是true才是true
1==1&&2==2
1==1&&1==2
true  
false
|| 或运算
左右两边其中一边是true即是true
1==1||2==2
1==1||1==2
true  
true
非运算
true与false对调
!(1==1)
!(1==2)
false
true



:对了 上面教的是 if语句 一种逻辑判断

还有另一种逻辑判断 叫switch


:还有要学的啊……(打字好累的)

:等一下 关于 else 我们还没有学习

:哦! 我都忘了……


:别吧……



else是跟在if后面的 比如

  1. if(1==1&&1==2){
  2. npc.say("1");
  3. }else{npc.say("2");}
复制代码
else是当if中的条件不为true时运行的代码

逻辑判断-switch:
格式:
  1. switch(表达式n 一般是一个变量){
  2. case 表达式:
  3. 代码块
  4. }
复制代码
switch就是看
表达式n 是否与 case的表达式 相等
如果相等 就运行 这个case的代码块

如:
  1. var a,b;
  2. a=1;
  3. b=2;
  4. switch(a+b){
  5. case 1:
  6. npc.say(1)
  7. break;
  8. case 3:
  9. npc.say(2)
  10. break;
  11. case 100:
  12. npc.say(3)
  13. break;
  14. }
复制代码
(npc输出):2


:如果没有需要的话 最好在case的代码块结束的地方写上break;

而至于break是什么 我们之后会讲



:好的 猪大佬qwq




循环:



:好的 到本章要了解的最后一个项目了 循环

我一次性讲完各种循环的格式好了



格式:

  1. //for循环:
  2. for(第一次循环开始前执行的代码;循环条件;每一次循环后执行的代码){
  3. 代码块
  4. }
复制代码
  1. //while循环:
  2. while(循环条件){
  3. 代码块
  4. }
复制代码
  1. //do…while循环:
  2. do{
  3. 代码块
  4. }
  5. while(循环条件)
复制代码

例子:

  1. //for循环:
  2. for(var i=1;i<=5;i++){
  3. npc.say(i);
  4. }
  5. //npc从1数到5
复制代码
  1. //while循环:
  2. var i=1;
  3. while(i<=5){
  4. npc.say(i);
  5. i++;
  6. }
  7. //npc从1数到5
复制代码
  1. //do…while循环:
  2. var i=1;
  3. do{
  4. npc.say(i);
  5. i++;
  6. }
  7. while(i<=5);
  8. //npc从1数到5
复制代码


:感觉都差不多呢……

:对 其实都差不多 还有一个很重要的事 do…while 循环至少会执行一次

因为 do…while循环是先执行代码块后判定是否满足条件 如果满足条件 继续执行



---------本章到此结束---------



5.了解break和continue


:其实breakcontinue是非常简单的

:简单就快说=- =


还记得我们之前学的循环吗
在循环中就可以用到break和continue
break就是跳出循环
continue就是跳过本次循环
举个例子

  1. for(var i=0;i<50;i++){
  2. if(i>10&&i<=15)continue;
  3. if(i>30)break;
  4. npc.say(i)
  5. }
复制代码
这个代码的意思是当i是10~15的时候就跳过
当i>30就跳出
跳过和跳出的区别就是
跳过会进行后面的循环 跳出是直接结束循环
所以NPC实际上会说出来的是
1 2 3 4 5 6 7 8 9 10 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
在其他循环也是一样的道理 在switch最好每个case结束都用上break
---------本章到此结束---------
今天巨短啊



6.了解CNPC-API
跑回来更新了

反正这章也不会太长
http://www.kodevelopment.nl/customnpcs/api/1.7.10/index.html?overview-summary.html
这个是DOC
我们先来了解页面

红框:包列表
篮框:类列表
黄框:具体方法
好的 没啥好说的了 这个帖子会更新1.7.10NPC的API翻译和例子



7.了解function与拋异
在写了几个插件后 我又回来了更新教程了
其实打了一个星期狂战士信条

我们先认识function
function是什么?
function是一个代码块 类似java中的方法

举个例子更容易理解吧

  1. function yourName(name){
  2. npc.say(name);
  3. //让NPC说出参数name
  4. return true;
  5. //返回(return) 数据:true
  6. }
复制代码
这就是一个代码块

function的定义格式是:

function 方法名(参数){
代码块
}

function是一个可以被反复调用的代码块
function中代码的不会直接执行
我们需要调用

那要怎么调用呢
举个例子


  1. function yourName(name){
  2. npc.say(name);
  3. //让NPC说出参数name
  4. return true;
  5. //返回(return) 数据:true
  6. }
  7. yourName("mchhui");
复制代码

NPC输出:mchhui



:return又是什么?

[Notch]:return是返回语句 返回值就是……

:举个例子比什么都容易!




  1. function testA(){
  2. return true;
  3. }
  4. function testB(){
  5. return "hello world";
  6. }
  7. function testC(){
  8. return 233;
  9. }
复制代码

然后我们输出他们
是输出 而不是 调用
说简单点

a()这样子就是调用
npc.say(a())就是输出


  1. npc.say(testA());
  2. npc.say(testB());
  3. npc.say(testC());
复制代码
NPC输出:true
NPC输出:hello world
NPC输出:233

返回值就是返回return后面的数据
当function执行到return的时候就会跳出function
也就是不继续执行后面的代码
所以你可以写成这样 return;

说完了function 我们再来说说拋异
拋异又是什么
拋异 顾名思义 抛出异常
我们先认识拋异的格式

try{
代码块A
}
catch(e){
代码块B
}

那拋异又有什么用呢?
举个例子
在互动钩子中

  1. npc.say(player.getHeldItem().getDisplayName());
复制代码

是获取玩家手中物品名

但是 如果玩家手中没有物品 就会发生报错

那我们怎么解决这个问题呢
我们可以如下
使用逻辑判断解决

  1. if(player.getHeldItem()!=null){npc.say(player.getHeldItem().getDisplayName());
复制代码

但是 使用逻辑判断 是在我们知道 为什么会发生错误的情况下
如果我们不知道呢?
我们就可以使用拋异了

  1. try{
  2. npc.say(player.getHeldItem().getDisplayName());
  3. }
  4. catch(e){}
复制代码
try里面的代码发生异常时 就会跳出try区块并且执行catch代码块的代码
大部分情况下try拋异比起if判断处理异常更加省时省力

例子:

---------本章到此结束---------




脚把手实例:动态彩色名字
赌五毛 看和不看一个样XD 就是可以CV代码
要求&提示:
让NPC的名字变成彩色的 并且动起来
如:NPC -> NPC -> NPC -> NPC
1.更新钩子
2.数组与遍历
3.用正则表达式清空颜色代码


(先自己想啦QWQ 不要直接看代码啊!)

思路&代码:
  1. name=npc.getName();
  2. //获取名字
  3. name=name.replace(/§[A-Za-z0-9]/g,"")
  4. //清空name变量中的颜色代码
  5. color=["§4","§c","§6","§2","§e","§a","§3","§b","§1","§9","§d","§5","§f","§7","§8","§0"]//0~15
  6. //把颜色代码存入数组0~15分别表示一个
  7. colorName=""
  8. //新建一个名字变量
  9. for(var x=0 in name){
  10. colorName=colorName+(color[parseInt(Math.random()*15+0)]+name[x])
  11. }
  12. //把color[通过随机值随机获取颜色]+name[某一位]存到colorName
  13. npc.setName(colorName);
  14. //设置名字
复制代码
是不是有种看了跟没看一样的感觉XD


8.了解数组、遍历与正则表达式


[Notch]:在托更多年以后 以后 我又回来了
:今天你又要更新什么呢?
[Notch]:数组 遍历 以及 正则表达式
[Notch]:正则表达式好麻烦的 一点不想教
:我不教我教XD
:遍历是什么呢?
[Notch]:不急 在认识遍历之前 我们先认识数组

数组是什么吗?
数组是一种数据类型
array(数组)
是一种集合 他每一位 代表一个元素 这些元素可以是任意类型


[Notch]:举个例子[1,2,3]就是一个数组(var array=[1,2,3])
:数组是从0号开始计位的 比如[1,2,3] 1在0号位 2在1号位 3在2号位


  1. var array=[1,2,3]
  2. npc.say(array)
  3. npc.say(array[0])
  4. npc.say(array[1])
  5. npc.say(array[2])
复制代码
输出结果:
      (NPC):1,2,3
(NPC):1
(NPC):2
(NPC):3
我们也可以单独为某一位设置数据
比如:

  1. var array=[1,"请把我改掉",3]
  2. array[1]=2
  3. npc.say(array)
  4. npc.say(array[0])
  5. npc.say(array[1])
  6. npc.say(array[2])
复制代码
输出结果:
      (NPC):1,2,3
(NPC):1
(NPC):2
(NPC):3


[Notch]:数组说完了 我们说遍历
:嗯嗯 好

遍历可以说是为了数组存在的
就比如上面的那个代码
我们只有3个元素 分别是1 2 3
那我们的元素如果多了呢? 不可能每一个都写出来吧
所以就有了遍历
遍历是什么 遍历就是把所有的都经历一遍
举个例子容易理解

但在举例子之前 我们想认识数组的一个属性 length属性
如何使用?
比如

  1. var array=[1,2,3]
  2. npc.say(array.length)
复制代码
输出结果:
(NPC):3
length 就是数组的长度 也就他拥有多少个元素(从1开始计数)

然后给遍历举个例子:

  1. var array=[1,2,3]
  2. for(x=0;x<array.length;x++){
  3. npc.say(array[x])
  4. }
复制代码
输出结果:
(NPC):1
(NPC):2
[character](NPC):3
遍历还有另一种写法

  1. var array=[1,2,3]
  2. for(x=0 in array){
  3. npc.say(array[x])
  4. }
  5. /*格式for(位数变量 in 数组对象){
  6. 代码块
  7. }*/
复制代码
输出结果:
[character](NPC):1
[character](NPC):2
[character](NPC):3


[Notch]:现在到正则表达式了 我是真的懒得讲
:我来稍微讲一下好了

我们要弄懂三个问题 正则表达式是什么 可以做什么 如何使用
是什么:
正则表达式是一种表达式 你可以理解为 格式符号
比如[abc] [0-9]这样子的

可以做什么:
你还记得各种网站上的绑定邮箱吗
你的邮箱格式假如不是[email protected]的话 它就会提示错误
这就是正则表达式做到的

如何使用:


function interact(e){
npc.say(/^\d+\.\d+$/.test("1.00"))
}
比如这个 /^\d+\.\d+$/.test("文本")
匹配文本中有没有小数点
有则为true反则false

各位有兴趣百度一下吧 这玩意可以讲到累死
推荐文献:
http://www.mcbbs.net/thread-827651-1-1.html(java的 其实都差不多)
http://www.runoob.com/js/js-regexp.html(js的)
—————本章完 END—————

9.认识Java.type()
注意:本章内容可能仅支持nashorn(JS)引擎


[Notch]:这个玩意可强大了 调用java类 java自带工具类 mods里jar的类 bukkit forge 强大的一批
:更多骚操作陆续放出 可收藏本贴

本章很短 只有格式和简单的实例
  1. //格式:Java.type("类路径")
  2. //然后我们就可以直接使用或者new一个对象使用其中的方法了
  3. //比如:
  4. var System=Java.type("java.lang.System")
  5. npc.say(System.getProperty("os.name"))//获取系统 服务器就是服务器的系统
复制代码
输出结果(我是win7):
[character](NPC):Windows 7
—————本章完 END—————


10.后记
不知不觉中 本贴的1.7.10部分就算完结了
1.12.2的教程马上会开始编写
更多的骚操作等待发现
1.7.10的教程因为是第一次写 可能写的不太好
已经获得一个优秀了 下一个目标精华
最后
我爱你们 亲爱的npcer
——hueihuea(mchhui)

2018/12/2
—————1.7.10NPC脚本教程完 END—————




1.监听事件


:时间过得真快 但是为什么1.12.2如此短小?
[Notch]:1.12.2和1.7.10实际上都是一个道理 不要在意细节

API地址: http://www.kodevelopment.nl/cust ... erview-summary.html
在学习之前 我们先认识一下新的脚本界面

黄框:TAB栏(点击"+"新建一个TAB 类似类?)
蓝框:设置栏(设置你的属性)
橙框:帮助栏
红框:操作栏

黄框:TAB栏(目前以新建一个TAB)
橙框:编辑栏(在里面写代码)
篮框:操作栏
紫框:脚本栏(导入你的脚本 我也没用过)
注:TAB是从前往后执行的
事件函数:
  1. function interact(event){
  2. //代码块
  3. }
  4. //其中event参数为事件对象
  5. //更多事件名请参考APIDOC
复制代码
—————本章完 END—————

2.后记
1.12.2的教程意外的简短
因为也没什么可以教的了
之后会疯狂写实例教程的!

——hueihuea(mchhui)


2018/12/22
—————1.12.2NPC脚本教程完 END—————
[groupid=1595]CNPC Script Studio[/groupid]