├── 3dminecraft.html ├── FileSaver.js ├── LICENSE ├── PointerLockControls.js ├── README.md ├── cursor.png ├── minecraftfont.woff ├── minecraftlogo.png ├── perlin.js ├── stats.js ├── texture ├── brick │ └── brick.png ├── cobblestone │ └── cobblestone.png ├── dirt │ ├── customdirt.png │ └── dirt.png ├── glass │ └── glass.png ├── grass │ ├── bottom.jpg │ ├── side.jpg │ └── top.jpg ├── oakLeaves │ ├── oakLeaves.png │ └── oakLeavesTransparent.png ├── oakLog │ ├── bottom.jpg │ ├── side.png │ └── top.jpg ├── plank │ └── plank.png ├── sand │ └── sand.png ├── stone │ └── stone.png ├── texture.png └── water │ └── water.jpeg ├── three.js └── titleScreen ├── five.jpeg ├── four.jpeg ├── one.jpeg ├── six.jpeg ├── three.jpeg └── two.jpeg /3dminecraft.html: -------------------------------------------------------------------------------- 1 | 51 | 52 | 53 | 54 | 3D Minecraft 55 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 |
159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 |
171 | 172 | 173 |
174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 |
188 | 189 | 190 |
191 |
192 | 193 | 194 |
195 | 196 | 2022 | 2023 | 2024 | -------------------------------------------------------------------------------- /FileSaver.js: -------------------------------------------------------------------------------- 1 | /* 2 | * FileSaver.js 3 | * A saveAs() FileSaver implementation. 4 | * 5 | * By Eli Grey, http://eligrey.com 6 | * 7 | * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT) 8 | * source : http://purl.eligrey.com/github/FileSaver.js 9 | */ 10 | 11 | // The one and only way of getting global scope in all environments 12 | // https://stackoverflow.com/q/3277182/1008999 13 | var _global = typeof window === 'object' && window.window === window 14 | ? window : typeof self === 'object' && self.self === self 15 | ? self : typeof global === 'object' && global.global === global 16 | ? global 17 | : this 18 | 19 | function bom (blob, opts) { 20 | if (typeof opts === 'undefined') opts = { autoBom: false } 21 | else if (typeof opts !== 'object') { 22 | console.warn('Deprecated: Expected third argument to be a object') 23 | opts = { autoBom: !opts } 24 | } 25 | 26 | // prepend BOM for UTF-8 XML and text/* types (including HTML) 27 | // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF 28 | if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { 29 | return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type }) 30 | } 31 | return blob 32 | } 33 | 34 | function download (url, name, opts) { 35 | var xhr = new XMLHttpRequest() 36 | xhr.open('GET', url) 37 | xhr.responseType = 'blob' 38 | xhr.onload = function () { 39 | saveAs(xhr.response, name, opts) 40 | } 41 | xhr.onerror = function () { 42 | console.error('could not download file') 43 | } 44 | xhr.send() 45 | } 46 | 47 | function corsEnabled (url) { 48 | var xhr = new XMLHttpRequest() 49 | // use sync to avoid popup blocker 50 | xhr.open('HEAD', url, false) 51 | try { 52 | xhr.send() 53 | } catch (e) {} 54 | return xhr.status >= 200 && xhr.status <= 299 55 | } 56 | 57 | // `a.click()` doesn't work for all browsers (#465) 58 | function click (node) { 59 | try { 60 | node.dispatchEvent(new MouseEvent('click')) 61 | } catch (e) { 62 | var evt = document.createEvent('MouseEvents') 63 | evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 64 | 20, false, false, false, false, 0, null) 65 | node.dispatchEvent(evt) 66 | } 67 | } 68 | 69 | // Detect WebView inside a native macOS app by ruling out all browsers 70 | // We just need to check for 'Safari' because all other browsers (besides Firefox) include that too 71 | // https://www.whatismybrowser.com/guides/the-latest-user-agent/macos 72 | var isMacOSWebView = _global.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent) 73 | 74 | var saveAs = _global.saveAs || ( 75 | // probably in some web worker 76 | (typeof window !== 'object' || window !== _global) 77 | ? function saveAs () { /* noop */ } 78 | 79 | // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView 80 | : ('download' in HTMLAnchorElement.prototype && !isMacOSWebView) 81 | ? function saveAs (blob, name, opts) { 82 | var URL = _global.URL || _global.webkitURL 83 | var a = document.createElement('a') 84 | name = name || blob.name || 'download' 85 | 86 | a.download = name 87 | a.rel = 'noopener' // tabnabbing 88 | 89 | // TODO: detect chrome extensions & packaged apps 90 | // a.target = '_blank' 91 | 92 | if (typeof blob === 'string') { 93 | // Support regular links 94 | a.href = blob 95 | if (a.origin !== location.origin) { 96 | corsEnabled(a.href) 97 | ? download(blob, name, opts) 98 | : click(a, a.target = '_blank') 99 | } else { 100 | click(a) 101 | } 102 | } else { 103 | // Support blobs 104 | a.href = URL.createObjectURL(blob) 105 | setTimeout(function () { URL.revokeObjectURL(a.href) }, 4E4) // 40s 106 | setTimeout(function () { click(a) }, 0) 107 | } 108 | } 109 | 110 | // Use msSaveOrOpenBlob as a second approach 111 | : 'msSaveOrOpenBlob' in navigator 112 | ? function saveAs (blob, name, opts) { 113 | name = name || blob.name || 'download' 114 | 115 | if (typeof blob === 'string') { 116 | if (corsEnabled(blob)) { 117 | download(blob, name, opts) 118 | } else { 119 | var a = document.createElement('a') 120 | a.href = blob 121 | a.target = '_blank' 122 | setTimeout(function () { click(a) }) 123 | } 124 | } else { 125 | navigator.msSaveOrOpenBlob(bom(blob, opts), name) 126 | } 127 | } 128 | 129 | // Fallback to using FileReader and a popup 130 | : function saveAs (blob, name, opts, popup) { 131 | // Open a popup immediately do go around popup blocker 132 | // Mostly only available on user interaction and the fileReader is async so... 133 | popup = popup || open('', '_blank') 134 | if (popup) { 135 | popup.document.title = 136 | popup.document.body.innerText = 'downloading...' 137 | } 138 | 139 | if (typeof blob === 'string') return download(blob, name, opts) 140 | 141 | var force = blob.type === 'application/octet-stream' 142 | var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari 143 | var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent) 144 | 145 | if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && typeof FileReader !== 'undefined') { 146 | // Safari doesn't allow downloading of blob URLs 147 | var reader = new FileReader() 148 | reader.onloadend = function () { 149 | var url = reader.result 150 | url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;') 151 | if (popup) popup.location.href = url 152 | else location = url 153 | popup = null // reverse-tabnabbing #460 154 | } 155 | reader.readAsDataURL(blob) 156 | } else { 157 | var URL = _global.URL || _global.webkitURL 158 | var url = URL.createObjectURL(blob) 159 | if (popup) popup.location = url 160 | else location.href = url 161 | popup = null // reverse-tabnabbing #460 162 | setTimeout(function () { URL.revokeObjectURL(url) }, 4E4) // 40s 163 | } 164 | } 165 | ) 166 | 167 | _global.saveAs = saveAs.saveAs = saveAs 168 | 169 | if (typeof module !== 'undefined') { 170 | module.exports = saveAs; 171 | } 172 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 HritikRC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PointerLockControls.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author Mugen87 / https://github.com/Mugen87 4 | */ 5 | 6 | THREE.PointerLockControls = function ( camera, domElement ) { 7 | 8 | if ( domElement === undefined ) { 9 | 10 | console.warn( 'THREE.PointerLockControls: The second parameter "domElement" is now mandatory.' ); 11 | domElement = document.body; 12 | 13 | } 14 | 15 | this.domElement = domElement; 16 | this.isLocked = false; 17 | 18 | // 19 | // internals 20 | // 21 | 22 | var scope = this; 23 | 24 | var changeEvent = { type: 'change' }; 25 | var lockEvent = { type: 'lock' }; 26 | var unlockEvent = { type: 'unlock' }; 27 | 28 | var euler = new THREE.Euler( 0, 0, 0, 'YXZ' ); 29 | 30 | var PI_2 = Math.PI / 2; 31 | 32 | var vec = new THREE.Vector3(); 33 | 34 | function onMouseMove( event ) { 35 | 36 | if ( scope.isLocked === false ) return; 37 | 38 | var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; 39 | var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; 40 | 41 | euler.setFromQuaternion( camera.quaternion ); 42 | 43 | euler.y -= movementX * 0.002; 44 | euler.x -= movementY * 0.002; 45 | 46 | euler.x = Math.max( - PI_2, Math.min( PI_2, euler.x ) ); 47 | 48 | camera.quaternion.setFromEuler( euler ); 49 | 50 | scope.dispatchEvent( changeEvent ); 51 | 52 | } 53 | 54 | function onPointerlockChange() { 55 | 56 | if ( document.pointerLockElement === scope.domElement ) { 57 | 58 | scope.dispatchEvent( lockEvent ); 59 | 60 | scope.isLocked = true; 61 | 62 | } else { 63 | 64 | scope.dispatchEvent( unlockEvent ); 65 | 66 | scope.isLocked = false; 67 | 68 | } 69 | 70 | } 71 | 72 | function onPointerlockError() { 73 | 74 | console.error( 'THREE.PointerLockControls: Unable to use Pointer Lock API' ); 75 | 76 | } 77 | 78 | this.connect = function () { 79 | 80 | document.addEventListener( 'mousemove', onMouseMove, false ); 81 | document.addEventListener( 'pointerlockchange', onPointerlockChange, false ); 82 | document.addEventListener( 'pointerlockerror', onPointerlockError, false ); 83 | 84 | }; 85 | 86 | this.disconnect = function () { 87 | 88 | document.removeEventListener( 'mousemove', onMouseMove, false ); 89 | document.removeEventListener( 'pointerlockchange', onPointerlockChange, false ); 90 | document.removeEventListener( 'pointerlockerror', onPointerlockError, false ); 91 | 92 | }; 93 | 94 | this.dispose = function () { 95 | 96 | this.disconnect(); 97 | 98 | }; 99 | 100 | this.getObject = function () { // retaining this method for backward compatibility 101 | 102 | return camera; 103 | 104 | }; 105 | 106 | this.getDirection = function () { 107 | 108 | var direction = new THREE.Vector3( 0, 0, - 1 ); 109 | 110 | return function ( v ) { 111 | 112 | return vec.copy( direction ).applyQuaternion( camera.quaternion ); 113 | 114 | }; 115 | 116 | }(); 117 | 118 | this.moveForward = function ( distance ) { 119 | 120 | // move forward parallel to the xz-plane 121 | // assumes camera.up is y-up 122 | 123 | vec.setFromMatrixColumn( camera.matrix, 0 ); 124 | 125 | vec.crossVectors( camera.up, vec ); 126 | 127 | camera.position.addScaledVector( vec, distance ); 128 | 129 | }; 130 | 131 | this.moveRight = function ( distance ) { 132 | 133 | vec.setFromMatrixColumn( camera.matrix, 0 ); 134 | 135 | camera.position.addScaledVector( vec, distance ); 136 | 137 | }; 138 | 139 | this.lock = function () { 140 | 141 | this.domElement.requestPointerLock(); 142 | 143 | }; 144 | 145 | this.unlock = function () { 146 | 147 | document.exitPointerLock(); 148 | 149 | }; 150 | 151 | this.connect(); 152 | 153 | }; 154 | 155 | THREE.PointerLockControls.prototype = Object.create( THREE.EventDispatcher.prototype ); 156 | THREE.PointerLockControls.prototype.constructor = THREE.PointerLockControls; 157 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Minecraft 2 | All the files for the youtube series, "How to Code Minecraft in Javascript" are located here! 3 | 4 | Goal: Build a spinoff of Minecraft in the web, using HTML, CSS and Javascript, from scratch. This project involves some really interesting algorithms and concepts, some of which are listed below. 5 | - Procedural Terrain Generation 6 | - Perlin Noise 7 | - THREE.js 8 | - Infinite Terrain Generation 9 | - Raycasting 10 | - 3D Character Movement 11 | - 3D Collision Detection 12 | - Loading and Saving Files 13 | 14 | Info: 15 | - Over 2 year project 16 | - Youtube series of tutorials starting from the very beginning 17 | - Has gained a lot of views and promotion 18 | 19 | 20 | Steps: 21 | 1) You can download the latest code from the series from here. 22 | 2) Download the whole repository as a zip or just as a folder. 23 | 3) If you download it as a ZIP, you will need to extract it. 24 | 4) Then, just open the folder and click on the 3dminecraft.html to open the minecraft program. 25 | 5) If you also want to play with textures, you have to run the file as a server. For that, watch part 4 of the youtube series (link below)! 26 | 27 | NOTE! 28 | - Make sure to open the minecraft.html file as a server! 29 | - Inlcude the license or credit this project for any commerical use! 30 | 31 | If you have any questions, please ask either here, discord or in youtube. 32 | - Find me in youtube at Hritik RC: https://www.youtube.com/c/hritikrc 33 | - Playlist for the minecraft series: https://www.youtube.com/playlist?list=PLEtXCX1lakbhq_01JKJILx90wLfdwrJig 34 | - Discord Server: https://discord.gg/tCEhtAwVvS 35 | 36 | Thanks for the support! :) 37 | -------------------------------------------------------------------------------- /cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/cursor.png -------------------------------------------------------------------------------- /minecraftfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/minecraftfont.woff -------------------------------------------------------------------------------- /minecraftlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/minecraftlogo.png -------------------------------------------------------------------------------- /perlin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * A speed-improved perlin and simplex noise algorithms for 2D. 3 | * 4 | * Based on example code by Stefan Gustavson (stegu@itn.liu.se). 5 | * Optimisations by Peter Eastman (peastman@drizzle.stanford.edu). 6 | * Better rank ordering method by Stefan Gustavson in 2012. 7 | * Converted to Javascript by Joseph Gentle. 8 | * 9 | * Version 2012-03-09 10 | * 11 | * This code was placed in the public domain by its original author, 12 | * Stefan Gustavson. You may use it as you see fit, but 13 | * attribution is appreciated. 14 | * 15 | */ 16 | 17 | (function(global){ 18 | var module = global.noise = {}; 19 | 20 | function Grad(x, y, z) { 21 | this.x = x; this.y = y; this.z = z; 22 | } 23 | 24 | Grad.prototype.dot2 = function(x, y) { 25 | return this.x*x + this.y*y; 26 | }; 27 | 28 | Grad.prototype.dot3 = function(x, y, z) { 29 | return this.x*x + this.y*y + this.z*z; 30 | }; 31 | 32 | var grad3 = [new Grad(1,1,0),new Grad(-1,1,0),new Grad(1,-1,0),new Grad(-1,-1,0), 33 | new Grad(1,0,1),new Grad(-1,0,1),new Grad(1,0,-1),new Grad(-1,0,-1), 34 | new Grad(0,1,1),new Grad(0,-1,1),new Grad(0,1,-1),new Grad(0,-1,-1)]; 35 | 36 | var p = [151,160,137,91,90,15, 37 | 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, 38 | 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, 39 | 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, 40 | 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, 41 | 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, 42 | 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, 43 | 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, 44 | 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, 45 | 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, 46 | 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, 47 | 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, 48 | 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180]; 49 | // To remove the need for index wrapping, double the permutation table length 50 | var perm = new Array(512); 51 | var gradP = new Array(512); 52 | 53 | // This isn't a very good seeding function, but it works ok. It supports 2^16 54 | // different seed values. Write something better if you need more seeds. 55 | module.seed = function(seed) { 56 | if(seed > 0 && seed < 1) { 57 | // Scale the seed out 58 | seed *= 65536; 59 | } 60 | 61 | seed = Math.floor(seed); 62 | if(seed < 256) { 63 | seed |= seed << 8; 64 | } 65 | 66 | for(var i = 0; i < 256; i++) { 67 | var v; 68 | if (i & 1) { 69 | v = p[i] ^ (seed & 255); 70 | } else { 71 | v = p[i] ^ ((seed>>8) & 255); 72 | } 73 | 74 | perm[i] = perm[i + 256] = v; 75 | gradP[i] = gradP[i + 256] = grad3[v % 12]; 76 | } 77 | }; 78 | 79 | module.seed(0); 80 | 81 | /* 82 | for(var i=0; i<256; i++) { 83 | perm[i] = perm[i + 256] = p[i]; 84 | gradP[i] = gradP[i + 256] = grad3[perm[i] % 12]; 85 | }*/ 86 | 87 | // Skewing and unskewing factors for 2, 3, and 4 dimensions 88 | var F2 = 0.5*(Math.sqrt(3)-1); 89 | var G2 = (3-Math.sqrt(3))/6; 90 | 91 | var F3 = 1/3; 92 | var G3 = 1/6; 93 | 94 | // 2D simplex noise 95 | module.simplex2 = function(xin, yin) { 96 | var n0, n1, n2; // Noise contributions from the three corners 97 | // Skew the input space to determine which simplex cell we're in 98 | var s = (xin+yin)*F2; // Hairy factor for 2D 99 | var i = Math.floor(xin+s); 100 | var j = Math.floor(yin+s); 101 | var t = (i+j)*G2; 102 | var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed. 103 | var y0 = yin-j+t; 104 | // For the 2D case, the simplex shape is an equilateral triangle. 105 | // Determine which simplex we are in. 106 | var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords 107 | if(x0>y0) { // lower triangle, XY order: (0,0)->(1,0)->(1,1) 108 | i1=1; j1=0; 109 | } else { // upper triangle, YX order: (0,0)->(0,1)->(1,1) 110 | i1=0; j1=1; 111 | } 112 | // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and 113 | // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where 114 | // c = (3-sqrt(3))/6 115 | var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords 116 | var y1 = y0 - j1 + G2; 117 | var x2 = x0 - 1 + 2 * G2; // Offsets for last corner in (x,y) unskewed coords 118 | var y2 = y0 - 1 + 2 * G2; 119 | // Work out the hashed gradient indices of the three simplex corners 120 | i &= 255; 121 | j &= 255; 122 | var gi0 = gradP[i+perm[j]]; 123 | var gi1 = gradP[i+i1+perm[j+j1]]; 124 | var gi2 = gradP[i+1+perm[j+1]]; 125 | // Calculate the contribution from the three corners 126 | var t0 = 0.5 - x0*x0-y0*y0; 127 | if(t0<0) { 128 | n0 = 0; 129 | } else { 130 | t0 *= t0; 131 | n0 = t0 * t0 * gi0.dot2(x0, y0); // (x,y) of grad3 used for 2D gradient 132 | } 133 | var t1 = 0.5 - x1*x1-y1*y1; 134 | if(t1<0) { 135 | n1 = 0; 136 | } else { 137 | t1 *= t1; 138 | n1 = t1 * t1 * gi1.dot2(x1, y1); 139 | } 140 | var t2 = 0.5 - x2*x2-y2*y2; 141 | if(t2<0) { 142 | n2 = 0; 143 | } else { 144 | t2 *= t2; 145 | n2 = t2 * t2 * gi2.dot2(x2, y2); 146 | } 147 | // Add contributions from each corner to get the final noise value. 148 | // The result is scaled to return values in the interval [-1,1]. 149 | return 70 * (n0 + n1 + n2); 150 | }; 151 | 152 | // 3D simplex noise 153 | module.simplex3 = function(xin, yin, zin) { 154 | var n0, n1, n2, n3; // Noise contributions from the four corners 155 | 156 | // Skew the input space to determine which simplex cell we're in 157 | var s = (xin+yin+zin)*F3; // Hairy factor for 2D 158 | var i = Math.floor(xin+s); 159 | var j = Math.floor(yin+s); 160 | var k = Math.floor(zin+s); 161 | 162 | var t = (i+j+k)*G3; 163 | var x0 = xin-i+t; // The x,y distances from the cell origin, unskewed. 164 | var y0 = yin-j+t; 165 | var z0 = zin-k+t; 166 | 167 | // For the 3D case, the simplex shape is a slightly irregular tetrahedron. 168 | // Determine which simplex we are in. 169 | var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords 170 | var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords 171 | if(x0 >= y0) { 172 | if(y0 >= z0) { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } 173 | else if(x0 >= z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } 174 | else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } 175 | } else { 176 | if(y0 < z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; } 177 | else if(x0 < z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; } 178 | else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; } 179 | } 180 | // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z), 181 | // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and 182 | // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where 183 | // c = 1/6. 184 | var x1 = x0 - i1 + G3; // Offsets for second corner 185 | var y1 = y0 - j1 + G3; 186 | var z1 = z0 - k1 + G3; 187 | 188 | var x2 = x0 - i2 + 2 * G3; // Offsets for third corner 189 | var y2 = y0 - j2 + 2 * G3; 190 | var z2 = z0 - k2 + 2 * G3; 191 | 192 | var x3 = x0 - 1 + 3 * G3; // Offsets for fourth corner 193 | var y3 = y0 - 1 + 3 * G3; 194 | var z3 = z0 - 1 + 3 * G3; 195 | 196 | // Work out the hashed gradient indices of the four simplex corners 197 | i &= 255; 198 | j &= 255; 199 | k &= 255; 200 | var gi0 = gradP[i+ perm[j+ perm[k ]]]; 201 | var gi1 = gradP[i+i1+perm[j+j1+perm[k+k1]]]; 202 | var gi2 = gradP[i+i2+perm[j+j2+perm[k+k2]]]; 203 | var gi3 = gradP[i+ 1+perm[j+ 1+perm[k+ 1]]]; 204 | 205 | // Calculate the contribution from the four corners 206 | var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0; 207 | if(t0<0) { 208 | n0 = 0; 209 | } else { 210 | t0 *= t0; 211 | n0 = t0 * t0 * gi0.dot3(x0, y0, z0); // (x,y) of grad3 used for 2D gradient 212 | } 213 | var t1 = 0.6 - x1*x1 - y1*y1 - z1*z1; 214 | if(t1<0) { 215 | n1 = 0; 216 | } else { 217 | t1 *= t1; 218 | n1 = t1 * t1 * gi1.dot3(x1, y1, z1); 219 | } 220 | var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2; 221 | if(t2<0) { 222 | n2 = 0; 223 | } else { 224 | t2 *= t2; 225 | n2 = t2 * t2 * gi2.dot3(x2, y2, z2); 226 | } 227 | var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3; 228 | if(t3<0) { 229 | n3 = 0; 230 | } else { 231 | t3 *= t3; 232 | n3 = t3 * t3 * gi3.dot3(x3, y3, z3); 233 | } 234 | // Add contributions from each corner to get the final noise value. 235 | // The result is scaled to return values in the interval [-1,1]. 236 | return 32 * (n0 + n1 + n2 + n3); 237 | 238 | }; 239 | 240 | // ##### Perlin noise stuff 241 | 242 | function fade(t) { 243 | return t*t*t*(t*(t*6-15)+10); 244 | } 245 | 246 | function lerp(a, b, t) { 247 | return (1-t)*a + t*b; 248 | } 249 | 250 | // 2D Perlin Noise 251 | module.perlin2 = function(x, y) { 252 | // Find unit grid cell containing point 253 | var X = Math.floor(x), Y = Math.floor(y); 254 | // Get relative xy coordinates of point within that cell 255 | x = x - X; y = y - Y; 256 | // Wrap the integer cells at 255 (smaller integer period can be introduced here) 257 | X = X & 255; Y = Y & 255; 258 | 259 | // Calculate noise contributions from each of the four corners 260 | var n00 = gradP[X+perm[Y]].dot2(x, y); 261 | var n01 = gradP[X+perm[Y+1]].dot2(x, y-1); 262 | var n10 = gradP[X+1+perm[Y]].dot2(x-1, y); 263 | var n11 = gradP[X+1+perm[Y+1]].dot2(x-1, y-1); 264 | 265 | // Compute the fade curve value for x 266 | var u = fade(x); 267 | 268 | // Interpolate the four results 269 | return lerp( 270 | lerp(n00, n10, u), 271 | lerp(n01, n11, u), 272 | fade(y)); 273 | }; 274 | 275 | // 3D Perlin Noise 276 | module.perlin3 = function(x, y, z) { 277 | // Find unit grid cell containing point 278 | var X = Math.floor(x), Y = Math.floor(y), Z = Math.floor(z); 279 | // Get relative xyz coordinates of point within that cell 280 | x = x - X; y = y - Y; z = z - Z; 281 | // Wrap the integer cells at 255 (smaller integer period can be introduced here) 282 | X = X & 255; Y = Y & 255; Z = Z & 255; 283 | 284 | // Calculate noise contributions from each of the eight corners 285 | var n000 = gradP[X+ perm[Y+ perm[Z ]]].dot3(x, y, z); 286 | var n001 = gradP[X+ perm[Y+ perm[Z+1]]].dot3(x, y, z-1); 287 | var n010 = gradP[X+ perm[Y+1+perm[Z ]]].dot3(x, y-1, z); 288 | var n011 = gradP[X+ perm[Y+1+perm[Z+1]]].dot3(x, y-1, z-1); 289 | var n100 = gradP[X+1+perm[Y+ perm[Z ]]].dot3(x-1, y, z); 290 | var n101 = gradP[X+1+perm[Y+ perm[Z+1]]].dot3(x-1, y, z-1); 291 | var n110 = gradP[X+1+perm[Y+1+perm[Z ]]].dot3(x-1, y-1, z); 292 | var n111 = gradP[X+1+perm[Y+1+perm[Z+1]]].dot3(x-1, y-1, z-1); 293 | 294 | // Compute the fade curve value for x, y, z 295 | var u = fade(x); 296 | var v = fade(y); 297 | var w = fade(z); 298 | 299 | // Interpolate 300 | return lerp( 301 | lerp( 302 | lerp(n000, n100, u), 303 | lerp(n001, n101, u), w), 304 | lerp( 305 | lerp(n010, n110, u), 306 | lerp(n011, n111, u), w), 307 | v); 308 | }; 309 | 310 | })(this); 311 | -------------------------------------------------------------------------------- /stats.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | (global.Stats = factory()); 5 | }(this, (function () { 'use strict'; 6 | 7 | /** 8 | * @author mrdoob / http://mrdoob.com/ 9 | */ 10 | 11 | var Stats = function () { 12 | 13 | var mode = 0; 14 | 15 | var container = document.createElement( 'div' ); 16 | container.style.cssText = 'position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000'; 17 | container.addEventListener( 'click', function ( event ) { 18 | 19 | event.preventDefault(); 20 | showPanel( ++ mode % container.children.length ); 21 | 22 | }, false ); 23 | 24 | // 25 | 26 | function addPanel( panel ) { 27 | 28 | container.appendChild( panel.dom ); 29 | return panel; 30 | 31 | } 32 | 33 | function showPanel( id ) { 34 | 35 | for ( var i = 0; i < container.children.length; i ++ ) { 36 | 37 | container.children[ i ].style.display = i === id ? 'block' : 'none'; 38 | 39 | } 40 | 41 | mode = id; 42 | 43 | } 44 | 45 | // 46 | 47 | var beginTime = ( performance || Date ).now(), prevTime = beginTime, frames = 0; 48 | 49 | var fpsPanel = addPanel( new Stats.Panel( 'FPS', '#0ff', '#002' ) ); 50 | var msPanel = addPanel( new Stats.Panel( 'MS', '#0f0', '#020' ) ); 51 | 52 | if ( self.performance && self.performance.memory ) { 53 | 54 | var memPanel = addPanel( new Stats.Panel( 'MB', '#f08', '#201' ) ); 55 | 56 | } 57 | 58 | showPanel( 0 ); 59 | 60 | return { 61 | 62 | REVISION: 16, 63 | 64 | dom: container, 65 | 66 | addPanel: addPanel, 67 | showPanel: showPanel, 68 | 69 | begin: function () { 70 | 71 | beginTime = ( performance || Date ).now(); 72 | 73 | }, 74 | 75 | end: function () { 76 | 77 | frames ++; 78 | 79 | var time = ( performance || Date ).now(); 80 | 81 | msPanel.update( time - beginTime, 200 ); 82 | 83 | if ( time >= prevTime + 1000 ) { 84 | 85 | fpsPanel.update( ( frames * 1000 ) / ( time - prevTime ), 100 ); 86 | 87 | prevTime = time; 88 | frames = 0; 89 | 90 | if ( memPanel ) { 91 | 92 | var memory = performance.memory; 93 | memPanel.update( memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576 ); 94 | 95 | } 96 | 97 | } 98 | 99 | return time; 100 | 101 | }, 102 | 103 | update: function () { 104 | 105 | beginTime = this.end(); 106 | 107 | }, 108 | 109 | // Backwards Compatibility 110 | 111 | domElement: container, 112 | setMode: showPanel 113 | 114 | }; 115 | 116 | }; 117 | 118 | Stats.Panel = function ( name, fg, bg ) { 119 | 120 | var min = Infinity, max = 0, round = Math.round; 121 | var PR = round( window.devicePixelRatio || 1 ); 122 | 123 | var WIDTH = 80 * PR, HEIGHT = 48 * PR, 124 | TEXT_X = 3 * PR, TEXT_Y = 2 * PR, 125 | GRAPH_X = 3 * PR, GRAPH_Y = 15 * PR, 126 | GRAPH_WIDTH = 74 * PR, GRAPH_HEIGHT = 30 * PR; 127 | 128 | var canvas = document.createElement( 'canvas' ); 129 | canvas.width = WIDTH; 130 | canvas.height = HEIGHT; 131 | canvas.style.cssText = 'width:80px;height:48px'; 132 | 133 | var context = canvas.getContext( '2d' ); 134 | context.font = 'bold ' + ( 9 * PR ) + 'px Helvetica,Arial,sans-serif'; 135 | context.textBaseline = 'top'; 136 | 137 | context.fillStyle = bg; 138 | context.fillRect( 0, 0, WIDTH, HEIGHT ); 139 | 140 | context.fillStyle = fg; 141 | context.fillText( name, TEXT_X, TEXT_Y ); 142 | context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT ); 143 | 144 | context.fillStyle = bg; 145 | context.globalAlpha = 0.9; 146 | context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT ); 147 | 148 | return { 149 | 150 | dom: canvas, 151 | 152 | update: function ( value, maxValue ) { 153 | 154 | min = Math.min( min, value ); 155 | max = Math.max( max, value ); 156 | 157 | context.fillStyle = bg; 158 | context.globalAlpha = 1; 159 | context.fillRect( 0, 0, WIDTH, GRAPH_Y ); 160 | context.fillStyle = fg; 161 | context.fillText( round( value ) + ' ' + name + ' (' + round( min ) + '-' + round( max ) + ')', TEXT_X, TEXT_Y ); 162 | 163 | context.drawImage( canvas, GRAPH_X + PR, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT, GRAPH_X, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT ); 164 | 165 | context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, GRAPH_HEIGHT ); 166 | 167 | context.fillStyle = bg; 168 | context.globalAlpha = 0.9; 169 | context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, round( ( 1 - ( value / maxValue ) ) * GRAPH_HEIGHT ) ); 170 | 171 | } 172 | 173 | }; 174 | 175 | }; 176 | 177 | return Stats; 178 | 179 | }))); 180 | -------------------------------------------------------------------------------- /texture/brick/brick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/brick/brick.png -------------------------------------------------------------------------------- /texture/cobblestone/cobblestone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/cobblestone/cobblestone.png -------------------------------------------------------------------------------- /texture/dirt/customdirt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/dirt/customdirt.png -------------------------------------------------------------------------------- /texture/dirt/dirt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/dirt/dirt.png -------------------------------------------------------------------------------- /texture/glass/glass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/glass/glass.png -------------------------------------------------------------------------------- /texture/grass/bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/grass/bottom.jpg -------------------------------------------------------------------------------- /texture/grass/side.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/grass/side.jpg -------------------------------------------------------------------------------- /texture/grass/top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/grass/top.jpg -------------------------------------------------------------------------------- /texture/oakLeaves/oakLeaves.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/oakLeaves/oakLeaves.png -------------------------------------------------------------------------------- /texture/oakLeaves/oakLeavesTransparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/oakLeaves/oakLeavesTransparent.png -------------------------------------------------------------------------------- /texture/oakLog/bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/oakLog/bottom.jpg -------------------------------------------------------------------------------- /texture/oakLog/side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/oakLog/side.png -------------------------------------------------------------------------------- /texture/oakLog/top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/oakLog/top.jpg -------------------------------------------------------------------------------- /texture/plank/plank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/plank/plank.png -------------------------------------------------------------------------------- /texture/sand/sand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/sand/sand.png -------------------------------------------------------------------------------- /texture/stone/stone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/stone/stone.png -------------------------------------------------------------------------------- /texture/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/texture.png -------------------------------------------------------------------------------- /texture/water/water.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/texture/water/water.jpeg -------------------------------------------------------------------------------- /titleScreen/five.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/titleScreen/five.jpeg -------------------------------------------------------------------------------- /titleScreen/four.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/titleScreen/four.jpeg -------------------------------------------------------------------------------- /titleScreen/one.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/titleScreen/one.jpeg -------------------------------------------------------------------------------- /titleScreen/six.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/titleScreen/six.jpeg -------------------------------------------------------------------------------- /titleScreen/three.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/titleScreen/three.jpeg -------------------------------------------------------------------------------- /titleScreen/two.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HritikRC/Minecraft/cd18949c2bcc2169cd143be3623e663ecc16a5c2/titleScreen/two.jpeg --------------------------------------------------------------------------------