Willard21 / MineKhan

Minecraft for Khan Academy
81 stars 52 forks source link

A MOD adding music feature to the game, and a few useful commands #132

Open qfcy opened 10 months ago

qfcy commented 10 months ago

1.MOD In a bid to apply my MOD, you could modify the source code like this:

①Play music after entering the world.

class World {
        constructor(empty) {
            if (!empty) {
                setSeed(Math.random() * 2000000000 | 0)
            }

            PlayMusic() // ==CHANGE==
            generatedChunks = 0
            fogDist = 16

            //Initialize the world's arrays
            this.chunks = []
            this.loaded = []
            this.sortedChunks = []
            this.doubleRenderChunks = []

② Stop the music when returning to the main menu.

        Button.add(width / 2, 475, 300, 40, "Exit Without Saving", "pause", () => {
            // savebox.value = world.getSaveString()
            if (multiplayer) {
                multiplayer.close()
            }
            initWorldsMenu()
            stopMusic() // ==CHANGE==
            changeScene("main menu")
        })

③The main code above the window.onload method.

var source=null; // global var
// Tip: When directly opening an HTML file in your browser, it is impossible to play music due to the CORS policy. This can be resolved by running "Click to start game.py"as a local server with Python in my fork (github.com/qfcy/MineKhan-extended).
function PlayMusic(){
    var url='/music.ogg'; // Audio file
    window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext ||
    window.msAudioContext;
    try {
    var context = new window.AudioContext();;
    var audioBuffer = null;
    function playSound() {
        source = context.createBufferSource();
        source.buffer = audioBuffer;
        source.loop = true; // Loop
        source.connect(context.destination);
        source.start(0); // Play immediately
    }

    function initSound(arrayBuffer) {
        context.decodeAudioData(arrayBuffer, function (buffer) { // the callback when decode succeeds
        audioBuffer = buffer;
        playSound();
        }, function (e) { // the callback when decode fails
        console.log('Error decoding file', e);
        });
    }

    function loadAudioFile(url) {
        var xhr = new XMLHttpRequest(); // Download audio file through XHR
        xhr.open('GET', url, true);
        xhr.responseType = 'arraybuffer';
        xhr.onload = function (e) { // Download complete
        initSound(this.response);
        };
        xhr.send();
    }
    loadAudioFile(url);
    } catch (e) {
    console.log('!Your browser does not support AudioContext');
    }
}
function stopMusic(){
    try{
        source.stop()
    } catch(e) {}
}

// Original code from Minekhan
window.onload = async function() {

    var init = await MineKhan()
    if (window.parent.raf) {
        window.cancelAnimationFrame(window.parent.raf)
        console.log("Canceled", window.parent.raf)
    }
    init()
}

For the adapted source code,please refer to my fork github.com/qfcy/MineKhan-extended. Additionally,the original file of music.ogg is hal3.ogg. I hope my contribution could be valuable.

2.Some useful commands 👍 Although the game does not have a command feature, you can still use commands in the developer tool. Firstly, use F12 to open the developer tools of your browser, and switch to the Console tab to enter the commands.

Player player.x=n ; player.y=n ; player.z=n : Set the coordinates of a player. If you teleport yourself into an unloaded chunk, the game tick will stop. This could be resolved by exiting and re-entering the world. However, severe distance effects will occur at high coordinates, especially beyond X/Z: ±16384, as the rendering uses single-precision floating-point numbers. player.gravityStrength=n : Set the value of gravity. If the value is set to 0, the player will gain weightlessness. World world.tickCount=n : Adjust the time of the world. 0<n<=6000: Day. (This is different from Minecraft) 6000<n<=12000: Night.The value n beyond 12000 is also acceptable. Example: world.tickCount = 8000 world.setBlock(x,y,z,blockID,lazy,remote) : Place a block in the world, and it's recommended to set lazy and remote to false. The blockID of 0 refers to the air. You can use this to destroy any existing blocks. Example: world.setBlock(0, 0, 0, 0, false, false) However, destroying a block at the bedrock layer(y=0) will allow the player to fall into the void.

3.A few screenshots The void The void. The severely twisted world beyond X/Z:±8388608 The severely twisted world beyond X/Z:±8388608.

SpaceSoldier123 commented 2 months ago

Nice!