Wall Sliding Demo

HTML

<p>Use the arrow keys to move around. Hold shift to run.</p>

<canvas id="c" width="480" height="480" />

<script id="vs" type="x-shader/x-vertex">
    attribute vec2 a_position;

    void main() {
        gl_Position = vec4(a_position, 0, 1);
    }
</script>

<script id="fs" type="x-shader/x-fragment">
    precision mediump float;
    void main() {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
</script>

JavaScript

// I'm using the default OpenGL coordinate system, where (-1, -1) is the bottom-left corner and (1, 1) is the top-right corner. Just because.

var WALL_COUNT = 30;
var MAX_WALL_LENGTH = 0.4;
var PLAYER_SIZE = 0.05;
var SPEED_WALKING = 0.01;
var SPEED_RUNNING = 0.02;

var KEY_SHIFT = 16;
var KEY_LEFT = 37;
var KEY_UP = 38;
var KEY_RIGHT = 39;
var KEY_DOWN = 40;

var pressedKeys = {};
var canvas = document.getElementById('c');
var gl = canvas.getContext("experimental-webgl");
var vertexPositionAttribute;
var position = [0, 0];
var walls = [];

function init() {
    initWalls();
    initInput();
    initShaders();
}

function initWalls() {
    var playerPolygon = getSquare(position, PLAYER_SIZE);
    for (var i = 0; i < WALL_COUNT; i += 1) {
        var start = subtractVectors(randomVector(2, 2), [1, 1]);
        var delta = subtractVectors(randomVector(MAX_WALL_LENGTH * 2, MAX_WALL_LENGTH * 2), [MAX_WALL_LENGTH, MAX_WALL_LENGTH]);
        var end = addVectors(start, delta);
        var wall = [start, end];
        if (!polygonsIntersect(playerPolygon, wall)) {
            walls.push(wall);
        }
    }
}

function initInput() {
    window.addEventListener("keydown", function(e) {
        pressedKeys[e.keyCode] = true;
    });
    window.addEventListener("keyup", function(e) {
        delete pressedKeys[e.keyCode];
    });
}

function initShaders() {
    var vsCode = document.querySelector("#vs").textContent;
    var vs = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vs, vsCode);
    gl.compileShader(vs);
	
    var fsCode = document.querySelector("#fs").textContent;
    var fs = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fs, fsCode);
    gl.compileShader(fs);
    
    var program = gl.createProgram();
    gl.attachShader(program, vs);
    gl.attachShader(program, fs);
    gl.linkProgram(program);
    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
        alert("Could not initialise shaders");
    }
    gl.useProgram(program);
    
...