function Player(soundEffects) { this.position = new Vector3(); this.lastPosition = new Vector3(); this.orientation = new Quaternion(); this.velocity = new Vector3(); this.pushVector = new Vector3(); this.onSurface = false; this.wasOnSurface = false; this.gravitationalStrength = 0.003; this.radius = 0.25; this.intendedPlanarVelocity = new Vector2(); this.surfaceControl = 0.01; this.airControl = 0.003; this.moveSpeed = 0.06; this.jumpForceY = 0.1; this.soundEffects = soundEffects; this.vbo = null; } Player.prototype.push = function(force) { this.pushVector.x += force.x; this.pushVector.y += force.y; this.pushVector.z += force.z; } Player.prototype.update = function() { var difference; var distance; var control; if (this.onSurface && (this.intendedPlanarVelocity.x != 0.0 || this.intendedPlanarVelocity.y != 0.0)) { if (this.intendedPlanarVelocity.x == 0.0) { if (this.intendedPlanarVelocity.y > 0.0) { this.orientation = Quaternion.fromAxisAngle(Vector3.up(), Math.PI); } else { this.orientation = new Quaternion(); } } else { var axis; var angle; var forward; forward = Vector2.withValues(0.0, -1.0); axis = Vector3.withValues(0.0, this.intendedPlanarVelocity.cross(forward), 0.0); angle = Math.acos(this.intendedPlanarVelocity.normalized().dot(forward)); this.orientation = Quaternion.fromAxisAngle(axis, angle); } } difference = Vector2.withValues(this.intendedPlanarVelocity.x - this.velocity.x, this.intendedPlanarVelocity.y - this.velocity.z); distance = difference.magnitude(); control = this.onSurface ? this.surfaceControl : this.airControl; if (distance > control) { difference.x /= distance; difference.y /= distance; difference.x *= control; difference.y *= control; } this.velocity.x += difference.x; this.velocity.z += difference.y; this.velocity.x += this.pushVector.x; this.velocity.y += this.pushVector.y; this.velocity.z += this.pushVector.z; this.pushVector.x = 0.0; this.pushVector.y = 0.0; this.pushVector.z = 0.0; this.velocity.y -= this.gravitationalStrength; this.lastPosition = this.position.copy(); this.position.x += this.velocity.x; this.position.y += this.velocity.y; this.position.z += this.velocity.z; this.wasOnSurface = this.onSurface; this.onSurface = false; } Player.prototype.platformCollision = function(platform) { if (!this.wasOnSurface) { this.soundEffects.play("land"); } this.position.y = platform.y; this.velocity.y = 0.0; this.onSurface = true; } Player.prototype.trampolineCollision = function(trampoline) { this.soundEffects.play("trampoline"); this.position.y = trampoline.y; this.velocity.y = trampoline.yforce; } Player.prototype.draw = function(gl) { var savedMatrix; if (this.vbo == null) { this.vbo = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo); gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray([-0.25,0.0, 0.25,0.0, 0.25,1.0, -0.25,1.0]), gl.STATIC_DRAW); this.ebo = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ebo); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new WebGLUnsignedShortArray([0, 1, 2, 2, 3, 0]), gl.STATIC_DRAW); this.indexCount = 6; } gl.enableVertexAttribArray(0); gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo); gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ebo); savedMatrix = gl.modelviewMatrix.copy(); gl.modelviewMatrix.translate(this.position.x, this.position.y, this.position.z); //gl.modelviewMatrix.multiply(this.orientation.toMatrix()); gl.uniform4f(gl.getUniformLocation(gl.program, "constantColor"), 0.0, 1.0, 0.0, 1.0); gl.uniformMatrix4fv(gl.getUniformLocation(gl.program, "uPMatrix"), false, new WebGLFloatArray(gl.projectionMatrix.m)); gl.uniformMatrix4fv(gl.getUniformLocation(gl.program, "uMVMatrix"), false, new WebGLFloatArray(gl.modelviewMatrix.m)); gl.drawElements(gl.TRIANGLES, this.indexCount, gl.UNSIGNED_SHORT, 0); gl.modelviewMatrix = savedMatrix; }