







其实安装了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":
我给大家一个脚本
- npc.say("hello world")
我们把它放在对话(互动)钩子里

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

---------本章到此结束---------
3.认识变量、运算符与注释
看来今天不能更新多少了qwq



这和代数有点相似 如: X=1 而在编程语言中 我们把其中的“1”称为值 “X”称为变量名 “=”称为赋值符号


声明变量:
- var 变量名;
而声明的格式就是上面的 var 变量名;
(注:虽然CNPC对编写是否规范并没有太大的要求 但是因为这是教程 我会以规范的形式写代码)
而我们看看两行代码
- npc.say("hello world");
- var str="hello world";
- npc.say(str)

变量类型:
SO,变量可以储存某些数据
而JS有很多的数据类型
我们目前主要关注:
数字类型
文本类型
布尔类型
那他们具体都是什么东西呢?
数字类型就是1 2 3 这样子的
而且数字类型还包括 整数类型 和 浮点数类型
如:1 2 3的是整数类型
而:1.00 2.01 3.745的是浮点数类型
也就是有点像我们平时说的小数 但它并不是小数
那文本类型又是什么呢?
文本类型就是储存字符串用的
说简单点 就是储存 你 好 A B C 这样子的文字用的
而字符串是要用" "裹住的
如:
- var str = "你好 minecraft"
布尔类型就是存储true和false的类型
而true和false就是布尔值
布尔值是什么? 也就是真与假 对与错 是与否
比如 1+1=2 那么就是true的
而 1+1=1 则又是false的






运算符:
我们目前主要认识算术运算符、赋值运算符和文本运算符
算术运算符:
运算符 | 描述 | 例子 | 结果 |
+ | 加法 | 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 |


比如:
- var a=1;
- npc.say(a++);
- npc.say(++a);





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

- var a=1;
- a++;
- 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=10,b=10这样子的是多声明 但是我没有写var
比如var a,b,c,d; 这样子我就可以一下子声明 a b c d 四个变量!


文本运算符就是+ 但是和字符串在一起 它就不是算术运算符 而是文本运算符的串联符号
比如:
- npc.say("1"+2);
这是因为"1"是先运算的 所以+变成了串联符号
2也就成了文本类型 所以是"12"
又比如:
- npc.say("你好 "+"中国!");



var a=1;
var b=2;
npc.say("这是:"+a+b) ;

- var a=1;
- var b=2;
- npc.say("这是:"+(a+b)) ;





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

- //npc.say("hello world")

