粒子与音效
给玩法加视觉和听觉反馈——粒子特效和音效。Bukkit 新旧两套 API 都能播,推荐用新的。
粒子效果
老方法:playEffect(不推荐)
java
loc.getWorld().playEffect(loc, Effect.HAPPY_VILLAGER, 1);Effect 枚举既含动效也含声效,是个老旧 API,常见枚举在新版被标记废弃。实际开发不常用。
新方法:spawnParticle(推荐)
新版 API 用 spawnParticle,配 Particle 枚举(与音效 Sound 分开):
java
Location loc = player.getLocation();
loc.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, loc, 10);
// 参数:粒子类型、位置、数量枚举跨版本会变
Particle、Sound 枚举在不同版本有变动(增删改名)。开发前确认目标版本有哪些枚举值,否则 ClassNotFoundException。
播放指定形状
粒子默认只在一个点喷出。要画圆、画线等形状,得逐点计算坐标、逐点播粒子。
示例:玩家脚底画一个圆环
以玩家脚底为原点建平面坐标系,圆是"到原点距离为半径 r 的点集"。遍历 0~360 度,用三角函数算每个点坐标:
java
Location loc = player.getLocation().clone();
double r = 1.0;
for (int t = 0; t < 360; t++) {
double rad = Math.toRadians(t); // 角度转弧度
double x = Math.cos(rad) * r;
double z = Math.sin(rad) * r;
loc.add(x, 0, z);
loc.getWorld().spawnParticle(Particle.VILLAGER_HAPPY, loc, 1, null);
loc.subtract(x, 0, z); // 加回去后减回来,保持原点
}通用思路
画任何形状都是三步:
- 数学分析:这个形状上的点满足什么方程(圆、直线、螺旋…)
- 坐标计算:遍历参数,用三角函数/参数方程算每个点坐标
- 逐点播粒子:在算出的坐标处
spawnParticle
性能注意
逐点播粒子数量大时吃性能。一个圆 360 个点就 360 次发包,别在主线程高频循环里画太复杂的形状。可用 runTaskTimer 降低频率,或减少点数(每隔几度取一个点)。
音效
新 API 用 playSound + Sound 枚举。World 和 Player 都有此方法——前者给范围内所有人听,后者只给指定玩家听:
java
// 给所有人听
world.playSound(loc, Sound.ENTITY_PLAYER_LEVELUP, 1.0f, 1.0f);
// 只给指定玩家听
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1.0f, 2.0f);参数:
| 参数 | 含义 |
|---|---|
| 位置 / 玩家 | 声源(playSound 重载不同) |
Sound | 音效枚举 |
volume | 音量(1.0 为正常,越大传得越远) |
pitch | 音调(0.5~2.0,1.0 正常) |
怎么找音效名
Sound 是枚举,IDE 点进去能看到全部(BLOCK_NOTE_BLOCK_PLING、ENTITY_PLAYER_LEVELUP、UI_BUTTON_CLICK 等)。游戏内也可装插件试听。
实战:技能释放特效
玩家右键释放技能时,脚底画圆 + 播放音效:
java
@EventHandler
public void onInteract(PlayerInteractEvent e) {
if (e.getAction() != Action.RIGHT_CLICK_AIR) return;
Player p = e.getPlayer();
// 脚底画圆
Location loc = p.getLocation().clone();
for (int t = 0; t < 360; t += 10) { // 每 10 度一个点,减少数量
double rad = Math.toRadians(t);
loc.add(Math.cos(rad), 0, Math.sin(rad));
loc.getWorld().spawnParticle(Particle.FLAME, loc, 1, null);
loc.subtract(Math.cos(rad), 0, Math.sin(rad));
}
// 音效
p.playSound(p.getLocation(), Sound.ENTITY_BLAZE_SHOOT, 1.0f, 1.0f);
}下一篇世界生成器。
