MC红石特效的原理

简单的讲一下红石特效制作的方法(教学向,不涉及各种材质包的添加什么的,尽量保证看文章之后能在mc里面用特效画出直线,曲线)

一、教学环境

  • 版本: 1.12.2(java版)
  • Fabric: 不安装
  • Forge: 14.23.5.2855
  • 不怎么清晰的头脑和不怎么协调的手

二、前置知识

  • MC的基础操作(这个不用教吧)
  • 简单的任何高级语言的使用
  • mcfunction的介绍
    • 在你的游戏存档下有这样一个文件夹./data/functions/,在其中你可以新建文件夹,同时在里面写一些后缀为.mcfunction的文件,在游戏中就可以调用内部的函数
  • 然后,然后我们就可以开始了!

三、生成粒子

粒子的生成需要用到particle命令

1
particle <粒子名称> <x> <y> <z> [<xd> <yd> <zd>] [飞行速度] [粒子数量] [显示模式] [目标玩家]

mc里面的坐标和我们平常感觉的存在着点差异!

上面讲的有点复杂,简单来说

1
2
particle endRod x y z 0 0 0 0 1 force//在(z,y,x)处生成一个静止的endRod粒子
particle endRod x y z vx vy vz r 0 force//在(z,y,x)处生成一个endRod粒子,大小为r,速度方向由vx,vy,vz决定

到这里,其实你就已经可以在游戏里面生成了一个点了,如果你只是想知道原理,那现在,你就可以走了,再接下来的简单来说就是不断调用这个指令了。

四、生成直线

  • 实现
    我们已经学会了生成一个粒子了,那么很自然的我们就可以想到,只要生成连续的多个粒子,就可以获得直线
    但是命令方块只能调用一次函数,怎么样才能够同时调用多个函数呢,这里我们就要用到刚才说的mcfunction了,在functions文件夹里面新建一个文件夹(我命名为draw),在其中新建一个文件line.mcfunction,这时候,我们就可以在其中进行编辑
    空间中直线的参数方程:

{x=x0+vxTy=y0+vyTz=z0+vzT\left\{ \begin{aligned} x = x_0+v_xT \\ y = y_0+v_yT\\ z = z_0+v_zT \end{aligned} \right.

  • 然后就可以直接根据循环来描点了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //具体参数要改
    #include <bits/stdc++.h>
    int main()
    {
    float x1, y1, z1, x2, y2, z2;
    std::cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;
    for (int i = 0; i <= 100; i++)
    {
    float x, y, z;
    x = x1 + ((x2 - x1) * i) / (100);
    y = y1 + ((y2 - y1) * i) / (100);
    z = z1 + ((z2 - z1) * i) / (100);
    std::cout << "particle fireworksSpark " << x << " " << y << " " << z << " 0 0 0 0 1 force" << std::endl;
    }
    return 0;
    }
  • 游戏内具体调用
    1
    2
    $ reload # 每次重写文件之后需要重新载入文件内容
    $ function draw:line # 调用函数

五、生成抛物线

和直线一样,写出参数方程,直接穷举就行了

{x=x0+vxTy=y0+vyTz=z0+vzT12gT2\left\{ \begin{array}{l} x = x_0+v_xT \\ y = y_0+v_yT\\ z = z_0+v_zT-\frac{1}{2}gT^2 \end{array} \right.

代码就很简单了,(自己写的太乱了,不贴出来了)

六、其他曲线

  • 只要你能写出曲线的参数方程,你就可以轻松的通过循环,得到描绘该曲线的mcfunction代码,这里就不做过多的赘述了
  • 当然只要你愿意,你甚至可以不需要参数方程,直接通过穷举描绘图线

七、关于图像

mc02.png
使用python,具体参数可以自己调

刚开始写红石特效的时候对python一窍不通,这个也是根据别人写的改的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from PIL import Image
im = Image.open('<填入你图片的名字>.png')
f = open(r'iamge.mcfunction', "w")
x, y, z = 0, 0, 0
direction = 'z'
zoom_level = 30
particle_name = "endRod"
particle_value = "0 0 0 0 1 force"
width, height = im.size[0], im.size[1]
for w in range(0, width):
for h in range(0, height):
imgdata = (im.getpixel((w, h)))
if imgdata[0] == 0:
if direction == 'z':
cmd = f'particle {particle_name} {x-w/zoom_level} {y-h/zoom_level} {z} {particle_value}'
f.write(f'{cmd}\n')
elif direction == 'y':
cmd = f'particle {particle_name} {x - w / zoom_level} {y} {z - h / zoom_level} {particle_value}'
f.write(f'{cmd}\n')
elif direction == 'x':
cmd = f'particle {particle_name} {x} {y - h / zoom_level} {z - w / zoom_level} {particle_value}'
f.write(f'{cmd}\n')
f.close()

八、补充

到这里,其实还有一个没有解决的问题:如何先后呈现红石特效
根据自己电脑性能自己看看一个区间花多少个点就行了

其实很简单,摆两行命令方块,中间空一行,上面一行命令方块,写入想要执行的指令,下面一行写入

1
clone ~ ~1 ~ ~ ~1 ~ ~1 ~1 ~ replace move # 注意修改方向

mc04.png

这样,我们在中间放上红石块,红石块触发上下两个命令方块,而触发了下面的命令方块,又会将命令方块向前移动一格,从此先后触发不同的效果

如果同一个时间触发多个效果,就上多个线程,多几个这样的命令方块轨道就行了

九、比较垃圾的展示

  • 依托于worldedit实现红石音乐与红石特效的简单结合
    mc05.png
  • 比较水的红石特效
    mc06.png
  • 祝曾经某个很可爱的朋友(不用怀疑,就是没有声音)

十、后记

  • 可以使用自制的粒子来达到更好的效果
  • 加材质包,加光影,加材质包,加光影
  • 红石特效原理其实很简单,但是它的难点不在其实现上,而在于创新
  • 本人对红石特效仍处于摸索阶段,如果有说的不对的地方欢迎联系