我们还可以用在介绍一段代码 比如这段:
- <blockquote>function sound(sound,volume,tone){
/*
是多行注释(可以注释包裹住的内容)
*/
自己试试吧awa
---------本章到此结束---------


:我们先不了解三元运算符是做什么的 我们先了解它的格式
- (表达式)? (表达式A):(表达式B)
- //三元运算符

:那怎么样是 true 怎么样是 false呢?
:不急 我们先来认识 关系(比较)运算符
运算符 | 描述 | 例子 | 布尔值 | ||||||||
== | 等于 |
|
| ||||||||
!= | 不等于 |
|
| ||||||||
> | 大于 |
|
| ||||||||
< | 小于 |
|
| ||||||||
>= | 大于或等于 |
|
| ||||||||
<= | 小于或等于 |
|
|


不是一个是整数类型 一个是文本类型吗

=== | 绝对等于(考虑数据类型) |
|
| ||||
!== | 不绝对等于(不考虑数据类型) |
|
|



:我给你举个例子 如果1==1是对(true)的 NPC就会说出YES
- npc.say((1==1)? "YES":"NO");



:如果你还不明白的话 我写个例子给你看吧
- if(1==1){
- npc.say(1)
- }

根据以上代码 我们也知道了 逻辑判断的格式
- if(条件){
- 代码块
- }



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


:还有要学的啊……(
打字好累的)
:等一下 关于 else 我们还没有学习
:哦! 我都忘了……


else是跟在if后面的 比如
- if(1==1&&1==2){
- npc.say("1");
- }else{npc.say("2");}
逻辑判断-switch:
格式:
- switch(表达式n 一般是一个变量){
- case 表达式:
- 代码块
- }
表达式n 是否与 case的表达式 相等
如果相等 就运行 这个case的代码块
如:
- var a,b;
- a=1;
- b=2;
- switch(a+b){
- case 1:
- npc.say(1)
- break;
- case 3:
- npc.say(2)
- break;
- case 100:
- npc.say(3)
- break;
- }








格式:
- //for循环:
- for(第一次循环开始前执行的代码;循环条件;每一次循环后执行的代码){
- 代码块
- }
- //while循环:
- while(循环条件){
- 代码块
- }
- //do…while循环:
- do{
- 代码块
- }
- while(循环条件)
例子:
- //for循环:
- for(var i=1;i<=5;i++){
- npc.say(i);
- }
- //npc从1数到5
- //while循环:
- var i=1;
- while(i<=5){
- npc.say(i);
- i++;
- }
- //npc从1数到5
- //do…while循环:
- var i=1;
- do{
- npc.say(i);
- i++;
- }
- while(i<=5);
- //npc从1数到5




---------本章到此结束---------
5.了解break和continue




还记得我们之前学的循环吗
在循环中就可以用到break和continue
break就是跳出循环
continue就是跳过本次循环
举个例子
- for(var i=0;i<50;i++){
- if(i>10&&i<=15)continue;
- if(i>30)break;
- npc.say(i)
- }
当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中的方法
举个例子更容易理解吧
- function yourName(name){
- npc.say(name);
- //让NPC说出参数name
- return true;
- //返回(return) 数据:true
- }
function的定义格式是:
function 方法名(参数){
代码块
}
function是一个可以被反复调用的代码块
function中代码的不会直接执行
我们需要调用它
那要怎么调用呢
举个例子
- function yourName(name){
- npc.say(name);
- //让NPC说出参数name
- return true;
- //返回(return) 数据:true
- }
- yourName("mchhui");



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


- function testA(){
- return true;
- }
- function testB(){
- return "hello world";
- }
- function testC(){
- return 233;
- }
然后我们输出他们
是输出 而不是 调用
说简单点
a()这样子就是调用
npc.say(a())就是输出
- npc.say(testA());
- npc.say(testB());
- npc.say(testC());



返回值就是返回return后面的数据
当function执行到return的时候就会跳出function
也就是不继续执行后面的代码
所以你可以写成这样 return;
说完了function 我们再来说说拋异
拋异又是什么
拋异 顾名思义 抛出异常
我们先认识拋异的格式
try{
代码块A
}catch(e){
代码块B
}
那拋异又有什么用呢?
举个例子
在互动钩子中
- npc.say(player.getHeldItem().getDisplayName());
是获取玩家手中物品名
但是 如果玩家手中没有物品 就会发生报错
那我们怎么解决这个问题呢
我们可以如下
使用逻辑判断解决
- if(player.getHeldItem()!=null){npc.say(player.getHeldItem().getDisplayName());
但是 使用逻辑判断 是在我们知道 为什么会发生错误的情况下
如果我们不知道呢?
我们就可以使用拋异了
- try{
- npc.say(player.getHeldItem().getDisplayName());
- }
- catch(e){}
大部分情况下try拋异比起if判断处理异常更加省时省力
例子:
---------本章到此结束---------
要求&提示:
让NPC的名字变成彩色的 并且动起来
如:NPC -> NPC -> NPC -> NPC
2.数组与遍历
3.用正则表达式清空颜色代码
(先自己想啦QWQ 不要直接看代码啊!)
思路&代码:
- name=npc.getName();
- //获取名字
- name=name.replace(/§[A-Za-z0-9]/g,"")
- //清空name变量中的颜色代码
- color=["§4","§c","§6","§2","§e","§a","§3","§b","§1","§9","§d","§5","§f","§7","§8","§0"]//0~15
- //把颜色代码存入数组0~15分别表示一个
- colorName=""
- //新建一个名字变量
- for(var x=0 in name){
- colorName=colorName+(color[parseInt(Math.random()*15+0)]+name[x])
- }
- //把color[通过随机值随机获取颜色]+name[某一位]存到colorName
- npc.setName(colorName);
- //设置名字
8.了解数组、遍历与正则表达式

[Notch]:在托更多年以后 以后 我又回来了

[Notch]:数组 遍历 以及 正则表达式
[Notch]:正则表达式好麻烦的 一点不想教


[Notch]:不急 在认识遍历之前 我们先认识数组

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

[Notch]:举个例子[1,2,3]就是一个数组(var array=[1,2,3])


- var array=[1,2,3]
- npc.say(array)
- npc.say(array[0])
- npc.say(array[1])
- npc.say(array[2])




我们也可以单独为某一位设置数据
比如:
- var array=[1,"请把我改掉",3]
- array[1]=2
- npc.say(array)
- npc.say(array[0])
- npc.say(array[1])
- npc.say(array[2])





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


遍历可以说是为了数组存在的
就比如上面的那个代码
我们只有3个元素 分别是1 2 3
那我们的元素如果多了呢? 不可能每一个都写出来吧
所以就有了遍历
遍历是什么 遍历就是把所有的都经历一遍
举个例子容易理解
但在举例子之前 我们想认识数组的一个属性 length属性
如何使用?
比如
- var array=[1,2,3]
- npc.say(array.length)

length 就是数组的长度 也就他拥有多少个元素(从1开始计数)
然后给遍历举个例子:
- var array=[1,2,3]
- for(x=0;x<array.length;x++){
- npc.say(array[x])
- }


[character](NPC):3
遍历还有另一种写法
- var array=[1,2,3]
- for(x=0 in array){
- npc.say(array[x])
- }
- /*格式for(位数变量 in 数组对象){
- 代码块
- }*/
[character](NPC):1
[character](NPC):2
[character](NPC):3

[Notch]:现在到正则表达式了 我是真的懒得讲


我们要弄懂三个问题 正则表达式是什么 可以做什么 如何使用
是什么:
正则表达式是一种表达式 你可以理解为 格式符号
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 强大的一批


本章很短 只有格式和简单的实例
- //格式:Java.type("类路径")
- //然后我们就可以直接使用或者new一个对象使用其中的方法了
- //比如:
- var System=Java.type("java.lang.System")
- npc.say(System.getProperty("os.name"))//获取系统 服务器就是服务器的系统
[character](NPC):Windows 7
—————本章完 END—————
10.后记
不知不觉中 本贴的1.7.10部分就算完结了
1.12.2的教程马上会开始编写
更多的骚操作等待发现
1.7.10的教程因为是第一次写 可能写的不太好
已经获得一个优秀了 下一个目标精华
最后
我爱你们 亲爱的npcer
1.监听事件


[Notch]:1.12.2和1.7.10实际上都是一个道理 不要在意细节

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

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

黄框:TAB栏(目前以新建一个TAB)
橙框:编辑栏(在里面写代码)
篮框:操作栏
紫框:脚本栏(导入你的脚本 我也没用过)
注:TAB是从前往后执行的
事件函数:
- function interact(event){
- //代码块
- }
- //其中event参数为事件对象
- //更多事件名请参考APIDOC
2.后记
1.12.2的教程意外的简短
因为也没什么可以教的了
之后会疯狂写实例教程的!