Open12
マイクラ花火メモ置き場
とりあえず万華鏡花火のレシピ
計算式は LifeTime と距離(ブロック)依存性より、多項式近似による二次式を用いる。
ただし、C は初期条件(任意定数)
2階微分したら 0.04119 という定数が得られるので、マイクラの世界の花火は 0.04119 [block/tick
ソースコード
using MinecraftConnection;
using MinecraftConnection.Entity;
// マイクラサーバ接続先の設定
string address = "127.0.0.1";
ushort port = 25575;
string pass = "minecraft";
MinecraftCommands command = new MinecraftCommands(address, port, pass);
// メインとなる大玉花火
ushort lifeTime = 30;
Fireworks fireworks = new Fireworks()
{
LifeTime = lifeTime,
Type = FireworkType.LargeBall,
Colors = FireworkOption.RandomColor(),
FadeColors = new List<FireworkColors> { FireworkColors.WHITE },
};
// 周りを彩るバースト花火
Fireworks BurstFireworks(double x, double y, double z)
{
Fireworks fireworks = new Fireworks()
{
LifeTime = 0,
Type = FireworkType.Burst,
Colors = FireworkOption.RandomColor(),
FadeColors = new List<FireworkColors> { FireworkColors.WHITE },
Flicker = false,
Trail = true,
Motion = new Motion(x, y, z)
};
return fireworks;
}
// 多項式近似の計算式(任意定数は各自で調整が必要)
double diff = (0.020595 * lifeTime * lifeTime) - (0.02976 * lifeTime);
// 大玉花火とバースト花火の座標
Position pos = new Position(-516, 64, -205);
Position burstPos = new Position(-516, 64 + diff, -205);
// 大玉花火とバースト花火をそれぞれ打ち上げる
command.SetOffFireworks(pos, fireworks);
command.Wait(1700); // インターバルを置いておく
double val = 1.0;
command.SetOffFireworks(burstPos, BurstFireworks(val, 0, 0));
command.SetOffFireworks(burstPos, BurstFireworks(-val, 0, 0));
command.SetOffFireworks(burstPos, BurstFireworks(0, val, 0));
command.SetOffFireworks(burstPos, BurstFireworks(0, -val, 0));
command.SetOffFireworks(burstPos, BurstFireworks(val, val, 0));
command.SetOffFireworks(burstPos, BurstFireworks(val, -val, 0));
command.SetOffFireworks(burstPos, BurstFireworks(-val, val, 0));
command.SetOffFireworks(burstPos, BurstFireworks(-val, -val, 0));
実行結果
空の花火を実装してみた。
IsEmpty プロパティを true にすれば花火なしに軌跡だけ描ける。一本の軌跡を描きたいときに使えそう。
ソースコード
Fireworks fireworks1 = new Fireworks()
{
LifeTime = 100,
Motion = new Motion(0.05, 0.5, 0.0),
IsEmpty = true
};
Fireworks fireworks2 = new Fireworks()
{
LifeTime = 100,
Motion = new Motion(-0.05, 0.5, 0.0),
IsEmpty = true
};
Position pos = new Position(-523, 67, -205);
Position pos2 = new Position(-514, 67, -205);
command.SetOffFireworks(pos, fireworks1);
command.SetOffFireworks(pos2, fireworks2);
逆方向もできた。
軌跡に関しても Motion をいじればあらゆる方向へ打ち出せる。
ソースコード
Fireworks fireworks1 = new Fireworks()
{
LifeTime = 100,
Motion = new Motion(0.05, -1.0, 0.0),
IsEmpty = true
};
Fireworks fireworks2 = new Fireworks()
{
LifeTime = 100,
Motion = new Motion(-0.05, -1.0, 0.0),
IsEmpty = true
};
// 以下前スレッドと同じ
キレイ
これができたらどんなエフェクトでも作れそう
花火の例
ソースコード
Position pos = new Position(-536, 64, -205);
Fireworks emptyFirewroks(double x, double y, double z)
{
return new Fireworks()
{
LifeTime = 20,
IsEmpty = true,
Motion = new Motion(x, y, z)
};
}
Fireworks smallFirewroks()
{
return new Fireworks()
{
LifeTime = 0,
Colors = new List<FireworkColors> { FireworkColors.YELLOW },
FadeColors = new List<FireworkColors> { FireworkColors.ORANGE },
};
}
for (int i = 0; i < 10; i++)
{
command.SetOffFireworks(pos.X + 5 * i, pos.Y, pos.Z, emptyFirewroks(0.2, 0.7, 0.0));
command.SetOffFireworks(pos.X + 5 * i, pos.Y, pos.Z, emptyFirewroks(-0.2, 0.7, 0.0));
command.Wait(100);
}
command.Wait(300);
for (int i = 0; i < 10; i++)
{
command.SetOffFireworks(pos.X + 5 * i, pos.Y + 25, pos.Z, smallFirewroks());
}
チューリップ型花火(もう少し改良が必要かな)
ソースコード
Position pos = new Position(-540, 74, -205);
Fireworks Leaf(double x, double y, double z)
{
return new Fireworks()
{
LifeTime = 0,
Type = FireworkType.Burst,
Colors = new List<FireworkColors> { FireworkColors.LIME },
Trail = true,
Motion = new Motion(x, y, z)
};
}
Fireworks Flower(double x, double y, double z)
{
return new Fireworks()
{
LifeTime = 0,
Type = FireworkType.Burst,
Colors = new List<FireworkColors> { FireworkColors.RED },
Trail = true,
Motion = new Motion(x, y, z)
};
}
for (int i = 0; i < 3; i++)
{
command.SetOffFireworks(pos.X + 25 * i, pos.Y, pos.Z, Leaf(1.3, 0.8, 0));
command.SetOffFireworks(pos.X + 25 * i, pos.Y, pos.Z, Leaf(-1.3, 0.8, 0));
command.SetOffFireworks(pos.X + 23 * i, pos.Y - 2, pos.Z, Flower(-0.2, 2.0, 0));
command.SetOffFireworks(pos.X + 24 * i, pos.Y - 2, pos.Z, Flower(-0.1, 2.0, 0));
command.SetOffFireworks(pos.X + 25 * i, pos.Y - 2, pos.Z, Flower(0, 2.0, 0));
command.SetOffFireworks(pos.X + 26 * i, pos.Y - 2, pos.Z, Flower(0.1, 2.0, 0));
command.SetOffFireworks(pos.X + 27 * i, pos.Y - 2, pos.Z, Flower(0.2, 2.0, 0));
}
チューリップ型を少し書き換えてラベンダー風
ソースコード
Position pos = new Position(-540, 74, -205);
Random rand = new Random();
Fireworks Leaf(double x, double y, double z)
{
return new Fireworks()
{
LifeTime = 0,
Type = FireworkType.Burst,
Colors = new List<FireworkColors> { FireworkColors.LIME },
Trail = true,
Motion = new Motion(x, y, z)
};
}
Fireworks Flower = new Fireworks()
{
LifeTime = 0,
Type = FireworkType.SmallBall,
Colors = new List<FireworkColors> { FireworkColors.PURPLE }
};
for (int i = 0; i < 3; i++)
{
command.SetOffFireworks(pos.X + 25 * i, pos.Y, pos.Z, Leaf(1.3, 0.8, 0));
command.SetOffFireworks(pos.X + 25 * i, pos.Y, pos.Z, Leaf(-1.3, 0.8, 0));
command.Wait(200);
for (int j = 0; j < 10; j++)
{
command.SetOffFireworks(pos.X + 25 * i + rand.Next(-2, 2), pos.Y + rand.Next(3, 18), pos.Z, Flower);
}
}
結構力技だけどキャラものも作れそう。
これは ネコチャン (=^・^=)
ソースコード
Position pos = new Position(-510, 94, -205);
Fireworks Parts(double x, double y, double z)
{
return new Fireworks()
{
LifeTime = 0,
Type = FireworkType.Burst,
Colors = new List<FireworkColors> { FireworkColors.YELLOW },
Trail = true,
Motion = new Motion(x, y, z)
};
}
Fireworks Eyes(double x, double y, double z)
{
return new Fireworks()
{
LifeTime = 0,
Type = FireworkType.SmallBall,
Colors = new List<FireworkColors> { FireworkColors.BLUE },
Trail = true,
Motion = new Motion(x, y, z)
};
}
Fireworks Face(double x, double y, double z)
{
return new Fireworks()
{
LifeTime = 5,
IsEmpty = true,
Motion = new Motion(x, y, z)
};
}
Fireworks Face2(double x, double y, double z)
{
return new Fireworks()
{
LifeTime = 20,
IsEmpty = true,
Motion = new Motion(x, y, z)
};
}
for (int i = 0; i < 10; i++)
{
command.SetOffFireworks(pos.X, pos.Y, pos.Z, Face(-0.2, -1, 0));
command.SetOffFireworks(pos.X, pos.Y, pos.Z, Face(0.2, -1, 0));
command.SetOffFireworks(pos.X - 10, pos.Y, pos.Z, Face(-0.2, -1, 0));
command.SetOffFireworks(pos.X - 10, pos.Y, pos.Z, Face(0.2, -1, 0));
command.SetOffFireworks(pos.X - 10, pos.Y - 2, pos.Z, Face(0.8, 0, 0));
}
command.SetOffFireworks(pos.X - 14, pos.Y - 6, pos.Z, Face2(0.05, -0.85, 0));
command.SetOffFireworks(pos.X + 3, pos.Y - 6, pos.Z, Face2(-0.05, -0.85, 0));
command.SetOffFireworks(pos.X - 6, pos.Y - 12, pos.Z, Parts(-1.4, -0.2, 0));
command.SetOffFireworks(pos.X - 6, pos.Y - 12, pos.Z, Parts(1.4, -0.2, 0));
command.SetOffFireworks(pos.X - 11, pos.Y - 5, pos.Z + 7, Eyes(0, 0, 2));
command.SetOffFireworks(pos.X, pos.Y - 5, pos.Z + 7, Eyes(0, 0, 2));
花火パーティクルを使うと任意の形状を描画できる。pos.X
にかかっている 0.1 はゲイン調整のためのパラメータ。pos.Y
にかかっている 5 も同様。
例えば sin と cos をプロットすることもできる。
Position pos = new Position(-510, 94, -205);
for (int i = 0; i < 360; i++)
{
double angle = Math.PI * i / 180;
command.SendCommand($"particle firework {pos.X - i * 0.1} {pos.Y + Math.Sin(angle) * 5} {pos.Z} 0 0 0 0 1");
command.SendCommand($"particle firework {pos.X - i * 0.1} {pos.Y - 15 + Math.Cos(angle) * 5} {pos.Z} 0 0 0 0 1");
}
えっぐw
とりあえずフーリエ級数展開しとく。
ソースコード
for (int i = -360; i <= 360; i++)
{
double angle = Math.PI * i / 180;
double val = 0.0;
for (int j = 1; j <= 20; j++)
{
val += Math.Sin((2 * j - 1) * angle) / (2 * j - 1);
}
command.SendCommand($"particle firework {pos.X - i * 0.05} {pos.Y + val * 4} {pos.Z} 0 0 0 0 1");
}
三角波のフーリエ級数展開
ソースコード
for (int i = -360; i <= 360; i++)
{
double angle = Math.PI * i / 180;
double val = 0.0;
for (int j = 1; j <= 20; j++)
{
if (j % 2 == 0)
{
val += Math.Sin((2 * j - 1) * angle) / Math.Pow((2 * j - 1), 2);
}
else
{
val -= Math.Sin((2 * j - 1) * angle) / Math.Pow((2 * j - 1), 2);
}
}
command.SendCommand($"particle firework {pos.X - i * 0.05} {pos.Y + val * 4} {pos.Z} 0 0 0 0 1");
}