/** InfiniCraft * by Timothy Smith * * v. 4.0 * * I wanted to turn this into a puzzle, but the blocks * system wouldn't work very well for that. I'll keep trying, * though, and maybe things will work out. * * Use the arrow keys to walk. You can theoretically walk * FOREVER in any direction; the only limit is the amount of * memory in your computer. * * The character automatically jumps up small steps, but you * can jump manually by pressing and releasing the down * arrow. The longer you hold it down, the higher the * character jumps. * * Notice that you can tell which way the dude's facing, even * though he doesn't have a face. Things like that are * important in art. * * Eventually, I will make it possible for the guy to dig. * * * IDEAS: * -Turn him into a skateboarder. * -Add arms. * -Modify the world. */ frameRate(30); var frame = { c: 0, rate: 60, last: second(), cycle: function() { this.c++; if (this.last !== second()) { this.rate = this.c; this.c = 0; this.last = second(); } } }; // Type of character. Only 1 type so far. var dude_type = 1; // How fast character walks var speed = 3; // Position of character var x_pos = 0; // The x-position in pixels var y_pos = -15; // The y-position in pixels // The position, in block heights/widths var x_pos_b = 0; var y_pos_b = 0; //This variable represents the direction the character is facing. var direction = RIGHT; // How fast his legs swing: var angle_change = 3; //This is the angle of his legs. var angle = -27; // Initial speed of character var y_speed = -3; var x_speed = 0; // Strength of gravity var grav_strength = 0.4; var sky_color = color(156, 164, 255); //Block data var block_w = 30; var block_h = 30; var block_dots = []; for (var i = 0; i < 300; i++) { block_dots.push([round(random(2, block_w - 2)), round(random(2, block_h - 2)), random(0, 10)]); } /* The following array lists all the "exceptional" blocks, or the blocks that are out of the ordinary. Format: [x,y,type] type 0 = no block. 1 = lava block 2 = dirt+grass block 3 = clay block 4 = Grey stone block. 5 = White cloud 6 = Grey cloud */ var stoneBlock = function() { var image = createGraphics(block_w, block_h, JAVA2D); image.beginDraw(); image.stroke(61, 61, 61); image.fill(87, 76, 76); image.rect(0, 0, block_h-1, block_w-1); image.stroke(189, 189, 189, 25); image.strokeWeight(2); for (i = 0; i < 300; i++) { image.point(block_dots[i][0], block_dots[i][1]); } return image; }; var cloudBlock = function(type) { var image = createGraphics(block_w + 10, block_h + 10, JAVA2D); image.noStroke(); image.fill(sky_color); image.rect(0, 0, block_h, block_w); if (type === 1) { image.stroke(237, 237, 255, 50); } else { image.stroke(117, 117, 117, 80); } for (i = 0; i < block_dots.length; i++) { image.strokeWeight(1 + block_dots[i][2]/1.4); image.point(block_dots[i][0] * 1.1, block_dots[i][1]); } return image; }; var blocks = { stone: stoneBlock(), cloud_white: cloudBlock(1), cloud_grey: cloudBlock(2) }; var block_exc = [[1,0,0], [2,0,0], [3,0,0], [3,1,0], [4,0,0], [4,1,0], [4,2,0], [5,1,0], [5,2,0], [5,3,0], [5,4,0], [5,5,0], [6,2,0], [6,3,0], [4,4,0], [4,5,0], [4,6,0], [3,5,0], [3,6,0], [3,7,0], [2,6,0], [2,7,0], [2,8,0], [2,9,0], [2,10,0], [2,11,0], [2,12,0], [2,13,0], [2,14,0], [2,15,0], [2,16,0], [2,17,0], [2,18,0], [1,9,0], [1,10,0], [0,8,0], [0,9,0], [0,10,0], [-1,9,0], [-1,8,0], [-2,9,0], [-2,8,0], [-3,8,0], [-3,9,0], [-4,8,0], [-4,9,0], [-5,8,0], [-5,9,0], [-6,8,0], [-6,9,0], [-7,8,0], [-7,9,0], [-8,8,0], [-8,9,0], [-9,8,0], [-9,9,0], [-10,8,0], [-10,9,0], [-11,8,0], [-11,9,0], [-12,8,0], [-12,9,0], [-13,8,0], [-13,9,0], [-14,8,0], [-14,9,0], [-15,8,0], [-15,9,0], [-16,8,0], [-16,9,0], [-17,8,0], [-17,9,0], [-18,8,0], [-18,9,0], [-18,7,0], [-19,7,0], [-19,8,0], [-19,6,0], [-20,6,0], [-20,7,0], [-20,5,0], [-21,5,0], [-21,6,0], [-21,4,0], [-22,4,0], [-22,5,0], [-22,3,0], [-23,3,0], [-23,4,0], [-23,2,0], [-24,2,0], [-24,3,0], [-24,1,0], [-25,1,0], [-25,2,0], [-25,0,0], [-26,0,0], [-26,1,0], [-8,0,0], [-8,1,0], [-8,2,0], [-8,3,0], [-8,4,0], [-7,4,0], [-6,4,0], [-5,4,0], [-31,-1,2], [-31,-2,2], [-32,-1,2], [-32,-2,2], [-32,-3,2], [-32,-4,2], [-33,-1,2], [-33,-2,2], [-34,-1,2], [-34,-2,2], [-34,-3,2], [-34,-4,2], [-34,-8,0], [-35,-1,2], [-35,-2,2], [-35,-3,2], [-35,-4,2], [-35,-5,2], [-35,-6,2], [-35,-8,0], [-35,-9,0], [-36,-1,2], [-36,-2,2], [-36,-3,2], [-36,-4,2], [-36,-5,2], [-36,-6,2], [-36,-7,2], [-36,-8,2], [-36,-9,0], [-37,-1,2], [-37,-2,2], [-37,-3,2], [-37,-4,2], [-37,-5,2], [-37,-6,2], [-37,-7,2], [-37,-8,2], [-37,-9,2], [-37,-10,2]]; // Maximum jump strength var max_jump = 7; /********** End of tweakable zone *************/ // Jump height var jump = 0; // Remove a block var remove_block = 0; // Whether the character is falling var falling = false; // Variables that help with drawing the blocks var x_count = round(400/block_w); var hxc = round(x_count/2) + 1; var y_count = round(400/block_h); var hyc = round(y_count/2) + 1; var layer_count = 10; var layer_width = block_w / layer_count; var layer_height = block_h / layer_count; // Resets the matrix. var resetM = function() { resetMatrix(); translate(200, 200); }; resetM(); // Checks for an exception to the default ground texture var exception = function(x, y) { for (var iter = 0; iter < block_exc.length; iter++) { if (block_exc[iter][0] === x && block_exc[iter][1] === y) { return (iter); } else if (block_exc[iter][0] > x) { break; } } return (-1); }; // Draws a block var drawABlock = function(x, y, type) { var i; var b_x_pos = round(x*block_w - x_pos); var b_y_pos = round(y*block_w - y_pos) - 15; noStroke(); strokeWeight(1); switch (type) { case 0: // Sky fill(sky_color); rect(b_x_pos, b_y_pos, block_w, block_h); break; case 1: // Lava var factor = 255/layer_count - 5; for (var layer = 0; layer < layer_count; layer++) { fill((layer+5)*factor, 0, 0); rect(b_x_pos + layer_height*layer/2, b_y_pos+layer_width*layer/2, block_w - layer_height*layer, block_h - layer_height*layer, layer); } break; case 2: // Dirt & grass fill(115, 73, 22); rect(b_x_pos, b_y_pos, block_w, block_h); if (type === 2) { fill(0, 171, 0); rect(b_x_pos, b_y_pos, block_w, block_h/5.5); } noFill(); stroke(54, 54, 54); rect(b_x_pos, b_y_pos, block_w-1, block_h-1); break; case 3: // Clay stroke(41, 41, 41); fill(66, 48, 13); rect(b_x_pos, b_y_pos, block_h-1, block_w-1); break; case 4: // Rough grey stone image(blocks.stone, b_x_pos, b_y_pos); break; case 5: // White and grey clouds image(blocks.cloud_white, b_x_pos, b_y_pos); break; case 6: image(blocks.cloud_grey, b_x_pos, b_y_pos); break; } }; // Returns type of block in a given position var blockThere = function(xx, yy) { var n = exception(xx, yy); if (n !== -1) { return block_exc[n][2]; } else { if (yy >= -9 && yy < -7) { return 5; } else if (yy >= -7 && yy < 0 || yy < -7) { return 0; } else if (yy >= 0 && yy < 3) { return 2; } else if (yy >= 3 && yy < 10) { return 3; } else if (yy >= 10) { return 4; } } }; // Converts a given X-position into block-widths var sectionX = function(xx) { var sectX = round(xx / block_w); return sectX; }; // Converts a given Y-position into block-heights var sectionY = function(yy) { var sectY = round(yy / block_h); return sectY; }; // Draws the blocks on the screen var drawBlocks = function() { var x_pos_b = sectionX(x_pos); var y_pos_b = sectionY(y_pos); var l_edge = x_pos_b - hxc; var r_edge = x_pos_b + hxc; var u_edge = y_pos_b - hyc; var d_edge = y_pos_b + hyc; for (var draw_x = l_edge; draw_x < r_edge; draw_x++) { for (var draw_y = u_edge; draw_y < d_edge; draw_y++){ var x = draw_x; var y = draw_y; drawABlock(x, y, blockThere(x, y)); } } }; // Draws the character var drawCharacter = function() { strokeWeight(1); var squat = jump / max_jump * 10; var foot_x = 0; var torso_x = 0; var hat_angle = 0; if (direction === RIGHT) { foot_x = -3; torso_x = -1; hat_angle = -12; } else if (direction === LEFT) { foot_x = -7; torso_x = -1; hat_angle = 12; } // Head fill(212, 186, 146); stroke(163, 134, 91); rect(-2.5, -54 + squat, 13, 14, 23); stroke(0, 0, 0); // Hat fill(0, 0, 0); noStroke(); translate(4, -49 + squat - abs(y_speed/3)); rotate(hat_angle + (y_speed)); rect(-6, -9, 13, 8, 4); // Bowl rect(-10, -3, 21, 2, 2); // Rim resetM(); // Farther leg fill(71, 71, 255); translate(5, -19); rotate(angle); rect(-3, 0, 5, 16); // Leg fill(33, 33, 33); rect(foot_x, 14, 10, 3, 3); // Foot resetM(); // Closer leg fill(51, 51, 255); translate(7, -19); rotate(-angle); rect(-3, 0, 5, 16); // Leg fill(0, 0, 0); rect(foot_x, 14, 10, 3, 3); // Foot resetM(); // Body fill(186, 69, 69); stroke(173, 0, 0); rect(torso_x - (squat / 3), -39 + squat, 13 + (squat/2), 20 - (squat/2), 8); }; var inTheAir = function(x, y) { var yp = sectionY(y); if (blockThere(sectionX(x - block_w/2), yp) === 0 && blockThere(sectionX(x), yp) === 0) { return true; } else { return false; } }; var moveCharacter = function() { // If the character is not falling, but is in mid-air: if (falling === false && inTheAir(x_pos, y_pos)) { // Zap him to the ground. y_pos = (y_pos_b * block_h) + 15; // println((y_pos - 15) + ", " + (y_pos_b * block_h) + ", " + ((y_pos_b * block_h) - (y_pos - 15))); } // Update position. y_pos += y_speed; x_pos += x_speed; y_pos = round(y_pos); x_pos = round(x_pos); }; // Updates the character's speed var updateSpeed = function() { // If the character is in mid-air: if (inTheAir(x_pos, y_pos + (y_speed + grav_strength))) { // The following code is not executed if it will cause the character to fall into a block. y_speed += grav_strength; // The character falls downward x_speed *= 0.9; // The character's forward velocity is reduced falling = true; } else { // Once he touches down, his velocities are reset y_speed = 0; x_speed = 0; falling = false; } if (keyCode !== DOWN || !keyIsPressed) { if (!falling) { y_speed = -jump; } jump = 0; } // Update X-speed if (keyIsPressed) { var key = keyCode; // Key that's pressed // Make the guy's legs stop swinging forward, and start swinging backward if (angle > 30) { angle_change = -abs(angle_change); } else if (angle < -30) {angle_change = abs(angle_change); } // If guy is walking right if (key === RIGHT) { x_speed = speed; direction = RIGHT; } // If guy is walking left else if (key === LEFT) { x_speed = -speed; direction = LEFT; } if (key === RIGHT || key === LEFT) { angle += angle_change; // Legs angle } else if (key === DOWN) { if (jump < max_jump) { jump++; if (abs(angle) > 5) { angle *= (0.9); } } } } var y_sect = sectionY(y_pos-3); var front = (blockThere(sectionX(x_pos+x_speed), y_sect) !== 0 && direction === RIGHT); var back = (blockThere(sectionX(x_pos - 15 + x_speed), y_sect) !== 0 && direction === LEFT); var up_front = (blockThere(sectionX(x_pos+x_speed), y_sect-1) !== 0 && direction === RIGHT); var up_back = (blockThere(sectionX(x_pos - 15 +x_speed), y_sect-1) !== 0 && direction === LEFT); var offset; if (direction === LEFT) { offset = -15; } else { offset = 0; } // If the character hits the wall: if (front || back || up_front || up_back) { //If the character is on the ground and a jump will get him onto the wall: if (!inTheAir(x_pos, y_pos)) { if (blockThere(sectionX(x_pos + x_speed + offset), sectionY(y_pos-3)-1) === 0) { y_speed = -5; // He jumps upward } } x_speed = 0; // He doesn't move } }; var updateSect = function() { x_pos_b = round(x_pos / block_w); y_pos_b = round(y_pos / block_h); }; var blockSort = function() { var sort_method = function(a, b) { if (a[0] > b[0] || (a[0] === b[0] && a[1] > b[1])) { return 1; } else { return -1; } }; block_exc.sort(sort_method); }; blockSort(); var draw = function() { updateSect(); drawBlocks(); drawCharacter(); updateSpeed(); moveCharacter(); frame.cycle(); fill(255, 255, 255); text("Framerate: "+frame.rate, -185, -173); };