Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (function(w) {
- var ctx = document.getElementById("c").getContext("2d");
- var scale = w.innerHeight > w.innerWidth ? w.innerWidth : w.innerHeight;
- ctx.canvas.width = scale;
- ctx.canvas.height = scale;
- ctx.canvas.style = "position:fixed; left:25%; overflow:hidden;";
- var keys = [];
- var sprites = [];
- var platforms = [];
- var lcp = [null, null];
- var players = [];
- var frameCount = 0;
- var start = Date.now();
- var timer = 0;
- var checkpoints = 0;
- var player = {
- pos: [0, 0, -3],
- respawnPos: [0, 0, -3],
- size: [1, 1, 1],
- vel: [0, 0, 0],
- acc: [0, 0, 0],
- rot: 0,
- onGround: 0,
- oldOnGround: 0,
- id: Math.random()
- };
- var view = {
- pos: [0, -60, -3],
- rot: 0,
- rotX: -0.6
- };
- var objects = [["checkpoint", -10, -20, 0, false], ["checkpoint", -140, 35, -40, false], ["checkpoint", -140, 95, -40, false], ["checkpoint", 55, 125, -145, false], ["checkpoint", 30, 5, -145, false], ["checkpoint", 285, -5, -168, false], ["checkpoint", 85, -145, -55, false]];
- var s = new WebSocket("ws://xtoastx.website:3000");
- s.onmessage = function(m) {
- s.send(JSON.stringify(player));
- players = JSON.parse(m.data).filter((e) => {
- return e.id !== player.id;
- });
- }
- function lerpColor(a, b, c) {
- var d = "rgba(";
- a = a.substring(5).split(",");
- b = b.substring(5).split(",");
- for (var i = 0; i < 3; i++) {
- d += Math.round((lerp(parseInt(a[i]), parseInt(b[i]), c))).toString() + ", ";
- }
- return d + lerp(parseFloat(a[3]), parseFloat(b[3]), c).toString() + ")";
- }
- function map(a, b, c, d, f) {
- return d + (f - d) * ((a - b) / (c - b));
- }
- function lerp(a, b, c) {
- return (b - a) * c + a;
- }
- function constrain(a, b, c) {
- return a > c ? c : a < b ? b : a;
- }
- function random(a, b) {
- return Math.random() * (b - a) + a;
- }
- function color(a, b, c, d) {
- return "rgba(" + a + ", " + b + ", " + c + ", " + d + ")";
- }
- function alpha(a) {
- return a.split(",")[3];
- }
- function transform3D(x, y, z) {
- x -= view.pos[0];
- y -= view.pos[1];
- z -= view.pos[2];
- var s = Math.sin(view.rot);
- var c = Math.cos(view.rot);
- var tx = x * c - y * s;
- var ty = x * s + y * c;
- x = tx;
- y = ty;
- var s = Math.sin(view.rotX);
- var c = Math.cos(view.rotX);
- ty = y * c - z * s;
- var tz = y * s + z * c;
- y = ty;
- z = tz;
- y += 60;
- var d = y < 1 ? 1 : y
- var sx = (x / d) * scale + scale / 2;
- var sy = (z / d) * scale + scale / 2;
- return [sx, sy, x, y, z];
- }
- function vecCross(a, b) {
- return [
- a[1] * b[2] - a[2] * b[1],
- a[2] * b[0] - a[0] * b[2],
- a[0] * b[1] - a[1] * b[0]
- ];
- }
- function vecSub(a, b) {
- return [
- a[0] - b[0],
- a[1] - b[1],
- a[2] - b[2]
- ];
- }
- function vecDot(a, b) {
- return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
- }
- function vecNormalize(a) {
- var len = Math.hypot(a[0], a[1], a[2]);
- return [a[0] / len, a[1] / len, a[2] / len];
- }
- function quad3D(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, c) {
- var p1 = transform3D(x1, y1, z1);
- var p2 = transform3D(x2, y2, z2);
- var p3 = transform3D(x3, y3, z3);
- var p4 = transform3D(x4, y4, z4);
- if (p1[3] < 0.01 && p2[3] < 0.01 && p3[3] < 0.01 && p4[3] < 0.01) return;
- var normal = vecNormalize(vecCross(vecSub([p1[2], p1[3], p1[4]], [p2[2], p2[3], p2[4]]),
- vecSub([p1[2], p1[3], p1[4]], [p3[2], p3[3], p3[4]])));
- var offset = vecNormalize(vecSub([p1[2] + p2[2] + p3[2] + p4[2], p1[3] + p2[3] + p3[3] + p4[3], p1[4] + p2[4] + p3[4] + p4[4]], [0, 0, 0]));
- if (vecDot(offset, normal) < 0) return;
- var d = (z1 + z2 + z3 + z4) * 0.25;
- sprites.push(["quad", d, p1[0], p1[1], p2[0], p2[1], p3[0], p3[1], p4[0], p4[1], c, normal, offset]);
- }
- var box3D = function(x, y, z, w, h, d, c, rotation) {
- var sr = Math.sin(rotation) * 0.5;
- var cr = Math.cos(rotation) * 0.5;
- var center = [x + w * 0.5, y + h * 0.5, z + d * 0.5];
- var wO = [w * cr, -w * sr, 0];
- var hO = [h * sr, h * cr, 0];
- var dO = [0, 0, d * 0.5];
- function vert(wm, hm, dm) {
- wm = (wm ? 1 : -1);
- hm = (hm ? 1 : -1);
- dm = (dm ? 1 : -1);
- return [center[0] + wO[0] * wm + hO[0] * hm + dO[0] * dm,
- center[1] + wO[1] * wm + hO[1] * hm + dO[1] * dm,
- center[2] + wO[2] * wm + hO[2] * hm + dO[2] * dm];
- }
- function face(wm1, hm1, dm1, wm2, hm2, dm2, wm3, hm3, dm3, wm4, hm4, dm4) {
- var v1 = vert(wm1, hm1, dm1);
- var v2 = vert(wm2, hm2, dm2);
- var v3 = vert(wm3, hm3, dm3);
- var v4 = vert(wm4, hm4, dm4);
- quad3D(v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], v4[0], v4[1], v4[2], c);
- }
- face(false, false, false,
- false, true, false,
- false, true, true,
- false, false, true);
- face(true, true, false,
- true, false, false,
- true, false, true,
- true, true, true);
- face(true, false, false,
- false, false, false,
- false, false, true,
- true, false, true);
- face(false, true, false,
- true, true, false,
- true, true, true,
- false, true, true);
- face(false, false, true,
- false, true, true,
- true, true, true,
- true, false, true);
- face(false, true, false,
- false, false, false,
- true, false, false,
- true, true, false);
- }
- function collision3D(x1, y1, z1, w1, h1, d1, x2, y2, z2, w2, h2, d2) {
- if (x1 < x2 + w2 && x2 < x1 + w1) {
- if (y1 < y2 + h2 && y2 < y1 + h1) {
- return (z1 < z2 + d2 && z2 < z1 + h1)
- }
- }
- }
- function shadow(x, y, z, w, h) {
- var cp = null;
- var cz = 1000;
- for (var i = 0; i < platforms.length; i++) {
- var p = platforms[i];
- if (collision3D(p[0], p[1], p[2], p[3], p[4], p[5], x, y, z, w, h, 200)) {
- var pz = p[2] - 0.1;
- if (pz < z) continue;
- if (pz < cz) {
- cz = pz;
- cp = p;
- }
- }
- }
- if (cp) {
- var s = map(cz, z, z + 40, 0.5, -0.5);
- var mx = Math.max(x - s, cp[0]);
- var px = Math.min(x + w + s, cp[0] + cp[3]);
- var my = Math.max(y - s, cp[1]);
- var py = Math.min(y + h + s, cp[1] + cp[4]);
- quad3D(mx, my, cz,
- px, my, cz,
- px, py, cz,
- mx, py, cz, color(0, 0, 0, constrain(map(cz, z, z + 200, 0.6, 0)), 0, 1));
- }
- }
- function platform3D(x, y, z, w, h, d, c, px, py, pz) {
- box3D(x, y, z, w, h, d, c, 0);
- shadow(x, y, z, w, h);
- platforms.push([x, y, z, w, h, d, x - px, y - py, z - pz]);
- }
- function bobbingPlatform3D(x, y, z, w, h, d, c, cycle, offset, amount, axis) {
- var a = [x, y, z][axis];
- var pa = a + Math.sin(((frameCount - 1) / 100) * cycle + offset) * amount;
- a += Math.sin((frameCount / 100) * cycle + offset) * amount;
- var ppos = [x, y, z];
- ppos[axis] = pa;
- var pos = [x, y, z];
- pos[axis] = a;
- platform3D(pos[0], pos[1], pos[2], w, h, d, c, ppos[0], ppos[1], ppos[2]);
- }
- function doCollisions(axis, object) {
- var collided = false;
- object.pos[axis] += object.vel[axis];
- var vel = [0, 0, 0];
- var cp = null;
- var cpi = -1;
- for (var i = 0; i < platforms.length; i++) {
- var p = platforms[i];
- if (collision3D(object.pos[0] - object.size[0],
- object.pos[1] - object.size[1],
- object.pos[2] - object.size[2],
- object.size[0] * 2,
- object.size[1] * 2,
- object.size[2] * 2,
- p[0], p[1], p[2], p[3], p[4], p[5])) {
- if ((Math.abs(p[6]) + Math.abs(p[7]) + Math.abs(p[8])) > 0) {
- cp = p;
- cpi = i;
- }
- collided = true;
- }
- }
- if (axis === 2) {
- lcp.pop();
- lcp.unshift([cpi, collided]);
- for (var i = 0; i < lcp.length; i++) {
- if (lcp[i] !== null && lcp[i][0] !== -1 && lcp[i][1]) {
- cp = lcp[i];
- break;
- }
- }
- if (cp !== null && cp[0] !== null) {
- object.pos[0] += platforms[cp[0]][6];
- object.pos[1] += platforms[cp[0]][7];
- if (platforms[cp[0]][8] < 0) {
- object.pos[2] += platforms[cp[0]][8] * 1.1;
- } else {
- object.pos[2] += platforms[cp[0]][8] * 0.9;
- }
- }
- }
- if (collided) {
- object.pos[axis] -= object.vel[axis] * 1.01;
- object.vel[axis] = 0;
- return true;
- }
- }
- function playerDie() {
- player.pos[0] = player.respawnPos[0];
- player.pos[1] = player.respawnPos[1];
- player.pos[2] = player.respawnPos[2];
- player.vel = [0, 0, 0];
- }
- function draw() {
- w.requestAnimationFrame(draw);
- frameCount++;
- if (player.pos[2] > 5) playerDie();
- player.oldOnGround = player.onGround;
- player.onGround -= 0.2;
- player.vel[2] += 0.05;
- var s = Math.sin(view.rot);
- var c = Math.cos(view.rot);
- if (keys[87]) {
- player.acc[0] += s;
- player.acc[1] += c;
- }
- if (keys[83]) {
- player.acc[0] -= s;
- player.acc[1] -= c;
- }
- if (keys[65]) {
- player.acc[0] -= c;
- player.acc[1] += s;
- }
- if (keys[68]) {
- player.acc[0] += c;
- player.acc[1] -= s;
- }
- var len = Math.hypot(player.acc[0], player.acc[1]);
- if (len !== 0) {
- player.acc[0] /= len;
- player.acc[1] /= len;
- player.acc[0] *= 0.07;
- player.acc[1] *= 0.07;
- }
- player.vel[0] += player.acc[0];
- player.vel[1] += player.acc[1];
- player.acc = [0, 0, 0];
- if (keys[37]) player.rot -= 0.06;
- if (keys[39]) player.rot += 0.06;
- if (keys[38]) view.rotX -= 0.02;
- if (keys[40]) view.rotX += 0.02;
- player.vel[0] *= 0.9;
- player.vel[1] *= 0.9;
- doCollisions(0, player);
- doCollisions(1, player);
- if (doCollisions(2, player)) {
- player.onGround = 1;
- if (keys[32]) player.vel[2] = -1;
- }
- platforms = [];
- var rd = player.rot - view.rot;
- view.rot += rd * 0.12;
- if (keys[16]) {
- var v = view.rot % (Math.PI * 2);
- if (view.rot > 0) {
- if (v > 0.78 && v < 2.35) {
- view.rot = Math.PI / 2;
- player.rot = Math.PI / 2;
- } else if (v >= 2.35 && v < 3.92) {
- view.rot = Math.PI;
- player.rot = Math.PI;
- } else if (v >= 3.92 && v < 5.49) {
- view.rot = Math.PI / 2 + Math.PI;
- player.rot = Math.PI / 2 + Math.PI;
- } else {
- view.rot = 0;
- player.rot = 0;
- }
- } else {
- if (v < -0.78 && v > -2.35) {
- view.rot = -Math.PI / 2;
- player.rot = -Math.PI / 2;
- } else if (v <= -2.35 && v > -3.92) {
- view.rot = -Math.PI;
- player.rot = -Math.PI;
- } else if (v <= -3.92 && v > -5.49) {
- view.rot = -Math.PI / 2 - Math.PI;
- player.rot = -Math.PI / 2 - Math.PI;
- } else {
- view.rot = 0;
- player.rot = 0;
- }
- }
- }
- view.pos[0] = lerp(view.pos[0], player.pos[0], 0.05);
- view.pos[1] = lerp(view.pos[1], player.pos[1], 0.05);
- view.pos[2] = lerp(view.pos[2], player.pos[2] - 10, 0.05);
- ctx.fillStyle = "rgb(192, 240, 255)";
- ctx.fillRect(0, 0, scale, scale);
- platform3D(-1000, -1000, 10, 2000, 2000, 1, color(52, 52, 52, 1));
- if (checkpoints < 7) {
- // green
- platform3D(-50, -50, 0, 100, 100, 3, color(0, 255, 0, 1));
- bobbingPlatform3D(-80, -10, -8, 20, 10, 2, color(0, 255, 0, 1), Math.PI, Math.PI, 8, 0);
- bobbingPlatform3D(-80, -10, -16, 10, 20, 2, color(0, 255, 0, 1), Math.PI, 0, 8, 1);
- bobbingPlatform3D(-80, -10, -24, 20, 10, 2, color(0, 255, 0, 1), Math.PI, 0, 8, 0);
- platform3D(-100, -10, -30, 10, 60, 1, color(0, 255, 0, 1));
- platform3D(-120, 50, -36, 10, 30, 1, color(0, 255, 0, 1));
- platform3D(-145, 30, -40, 30, 10, 1, color(0, 0, 255, 1));
- platform3D(-145, 90, -40, 30, 10, 1, color(0, 225, 255, 1));
- // red
- for (var i = 0; i < 15; i++) {
- platform3D(50 + i * (30 - i), 0, -i * 5, 30 - i * 2, 30, 1, color(255, 0, 0, 1));
- }
- for (var i = 0; i < 15; i++) {
- if (i % 4 === 0) bobbingPlatform3D(280, 5, -70 - i * 7, 10, 20, 1, color(255, 0, 0, 1), Math.PI, 0, 15, 1);
- else if (i % 4 === 1) bobbingPlatform3D(275, 10, -70 - i * 7, 20, 10, 1, color(255, 0, 0, 1), Math.PI, 0, 15, 0);
- else if (i % 4 === 2) bobbingPlatform3D(280, 5, -70 - i * 7, 10, 20, 1, color(255, 0, 0, 1), Math.PI, Math.PI, 15, 1);
- else bobbingPlatform3D(275, 10, -70 - i * 7, 20, 10, 1, color(255, 0, 0, 1), Math.PI, Math.PI, 15, 0);
- }
- // blue
- bobbingPlatform3D(-145, 5, -90, 20, 20, 1, color(0, 0, 255, 1), 1, Math.PI, 50, 2);
- for (var i = 0; i < 20; i++) {
- platform3D(-145, 5 + (Math.sin(i / 2) * 20), -140 - i * 5, 8, 8, 1, color(0, 0, 255, 1));
- }
- bobbingPlatform3D(-90, -5, -240, 20, 20, 1, color(0, 0, 255, 1), 2, 0, 40, 0);
- platform3D(-5, -5, -185, 10, 10, 1, color(0, 0, 255, 1));
- platform3D(20, -5, -145, 20, 20, 1, color(0, 0, 255, 1));
- // teal
- bobbingPlatform3D(-145, 105, -90, 20, 20, 1, color(0, 255, 255, 1), 1, 0, 50, 2);
- platform3D(-145, 125, -140, 90, 2, 1, color(0, 255, 255, 1));
- for (var i = 0; i < 10; i++) {
- for (var j = 0; j < 5; j++) {
- if ((i + j) % 2 === 0) {
- bobbingPlatform3D(-40 + i * 8, 105 + j * 8, -140, 8, 8, 1, color(0, 255, 255, 1), 3, (i + j) / 4, 8, 2);
- }
- }
- }
- platform3D(45, 115, -145, 20, 20, 1, color(0, 255, 255, 1));
- } else {
- // yellow
- platform3D(-50, -50, 0, 100, 100, 3, color(255, 255, 0, 1));
- }
- // purple
- if (checkpoints > 5) {
- platform3D(0, -70, -5, 100, 10, 1, color(255, 0, 255, 1));
- platform3D(90, -160, -10, 9, 100, 1, color(255, 0, 255, 1));
- platform3D(0, -160, -15, 100, 8, 1, color(255, 0, 255, 1));
- platform3D(0, -160, -20, 7, 100, 1, color(255, 0, 255, 1));
- platform3D(0, -70, -25, 100, 6, 1, color(255, 0, 255, 1));
- platform3D(90, -160, -30, 5, 100, 1, color(255, 0, 255, 1));
- platform3D(0, -160, -35, 100, 4, 1, color(255, 0, 255, 1));
- platform3D(0, -160, -40, 3, 100, 1, color(255, 0, 255, 1));
- platform3D(0, -70, -45, 100, 2, 1, color(255, 0, 255, 1));
- platform3D(90, -160, -50, 1, 100, 1, color(255, 0, 255, 1));
- platform3D(80, -150, -55, 10, 10, 1, color(255, 0, 255, 1));
- }
- box3D(player.pos[0] - player.size[0], player.pos[1] - player.size[1], player.pos[2] - player.size[2] - 0.1, player.size[0] * 2, player.size[1] * 2, player.size[2] * 2, color(0, 178, 255, 1), player.rot);
- shadow(player.pos[0] - 1, player.pos[1] - 1, player.pos[2], 2, 2);
- for (var i of players) {
- box3D(i.pos[0] - i.size[0], i.pos[1] - i.size[1], i.pos[2] - i.size[2] - 0.1, i.size[0] * 2, i.size[1] * 2, i.size[2] * 2, color(240, 79, 84, 1), i.rot);
- shadow(i.pos[0] - 1, i.pos[1] - 1, i.pos[2], 2, 2);
- }
- if ((Math.abs(player.vel[0]) > 0.1 || Math.abs(player.vel[1]) > 0.1) && player.onGround > 0.5) objects.push(["dust", player.pos[0] + random(-1, 1), player.pos[1] + random(-1, 1), player.pos[2] + random(0.8, 1), 10, lcp[0][0]]);
- if (player.oldOnGround < -1 && player.onGround > 0) {
- for (var i = 0; i < 50; i++) {
- objects.push(["dust", player.pos[0] + random(-1, 1), player.pos[1] + random(-1, 1), player.pos[2] + random(0.8, 1), 8, lcp[0][0], random(-0.5, 0.5), random(-0.5, 0.5), 0]);
- }
- }
- for (var i = 0; i < objects.length; i++) {
- if (objects[i][0] === "checkpoint") {
- var sr = Math.sin(frameCount * 0.06) * 2;
- var cr = Math.cos(frameCount * 0.06) * 2;
- var c = color(255, 0, 0, 0.5 + Math.sin(frameCount * 0.05) / 3);
- if (objects[i][4]) c = color(0, 128, 0, 0.5 + Math.sin(frameCount * 0.05) / 3);
- else {
- objects.push(["checkpointEffect", objects[i][1] + sr, objects[i][2] + cr, objects[i][3] - 2.2, 0, 0, -0.5, 5]);
- objects.push(["checkpointEffect", objects[i][1] - sr, objects[i][2] - cr, objects[i][3] - 2.2, 0, 0, -0.5, 5]);
- }
- box3D(objects[i][1] - 2, objects[i][2] - 2, objects[i][3] - 2.2, 4, 4, 0.2, c, frameCount * 0.06);
- shadow(objects[i][1] - 2, objects[i][2] - 2, objects[i][3] - 4, 4, 4);
- if (collision3D(objects[i][1] - 2, objects[i][2] - 2, objects[i][3] - 6, 4, 4, 4, player.pos[0] - player.size[0], player.pos[1] - player.size[1], player.pos[2] - player.size[2], player.size[0] * 2, player.size[1] * 2, player.size[2] * 2)) {
- if (!objects[i][4]) checkpoints++;
- objects[i][4] = true;
- player.respawnPos = [objects[i][1], objects[i][2], objects[i][3] - 4];
- }
- } else if (objects[i][0] === "checkpointEffect") {
- var p = transform3D(objects[i][1], objects[i][2], objects[i][3]);
- if (p[3] > 0.5) sprites.push(["particle", objects[i][3], p[0], p[1], (objects[i][7] * 80) / p[3], color(255, 0, 255, map(objects[i][7], 5, 2, 1, 0))]);
- objects[i][1] += objects[i][4];
- objects[i][2] += objects[i][5];
- objects[i][3] += objects[i][6];
- objects[i][7] -= 0.1;
- if (objects[i][7] < 2) {
- objects.splice(i, 1);
- i--;
- continue;
- }
- } else if (objects[i][0] === "dust") {
- var p = transform3D(objects[i][1], objects[i][2], objects[i][3]);
- if (p[3] > 0.5) sprites.push(["particle", objects[i][3], p[0], p[1], objects[i][4], color(255, 255, 255, map(objects[i][4], 10, 5, 1, 0))]);
- if (objects[i][5] && platforms[objects[i][5]]) {
- objects[i][1] += platforms[objects[i][5]][6];
- objects[i][2] += platforms[objects[i][5]][7];
- objects[i][3] += platforms[objects[i][5]][8];
- }
- if (objects[i][6]) {
- objects[i][1] += objects[i][6];
- objects[i][2] += objects[i][7];
- objects[i][3] += objects[i][8];
- }
- objects[i][4] -= 0.25;
- if (objects[i][4] < 5) {
- objects.splice(i, 1);
- i--;
- continue;
- }
- }
- }
- sprites.sort(function(a, b) {
- return b[1] - a[1];
- });
- for (var i = 0; i < sprites.length; i++) {
- if (sprites[i][0] === "quad") {
- var d = vecDot(sprites[i][11], [0, 1, 0]);
- var cl = lerpColor(color(0, 0, 0, alpha(sprites[i][10])), sprites[i][10], constrain(d * 1.5, 0, 1));
- ctx.fillStyle = cl;
- ctx.strokeStyle = lerpColor(cl, "rgba(0, 0, 0, 1)", 0.25);
- ctx.beginPath();
- ctx.moveTo(sprites[i][2], sprites[i][3]);
- ctx.lineTo(sprites[i][4], sprites[i][5]);
- ctx.lineTo(sprites[i][6], sprites[i][7]);
- ctx.lineTo(sprites[i][8], sprites[i][9]);
- ctx.closePath();
- ctx.fill();
- ctx.stroke();
- } else if (sprites[i][0] === "particle") {
- ctx.fillStyle = sprites[i][5];
- ctx.beginPath();
- ctx.arc(sprites[i][2], sprites[i][3], sprites[i][4], 0, Math.PI * 2);
- ctx.fill();
- }
- }
- ctx.fillStyle = "rgb(0, 0, 0)";
- ctx.font = "15px Arial";
- ctx.textAlign = "left";
- ctx.fillText("Players: " + (players.length + 1), 10, 15);
- ctx.textAlign = "right";
- timer = checkpoints < 7 ? ((Date.now() - start) / 1000).toFixed(2) : timer;
- ctx.fillText("Seconds: " + timer, scale - 10, 15);
- ctx.fillText("Checkpoints grabbed: " + checkpoints, scale - 10, 30);
- sprites = [];
- }
- draw();
- w.addEventListener("keydown", function(e) {
- keys[e.keyCode] = true;
- });
- w.addEventListener("keyup", function(e) {
- keys[e.keyCode] = false;
- });
- })(window);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement