elve 0.0.1

engine for browser games (WIP)
Documentation
<!DOCTYPE html>
<meta charset="utf-8">
<body>
    <canvas id="game" width="1024" height="1024"></canvas>
    <script type="module">
        import initElve from './pkg/elve.js';

        initElve().then(api => {
            console.log("API", api);
            init();
        });


        function init() {
            function check({shader, program} = {}) {
            const err = gl.getError();
            if (err) console.log("ERR",err);
            if (shader) {
                const info = gl.getShaderInfoLog(shader);
                if (info) console.log(info)
            }
            if (program) {
                const info = gl.getProgramInfoLog(program);
                if (info) console.log(info);
            }
        }
        const shaderSources = {
            VERTEX_SHADER: `
            attribute vec2 aPosition;
            void main() {
                gl_Position = vec4(aPosition, 0.0, 1.0);
                gl_PointSize = 4.;
            }
            `,
            FRAGMENT_SHADER:  `
            void main() {
                gl_FragColor = vec4(1.0, 1.0, 0.0, 0.2);
            }
            `,
        };
        const canvas = document.getElementById('game');
        const gl = canvas.getContext('webgl2');

        const shaders = Object.fromEntries(Object.entries(shaderSources).map(([k, source]) => {
            const shader = gl.createShader(gl[k]);
            check({shader});
            gl.shaderSource(shader, source);
            check({shader});
            gl.compileShader(shader);
            check({shader});
            return [k.split('_')[0].toLowerCase(), shader];
        }));

        gl.enable(gl.BLEND);
        gl.blendFunc(gl.SRC_ALPHA, 1.0);
        const program = gl.createProgram();
        check({program});
        gl.attachShader(program, shaders.fragment);
        check({program});
        gl.attachShader(program, shaders.vertex);
        check({program});
        console.log("SHADERS", shaders);
        gl.linkProgram(program);
        check({program});


        const buffer = gl.createBuffer();
        check({program});
        gl.useProgram(program);
        check({program});


        const count = 1300;
        const componentsPerVertex = 2;
        const velocities = new Float32Array(count * componentsPerVertex);
        const particles =  new Float32Array(count * componentsPerVertex);
        let center;
        function randomize(i) {
            
            let angle = Math.random() * Math.PI * 2;
            
            let speed = Math.random() * 0.0056;

            velocities[i * componentsPerVertex] = center.x + speed * Math.cos(angle) + Math.sin(angle * 0.2 * speed) * 0.01;
            velocities[i * componentsPerVertex + 1] = center.y + speed * Math.sin(angle) + Math.cos(angle) * 0.04 + 0.14;

            {
                let angle = Math.random() * Math.PI * 2;
                let speed = Math.random() * 0.01 + 0.04;
                particles[i * componentsPerVertex] = speed * Math.cos(angle);
                particles[i * componentsPerVertex + 1] = -0.5 + speed * Math.sin(angle);

            }
        }
        for (let i = 0; i < count; i++) {
            let angle = Math.random() * Math.PI * 2;
            
            let speed = Math.random() * 0.0056;

            velocities[i * componentsPerVertex] = speed * Math.cos(angle) + Math.sin(angle * 0.2 * speed) * 0.01;
            velocities[i * componentsPerVertex + 1] = speed * Math.sin(angle) + Math.cos(angle) * 0.01 + 0.02;

            {
                let angle = Math.random() * Math.PI * 2;
                let speed = Math.random() * 0.01 + 0.04;
                particles[i * componentsPerVertex] = speed * Math.cos(angle);
                particles[i * componentsPerVertex + 1] = -0.5 + speed * Math.sin(angle);

            }

        }
        function render() {
            gl.clearColor(0.1, 0.0, 0.1, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);

            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
            gl.bufferData(gl.ARRAY_BUFFER, particles, gl.DYNAMIC_DRAW);

            const aPosition = gl.getAttribLocation(program, 'aPosition');
            gl.vertexAttribPointer(aPosition, componentsPerVertex, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(aPosition);

            gl.drawArrays(gl.POINTS, 0, count);

        }
        
        let angle = 0.0;
        (function update() {
            for (let i = 0; i < count; i++) {
                const idx = i * componentsPerVertex;

                const speed = 0.4;
                particles[idx] += velocities[idx] * speed;
                particles[idx + 1] += velocities[idx + 1] * speed;
                velocities[idx + 1] -= 0.00029;


            }
            {
                center = {x: (Math.random() - 0.5) * 0.1, y: (Math.random() - 0.5) * 0.1};
                for (let i = 0; i < 100; i++) {
                    const rnd = ~~(Math.random() * count);
                    randomize(rnd);

                }

            }
            angle += 0.1;
            particles[0] = Math.cos(angle);
            render();
            requestAnimationFrame(update);
        })();
        


        }



    </script>
</body>