/** * Cuberunner * by Raphael Rouvinov-Kats * * Based on the popular flash game by Max Abernethy * * 3D learned from Peter Collinridge's tutorial at * http://www.petercollingridge.appspot.com/3D-tutorial * * Click to start/restart * Drag left/right to move left/right * * Your Goal: Avoid hitting the oncoming cubes for as long as possible! * * TODO: * Keeping cubes from overlapping * Clouds in pink mode * Black Mode * Having stars scroll * */ var speed = 5; var cubeFrequency = 1.2; var focalLength = 100; var heightAboveGround = 10; var playerDistanceFromScreen = 40; var cubeSpawnZ = 300; var cubeSpawnXBounds = 500; var cubeSize = 10; var playerWidth = 3; var focalLimiter = 0; var currentZrotation = 0; var maxRotation = 30; var rotationSensitivity = 0.025; var maxDx = 2; var dxSensitivity = 2; var cubeQueue = cubeFrequency; var inMainMenu = true; var gameOver = false; var score = 0; var nightMode = false; var pinkMode = false; var createCuboid = function(x, y, z, w, h, d) { var nodes = [[x, y, z ], [x, y, z+d], [x, y+h, z ], [x, y+h, z+d], [x+w, y, z ], [x+w, y, z+d], [x+w, y+h, z ], [x+w, y+h, z+d]]; var edges = [[0, 1], [1, 3], [2, 3], [2, 0], [4, 5], [5, 7], [6, 7], [6, 4], [0, 4], [1, 5], [2, 6], [3, 7]]; var faces = [[1, 5], [2, 6], [0, 2], [6, 4], [3, 7], [4, 0]]; var colour = color(255, random(0, 255), 0); return { 'nodes': nodes, 'edges': edges, 'faces':faces, 'colour':colour }; }; var cubes = []; var removeCubes = function() { var o = 0; while(o < cubes.length) { var removed = false; var obj = cubes[o]; var nodes = obj.nodes; for(var n = 0; n < nodes.length; n++) { if(nodes[n][2] < 0) { cubes.splice(o, 1); removed = true; break; } } if(!removed) { o++; } } }; // turns x/y and z values into x or y values on the focal plane (canvas) var foc = function(xOrY, z) { return focalLength * xOrY / z; }; var rotateZ3D = function(theta, nodes) { var sin_t = sin(theta); var cos_t = cos(theta); for (var n=0; n= x1 && px <= x2 && pz >= z1 && pz <= z2) { gameOver = true; } } } // color mode, speed/cube frequency/spawn z adjustments if(score % 900 < 300) { if(pinkMode === true || nightMode === true) { speed++; cubeSpawnZ += 7; focalLength -= 5; } nightMode = false; pinkMode = false; } else if(score % 900 < 600) { if(nightMode === false) { speed++; cubeSpawnZ += 7; focalLength -= 5; } nightMode = true; pinkMode = false; } else { if(pinkMode === false) { speed++; cubeSpawnZ += 7; cubeFrequency = min(2, cubeFrequency + 0.5); focalLength -= 5; } nightMode = false; pinkMode = true; } pushMatrix(); translate(200, 200); // draw stars in night mode if(nightMode) { stroke(21, 138, 24); strokeWeight(5); rotateZ3D(currentZrotation, stars); for(var s = 0; s < stars.length; s++) { var sfx = foc(stars[s][0], stars[s][2]); var sfy = foc(stars[s][1], stars[s][2]); point(sfx, sfy); } rotateZ3D(-currentZrotation, stars); strokeWeight(1); } // draw ground noStroke(); fill(166, 166, 166); if(nightMode) { fill(0, 0, 0); } if(pinkMode) { fill(255, 255, 255); } rotateZ3D(currentZrotation, ground); quad(ground[0][0], ground[0][1], ground[1][0], ground[1][1], ground[2][0], ground[2][1], ground[3][0], ground[3][1]); rotateZ3D(-currentZrotation, ground); // draw player if(!inMainMenu) { stroke(0, 0, 0); fill(89, 89, 89); if(gameOver) { // fade player after game over var timeSinceGameOver = frameCount - scoreStartTime - score; stroke(0, 0, 0, 255 - min(254, 10*timeSinceGameOver)); fill(89, 89, 89, 255 - min(254, 10*timeSinceGameOver)); } var p1fx = foc(p[0][0], p[0][2]); var p1fy = foc(p[0][1], p[0][2]); var p2fx = foc(p[1][0], p[1][2]); var p2fy = foc(p[1][1], p[1][2]); var p3fx = foc(p[2][0], p[2][2]); var p3fy = foc(p[2][1], p[2][2]); triangle(p1fx, p1fy, p2fx, p2fy, p3fx, p3fy); } // draw each object noStroke(); var obj, nodes, edges, faces; for (obj=0; obj 300 && score % 300 < 30) { text("SPEED UP", 150, 150); } // for testing //text("first x: " + cubes[0].nodes[0][0], 5, 353); //text("first y: " + cubes[0].nodes[0][1], 5, 373); //text("first z: " + cubes[0].nodes[0][2], 5, 393); //text("fx: "+focalLength*cubes[0].nodes[0][0]/cubes[0].nodes[0][2], 170, 353); //text("fy: "+focalLength*cubes[0].nodes[0][1]/cubes[0].nodes[0][2], 170, 373); //text("cubes: " + cubes.length, 5, 333); //text("zrot: " + currentZrotation, 5, 333); }; var mouseDragged = function() { var dx = mouseX - pmouseX; dx *= dxSensitivity; // limit dx if(abs(dx) > maxDx) { var dxSign = dx/abs(dx); dx = maxDx * dxSign; } // var dy = mouseY - pmouseY; // rotate each object for (var obj=0; obj maxRotation) { // 30 degree angle max var currentZrotationSign = currentZrotation/abs(currentZrotation); currentZrotation = maxRotation * currentZrotationSign; } } }; var mouseClicked = function() { if(inMainMenu) { inMainMenu = false; gameOver = false; scoreStartTime = frameCount; cubes = []; } else if(gameOver) { inMainMenu = false; gameOver = false; cubes = []; scoreStartTime = frameCount; } };