forked from FabricMC/fabric-docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
finished first iteration of dynamic sound page
- Loading branch information
Showing
21 changed files
with
729 additions
and
149 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file modified
BIN
+45.7 KB
(110%)
public/assets/develop/sounds/dynamic-sounds/custom-dynamic-sound-handling.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
reference/latest/src/client/java/com/example/docs/network/ReceiveS2C.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.example.docs.network; | ||
|
||
import net.minecraft.client.world.ClientWorld; | ||
import net.minecraft.sound.SoundCategory; | ||
|
||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; | ||
import com.example.docs.block.entity.custom.EngineBlockEntity; | ||
import com.example.docs.networking.payload.EngineSoundInstancePacket; | ||
import com.example.docs.sound.AbstractDynamicSoundInstance; | ||
import com.example.docs.sound.CustomSounds; | ||
import com.example.docs.sound.DynamicSoundManager; | ||
import com.example.docs.sound.instance.EngineSoundInstance; | ||
|
||
public class ReceiveS2C { | ||
static { | ||
ClientPlayNetworking.registerGlobalReceiver(EngineSoundInstancePacket.IDENTIFIER, ReceiveS2C::handleEngineSound); | ||
} | ||
|
||
// ::: 1 | ||
private static void handleEngineSound(EngineSoundInstancePacket packet, ClientPlayNetworking.Context context) { | ||
ClientWorld world = context.client().world; | ||
if (world == null) return; | ||
if (!(world.getBlockEntity(packet.blockEntityPos()) instanceof EngineBlockEntity engineBlockEntity)) return; | ||
|
||
DynamicSoundManager soundManager = DynamicSoundManager.getInstance(); | ||
|
||
if (packet.shouldStart()) { | ||
soundManager.play(new EngineSoundInstance(engineBlockEntity, | ||
CustomSounds.ENGINE_LOOP, SoundCategory.BLOCKS, | ||
60, 30, 1.2f, 0.8f, 1.4f, | ||
soundManager) | ||
); | ||
} else { | ||
soundManager.getPlayingSoundInstance(CustomSounds.ENGINE_LOOP).ifPresent(AbstractDynamicSoundInstance::end); | ||
} | ||
} | ||
// ::: 1 | ||
|
||
public static void initialize() { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 53 additions & 20 deletions
73
reference/latest/src/client/java/com/example/docs/sound/DynamicSoundManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,75 @@ | ||
package com.example.docs.sound; | ||
|
||
import net.minecraft.client.MinecraftClient; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
import net.minecraft.client.MinecraftClient; | ||
import net.minecraft.sound.SoundEvent; | ||
|
||
public class DynamicSoundManager { | ||
import com.example.docs.sound.instance.SoundInstanceCallback; | ||
|
||
private static DynamicSoundManager instance; | ||
// :::1 | ||
public class DynamicSoundManager implements SoundInstanceCallback { | ||
// An instance of the client to use Minecraft's default SoundManager | ||
private static final MinecraftClient client = MinecraftClient.getInstance(); | ||
|
||
private final List<? extends AbstractDynamicSoundInstance> activeSounds = new ArrayList<>(); | ||
// static field to store the current instance for the Singleton Design Pattern | ||
private static DynamicSoundManager instance; | ||
// The list which keeps track of all currently playing dynamic SoundInstances | ||
private final List<AbstractDynamicSoundInstance> activeSounds = new ArrayList<>(); | ||
|
||
private DynamicSoundManager() { | ||
// private constructor to make sure that the normal | ||
// instantiation of that object is not used externally | ||
} | ||
|
||
/** | ||
* This "Singleton Design Pattern" makes sure that, at runtime, | ||
* only one instance of this class can exist. | ||
* <p> | ||
* If this class has been used once already, it keeps its instance stored | ||
* in the static instance variable and return it.<br> | ||
* Otherwise, the instance variable is not initialized yet (null). | ||
* It will create a new instance, use it | ||
* and store it in the static variable for next uses. | ||
*/ | ||
// when accessing this class for the first time a new instance | ||
// is created and stored. If this is called again only the already | ||
// existing instance will be returned, instead of creating a new instance | ||
public static DynamicSoundManager getInstance() { | ||
if (instance == null) return new DynamicSoundManager(); | ||
if (instance == null) { | ||
instance = new DynamicSoundManager(); | ||
} | ||
return instance; | ||
} | ||
// :::1 | ||
|
||
// :::2 | ||
// Plays a sound instance, if it doesn't already exist in the list | ||
public <T extends AbstractDynamicSoundInstance> void play(T soundInstance) { | ||
if (this.activeSounds.contains(soundInstance)) return; | ||
|
||
client.getSoundManager().play(soundInstance); | ||
this.activeSounds.add(soundInstance); | ||
} | ||
|
||
// Stops a sound immediately. in most cases it is preferred to use | ||
// the sound's ending phase, which will clean it up after completion | ||
public <T extends AbstractDynamicSoundInstance> void stop(T soundInstance) { | ||
client.getSoundManager().stop(soundInstance); | ||
this.activeSounds.remove(soundInstance); | ||
} | ||
|
||
public void play(AbstractDynamicSoundInstance sound) { | ||
client.getSoundManager().play(sound); | ||
// Finds a SoundInstance from a SoundEvent, if it exists and is currently playing | ||
public Optional<AbstractDynamicSoundInstance> getPlayingSoundInstance(SoundEvent soundEvent) { | ||
for (var activeSound : this.activeSounds) { | ||
// SoundInstances use their SoundEvent's id by default | ||
if (activeSound.getId().equals(soundEvent.getId())) { | ||
return Optional.of(activeSound); | ||
} | ||
} | ||
return Optional.empty(); | ||
} | ||
// :::2 | ||
|
||
public void stop(AbstractDynamicSoundInstance sound) { | ||
// :::1 | ||
|
||
// This is where the callback signal of a finished custom SoundInstance will arrive. | ||
// For now, we can just stop and remove the sound from the list, but you can add | ||
// your own functionality too | ||
@Override | ||
public <T extends AbstractDynamicSoundInstance> void onFinished(T soundInstance) { | ||
this.stop(soundInstance); | ||
} | ||
} | ||
// :::1 |
5 changes: 0 additions & 5 deletions
5
reference/latest/src/client/java/com/example/docs/sound/TransitionState.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.