implement sounds

This commit is contained in:
LabyStudio
2022-02-13 07:55:40 +01:00
parent 82ea74085b
commit c955fdc7f9
42 changed files with 209 additions and 2 deletions
@@ -62,6 +62,11 @@ window.GameWindow = class {
// Mouse buttons
document.addEventListener('click', function (event) {
// Create sound engine (It has to be created after user interaction)
if(!minecraft.soundManager.isCreated()) {
minecraft.soundManager.create(minecraft.worldRenderer);
}
// Handle in-game mouse click
minecraft.onMouseClicked(event.button);
+21 -2
View File
@@ -45,6 +45,9 @@ window.Minecraft = class {
this.world = new World(this);
this.worldRenderer.scene.add(this.world.group);
// Create sound manager
this.soundManager = new SoundManager();
// Create player
this.player = new Player(this, this.world);
this.inventory = new Inventory();
@@ -200,7 +203,19 @@ window.Minecraft = class {
// Destroy block
if (button === 0) {
if (hitResult != null) {
this.world.setBlockAt(hitResult.x, hitResult.y, hitResult.z, 0);
// Get previous block
let typeId = this.world.getBlockAt(hitResult.x, hitResult.y, hitResult.z);
let block = Block.getById(typeId);
if (typeId !== 0) {
let soundName = block.getSound().getBreakSound();
// Play sound
this.soundManager.playSound(soundName, hitResult.x + 0.5, hitResult.y + 0.5, hitResult.z + 0.5, 1.0);
// Destroy block
this.world.setBlockAt(hitResult.x, hitResult.y, hitResult.z, 0);
}
}
}
@@ -227,13 +242,17 @@ window.Minecraft = class {
if (!placedBoundingBox.intersects(this.player.boundingBox)) {
let typeId = this.inventory.getItemInSelectedSlot();
if (typeId !== 0) {
// Place block
this.world.setBlockAt(x, y, z, typeId);
// Handle block abilities
let block = Block.getById(typeId);
block.onBlockPlaced(this.world, x, y, z, hitResult.face);
// Play sound
let sound = block.getSound();
let soundName = sound.getStepSound();
this.soundManager.playSound(soundName, hitResult.x + 0.5, hitResult.y + 0.5, hitResult.z + 0.5, sound.getPitch() * 0.8);
}
}
}
@@ -43,6 +43,9 @@ window.Player = class {
this.prevFovModifier = 0;
this.fovModifier = 0;
this.timeFovChanged = 0;
this.distanceWalked = 0;
this.nextStepDistance = 0;
}
respawn() {
@@ -242,6 +245,9 @@ window.Player = class {
travel(forward, vertical, strafe) {
let prevSlipperiness = this.getBlockSlipperiness() * 0.91;
let prevX = this.x;
let prevZ = this.z;
let value = 0.16277136 / (prevSlipperiness * prevSlipperiness * prevSlipperiness);
let friction;
@@ -268,6 +274,28 @@ window.Player = class {
this.motionX *= slipperiness;
this.motionY *= 0.98;
this.motionZ *= slipperiness;
let blockX = MathHelper.floor_double(this.x);
let blockY = MathHelper.floor_double(this.y - 0.2);
let blockZ = MathHelper.floor_double(this.z);
let typeId = this.world.getBlockAt(blockX, blockY, blockZ);
let distanceX = this.x - prevX;
let distanceZ = this.z - prevZ;
// Step sound
this.distanceWalked += Math.sqrt(distanceX * distanceX + distanceZ * distanceZ) * 0.6;
if (this.distanceWalked > this.nextStepDistance && typeId !== 0) {
this.nextStepDistance++;
let block = Block.getById(typeId);
let sound = block.getSound();
// Play sound
if (!block.isLiquid()) {
this.minecraft.soundManager.playSound(sound.getStepSound(), this.x, this.y, this.z, sound.getPitch());
}
}
}
getBlockSlipperiness() {
@@ -0,0 +1,88 @@
window.SoundManager = class {
constructor() {
this.audioLoader = new THREE.AudioLoader();
this.audioListener = null;
this.soundPool = [];
}
create(worldRenderer) {
this.scene = worldRenderer.scene;
this.audioListener = new THREE.AudioListener();
worldRenderer.camera.add(this.audioListener);
// Load initial sound pool
for (let i in Block.sounds) {
let sound = Block.sounds[i];
// Load sound types
this.loadSoundPool(sound.getStepSound());
}
}
loadSoundPool(name) {
let pool = [];
let amount = 4;
// Load all sounds into pool
let path = name.replace(".", "/");
for (let i = 0; i < amount; i++) {
let sound = this.loadSound('src/resources/sound/' + path + (i + 1) + '.ogg');
pool.push(sound);
}
// Register sound pool
this.soundPool[name] = pool;
}
loadSound(path) {
let scope = this;
// Create sound
let sound = new THREE.PositionalAudio(this.audioListener);
sound.setRefDistance(0.1);
sound.setRolloffFactor(6);
sound.setFilter(sound.context.createBiquadFilter());
// Load sound
this.audioLoader.load(path, function (buffer) {
sound.setBuffer(buffer);
scope.scene.add(sound);
});
return sound;
}
playSound(name, x, y, z, pitch) {
let pool = this.soundPool[name];
if (typeof pool === "undefined") {
// Load sound pool
this.loadSoundPool(name);
} else if (pool.length > 0) {
// Play random sound in pool
let sound = pool[Math.floor(Math.random() * pool.length)];
// Stop previous sound
if (sound.isPlaying) {
sound.stop();
}
// Update position
sound.position.set(x, y, z);
// Update pitch
sound.filters[0].frequency.setValueAtTime(12000 * pitch, sound.context.currentTime);
// Play sound
sound.play();
}
}
isCreated() {
return !(this.audioListener === null);
}
}
@@ -2,7 +2,18 @@ window.Block = class {
static blocks = new Map();
static sounds = {};
static create() {
// Sounds
Block.sounds.stone = new Sound("stone", 1.0);
Block.sounds.wood = new Sound("wood", 1.0);
Block.sounds.gravel = new Sound("gravel", 1.0);
Block.sounds.grass = new Sound("grass", 1.0);
Block.sounds.cloth = new Sound("cloth", 1.0);
Block.sounds.sand = new Sound("sand", 1.0);
// Blocks
Block.STONE = new BlockStone(1, 0);
Block.GRASS = new BlockGrass(2, 1);
Block.DIRT = new BlockDirt(3, 2);
@@ -17,8 +28,12 @@ window.Block = class {
this.id = id;
this.textureSlotId = textureSlotId;
// Bounding box
this.boundingBox = new BoundingBox(0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
// Default sound
this.sound = Block.sounds.stone;
// Register block
Block.blocks.set(id, this);
}
@@ -60,6 +75,14 @@ window.Block = class {
return true;
}
isLiquid() {
return false;
}
getSound() {
return this.sound;
}
getBoundingBox(world, x, y, z) {
return this.boundingBox;
}
@@ -2,6 +2,9 @@ window.BlockDirt = class extends Block {
constructor(id, textureSlotId) {
super(id, textureSlotId);
// Sound
this.sound = Block.sounds.gravel;
}
}
@@ -2,6 +2,9 @@ window.BlockGrass = class extends Block {
constructor(id, textureSlotId) {
super(id, textureSlotId);
// Sound
this.sound = Block.sounds.grass;
}
getTextureForFace(face) {
@@ -2,6 +2,9 @@ window.BlockLeave = class extends Block {
constructor(id, textureSlotId) {
super(id, textureSlotId);
// Sound
this.sound = Block.sounds.grass;
}
getOpacity() {
@@ -2,6 +2,9 @@ window.BlockLog = class extends Block {
constructor(id, textureSlotId) {
super(id, textureSlotId);
// Sound
this.sound = Block.sounds.wood;
}
getTextureForFace(face) {
@@ -2,6 +2,9 @@ window.BlockSand = class extends Block {
constructor(id, textureSlotId) {
super(id, textureSlotId);
// Sound
this.sound = Block.sounds.sand;
}
}
@@ -5,6 +5,9 @@ window.BlockTorch = class extends Block {
this.boundingBox = new BoundingBox(0.4, 0.0, 0.4, 0.6, 0.6, 0.6);
// Sound
this.sound = Block.sounds.wood;
// Create data faces
this.dataFaces = [
EnumBlockFace.WEST,
@@ -12,6 +12,10 @@ window.BlockWater = class extends Block {
return false;
}
isLiquid() {
return true;
}
canInteract() {
return false;
}
@@ -0,0 +1,20 @@
window.Sound = class {
constructor(name, pitch) {
this.name = name;
this.pitch = pitch;
}
getBreakSound() {
return "step." + this.name;
}
getStepSound() {
return "step." + this.name;
}
getPitch() {
return this.pitch;
}
}