├── css ├── DooM.ttf └── style.css ├── assets ├── STBAR.PNG ├── Thumbs.db ├── BFGFB0.PNG ├── BFGGB0.PNG ├── BOSSB1.PNG ├── FLOOR5_1.PNG ├── MFLR8_1.PNG ├── PISGA0.PNG ├── portal.gif ├── railgf1a.wav └── doom_icon_final3.gif ├── .gitmodules ├── README.md ├── js ├── ui.js ├── controls.js ├── gun.js ├── game.js ├── map.js └── camera.js └── index.html /css/DooM.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/css/DooM.ttf -------------------------------------------------------------------------------- /assets/STBAR.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/STBAR.PNG -------------------------------------------------------------------------------- /assets/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/Thumbs.db -------------------------------------------------------------------------------- /assets/BFGFB0.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/BFGFB0.PNG -------------------------------------------------------------------------------- /assets/BFGGB0.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/BFGGB0.PNG -------------------------------------------------------------------------------- /assets/BOSSB1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/BOSSB1.PNG -------------------------------------------------------------------------------- /assets/FLOOR5_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/FLOOR5_1.PNG -------------------------------------------------------------------------------- /assets/MFLR8_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/MFLR8_1.PNG -------------------------------------------------------------------------------- /assets/PISGA0.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/PISGA0.PNG -------------------------------------------------------------------------------- /assets/portal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/portal.gif -------------------------------------------------------------------------------- /assets/railgf1a.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/railgf1a.wav -------------------------------------------------------------------------------- /assets/doom_icon_final3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StephenGrider/DOM/master/assets/doom_icon_final3.gif -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "matrixUtil"] 2 | path = matrixUtil 3 | url = git@github.com:StephenGrider/matrixUtil.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DOM 2 | === 3 | 4 | DOOM clone using DOM elements. Multiplayer enabled via firebase. Currently only one instance available at a time. 5 | 6 | 7 | How To 8 | === 9 | 10 | ``` 11 | git clone git@github.com:StephenGrider/DOM.git 12 | cd DOM 13 | git submodule update --init 14 | ``` 15 | 16 | 17 | Run index.html. 18 | Use your WASD keys to move around- not the arrow keys 19 | NOTE: ONLY WORKS WITH WEBKIT BROWSERS 20 | 21 | 22 | Screenshot 23 | === 24 | 25 | 26 | ![alt tag](http://i.imgur.com/tEMheqW.png) -------------------------------------------------------------------------------- /js/ui.js: -------------------------------------------------------------------------------- 1 | var UI = function(){ 2 | 3 | 4 | }; 5 | 6 | UI.prototype.init = function(){ 7 | var gun = document.getElementsByClassName('gun'); 8 | var matrix = new MatrixUtil([[1,0,0,0], 9 | [0,1,0,0], 10 | [0,0,1,0], 11 | [0,0,0,1]]); 12 | matrix.translateY(window.innerHeight*.61) 13 | gun[0].style['-webkit-transform'] = "matrix3d("+ matrix.toString()+")"; 14 | } 15 | 16 | UI.prototype.updateAmmo = function(){ 17 | var ammo = document.getElementsByClassName('ammo'); 18 | ammo[0].innerHTML = ammo[0].innerHTML - 1; 19 | }; 20 | 21 | UI.prototype.updateFrag = function(){ 22 | var frags = document.getElementsByClassName('frags'); 23 | frags[0].innerHTML = parseInt(frags[0].innerHTML) + 1; 24 | }; -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 |
GOTTEM
18 | 19 | 20 | 40 21 | 100% 22 | 0 23 | 24 | 100% 25 | 26 | 27 | 30 | -------------------------------------------------------------------------------- /js/controls.js: -------------------------------------------------------------------------------- 1 | Game.prototype.setupControls = function(ui){ 2 | var keyPressDown = function(e){ 3 | if(e.keyCode === 68){ 4 | this.keyState.right = true; 5 | } else if(e.keyCode === 65){ 6 | this.keyState.left = true; 7 | } else if(e.keyCode === 83){ 8 | this.keyState.backward = true; 9 | } else if(e.keyCode === 87){ 10 | this.keyState.forward = true; 11 | } else if(e.keyCode === 81){ 12 | this.keyState.strafeLeft = true; 13 | } else if(e.keyCode === 69){ 14 | this.keyState.strafeRight = true; 15 | } else if(e.keyCode === 32){ 16 | e.preventDefault(); 17 | if(this.gun.then === null){ 18 | this.gun.then = new Date(); 19 | }else if((new Date()) - this.gun.then < 3000){ 20 | return false; 21 | } 22 | this.updatePosition(true) 23 | var fired = this.gun.selfFire(this.camera.cameraPos.x,this.camera.cameraPos.z,this.camera.cameraPos.heading) 24 | var playerHit = this.gun.checkHit(this.players,this.playerId,this.camera); 25 | if(fired){ 26 | this.ui.updateAmmo(); 27 | } 28 | if(playerHit && fired){ 29 | this.ui.updateFrag(); 30 | this.gottemText[0].style.opacity = 1; 31 | } 32 | } 33 | }.bind(this); 34 | 35 | var keyPressUp = function(e){ 36 | if(e.keyCode === 68){ 37 | this.keyState.right = false; 38 | } else if(e.keyCode === 65){ 39 | this.keyState.left = false; 40 | } else if(e.keyCode === 83){ 41 | this.keyState.backward = false; 42 | } else if(e.keyCode === 81){ 43 | this.keyState.strafeLeft = false; 44 | } else if(e.keyCode === 69){ 45 | this.keyState.strafeRight = false; 46 | } else if(e.keyCode === 87){ 47 | this.keyState.forward = false; 48 | } 49 | }.bind(this); 50 | window.onkeydown = keyPressDown; 51 | window.onkeyup = keyPressUp 52 | } -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | html, body{ 2 | -webkit-perspective: 1200px; 3 | -webkit-transform-style: preserve-3d; 4 | height:75%; 5 | margin: 0; 6 | padding: 0; 7 | 8 | } 9 | 10 | .dir{ 11 | -webkit-transform-style: preserve-3d; 12 | } 13 | 14 | .floorTile{ 15 | position:absolute; 16 | height:805px; 17 | width:805px; 18 | } 19 | 20 | .wallTile{ 21 | position:absolute; 22 | height:805px; 23 | width:805px; 24 | } 25 | 26 | .player{ 27 | position:absolute; 28 | height:600px; 29 | width:300px; 30 | } 31 | 32 | #container { 33 | min-height:100%; 34 | position:absolute; 35 | top:-20px; 36 | } 37 | 38 | #gun{ 39 | -webkit-perspective: 300px; 40 | position:absolute; 41 | } 42 | 43 | .shot{ 44 | height:100px; 45 | width: 150px; 46 | background-color:white; 47 | box-shadow: 0 0 50px #fefcc9, 48 | 10px -10px 30px #feec85, 49 | -20px -20px 40px #ffae34, 50 | 20px -40px 50px #ec760c, 51 | -20px -60px 60px #cd4606, 52 | 0 -80px 70px #973716, 53 | 10px -20px 80px #451b0e; 54 | position:absolute; 55 | } 56 | 57 | .gottem{ 58 | background:none; 59 | text-align: center; 60 | font-family: Arial; 61 | font-size: 140px; text-transform: uppercase; 62 | color: #fff; 63 | text-shadow: 0 0 20px #fefcc9, 10px -10px 30px #feec85, -20px -20px 40px #ffae34, 20px -40px 50px #ec760c, -20px -60px 60px #cd4606, 0 -80px 70px #973716, 10px -90px 80px #451b0e; 64 | width: 60%; 65 | left: 20%; 66 | top: 100px; 67 | position:absolute; 68 | opacity: 0; 69 | } 70 | 71 | div{ 72 | font-size: 100px; 73 | background: gray; 74 | } 75 | 76 | 77 | @font-face { 78 | font-family: "doom"; 79 | src: url(DooM.ttf) format("truetype"); 80 | } 81 | 82 | .ui{ 83 | position:absolute; 84 | font-size: 40px; 85 | bottom:-78%; 86 | width:100%; 87 | height:100px; 88 | color:red; 89 | -webkit-text-stroke-color: black; 90 | -webkit-text-stroke-width: 2.00px; 91 | font-family: 'doom'; 92 | /*color: transparent;*/ 93 | text-shadow: 0 0 25px rgba(0,0,0,0.8); 94 | } 95 | 96 | .portrait{ 97 | height:80px; 98 | width: 10%; 99 | left: 45%; 100 | } 101 | 102 | .health{ 103 | height:80px; 104 | width: 10%; 105 | left: 20%; 106 | } 107 | 108 | .ammo{ 109 | height:80px; 110 | width: 10%; 111 | left: 5%; 112 | } 113 | 114 | .armor{ 115 | height:80px; 116 | width: 10%; 117 | left: 60%; 118 | } 119 | 120 | .frags{ 121 | height:80px; 122 | width: 10%; 123 | left: 38%; 124 | } 125 | 126 | .gun{ 127 | position:absolute; 128 | font-size: 40px; 129 | /*bottom:-54%;*/ 130 | right: 35.5%; 131 | width:30%; 132 | height:180px; 133 | } 134 | 135 | -------------------------------------------------------------------------------- /js/gun.js: -------------------------------------------------------------------------------- 1 | var Gun = function(){ 2 | this.sound = new Audio('assets/railgf1a.wav'); 3 | this.then = null; 4 | this.targets = []; 5 | this.shots = []; 6 | this.container = document.getElementById('container'); 7 | }; 8 | 9 | Gun.prototype.selfFire = function(){ 10 | this.sound.play(); 11 | shot = document.createElement('div'); 12 | shot.className = 'shot'; 13 | var matrix = new MatrixUtil([[1,0,0,0], 14 | [0,1,0,0], 15 | [0,0,1,0], 16 | [0,0,0,1]]) 17 | 18 | matrix.translateY(-2500) 19 | matrix.rotateX(-88 * Math.PI / 180); 20 | matrix.translateY(-2500) 21 | matrix.translateZ(-150) 22 | matrix.translateX(window.innerWidth*.44) 23 | matrix.translateY(window.innerHeight*.85); 24 | 25 | shot.style['-webkit-transform'] = "matrix3d("+ matrix.toString()+")";; 26 | // shot.style['width'] = '100px'; 27 | document.body.appendChild(shot); 28 | shot.currentOpacity = 1; 29 | this.shots.push(shot); 30 | shot.style['height'] = '5000px'; 31 | 32 | this.then = new Date(); 33 | return true; 34 | }; 35 | 36 | Gun.prototype.fire = function(x,y,heading, otherPlayerShot){ 37 | this.sound.play(); 38 | shot = document.createElement('div'); 39 | shot.className = 'shot'; 40 | var matrix = new MatrixUtil([[1,0,0,0], 41 | [0,1,0,0], 42 | [0,0,1,0], 43 | [0,0,0,1]]) 44 | 45 | matrix.translateY(2500); 46 | matrix.translateX(50); 47 | matrix.rotateZ(heading+Math.PI); 48 | matrix.translateY(-2500); 49 | matrix.translateX(-50); 50 | 51 | matrix.translateY(-y) 52 | matrix.translateX(-x) 53 | matrix.translateZ(250); 54 | 55 | shot.style['-webkit-transform'] = "matrix3d("+ matrix.toString()+")";; 56 | this.container.appendChild(shot); 57 | shot.currentOpacity = 1; 58 | this.shots.push(shot); 59 | shot.style['height'] = '5000px'; 60 | 61 | this.then = new Date(); 62 | return true; 63 | }; 64 | 65 | Gun.prototype.fade = function(){ 66 | for(var i = 0; i < this.shots.length; i++){ 67 | if(this.shots[i].currentOpacity <= 0){ 68 | this.shots[i].style.display = 'none'; 69 | this.shots.splice(i,1); 70 | } 71 | if(this.shots[i]){ 72 | this.shots[i].currentOpacity -= .025; 73 | this.shots[i].style.opacity = this.shots[i].currentOpacity; 74 | } 75 | } 76 | }; 77 | 78 | Gun.prototype.checkHit = function(players, myId, myCamera){ 79 | for(var key in players){ 80 | if(key === myId.toString()){ 81 | continue; 82 | }else{ 83 | var meX = players[myId].posX; 84 | var meZ = players[myId].posZ; 85 | var themX = players[key].posX; 86 | var themZ = players[key].posZ; 87 | 88 | if(meX > themX && meZ > themZ){ 89 | var enemy = Math.atan((meX-themX)/(meZ-themZ)) +Math.PI; 90 | } else if( meX > themX && meZ < themZ){ 91 | var enemy = Math.PI*2 - Math.abs(Math.atan((meX-themX)/(meZ-themZ))); 92 | } else if( meX < themX && meZ < themZ){ 93 | var enemy = Math.atan((meX-themX)/(meZ-themZ)); 94 | } else if(meX < themX && meZ > themZ){ 95 | var enemy = Math.PI + Math.atan((meX-themX)/(meZ-themZ)); 96 | } 97 | var aim = myCamera.cameraPos.heading; 98 | enemy = Math.abs(enemy); 99 | //hitbox size!!! 100 | var hitBoxWidth = .15 101 | if(Math.abs(enemy-aim) < hitBoxWidth){ 102 | console.log('HIT'); 103 | return key; 104 | } 105 | } 106 | } 107 | }; 108 | 109 | -------------------------------------------------------------------------------- /js/game.js: -------------------------------------------------------------------------------- 1 | var Game = function(options){ 2 | this.options = {}; 3 | this.playerId = ~~(Math.random()*1000) 4 | this.fbMe = new Firebase("https://doom.firebaseio.com/players/"+this.playerId); 5 | this.fb = new Firebase("https://doom.firebaseio.com/players/"); 6 | this.fbShots = new Firebase("https://doom.firebaseio.com/shots/"+this.playerId); 7 | this.then = new Date(); //avoid updating firebase every render tick 8 | this.map = new Map({}); 9 | this.map.init(); 10 | this.keyState = {}; 11 | this.otherPlayers = {}; 12 | this.camera = new Camera(this.keyState); 13 | this.camera.init(); 14 | this.gun = new Gun(); 15 | this.ui = new UI(); 16 | this.ui.init(); 17 | this.init(); 18 | this.then = null; 19 | this.gottemText = document.getElementsByClassName('gottem'); 20 | } 21 | 22 | Game.prototype.render = function(){ 23 | if(!this.gottemText){ 24 | this.gottemText = document.getElementsByClassName('gottem'); 25 | } 26 | if(this.keyState.left){this.camera.move('left')} 27 | if(this.keyState.right){this.camera.move('right')} 28 | if(this.keyState.forward){this.camera.move('forward')} 29 | if(this.keyState.backward){this.camera.move('backward')} 30 | if(this.keyState.strafeLeft){this.camera.move('strafeLeft')} 31 | if(this.keyState.strafeRight){this.camera.move('strafeRight')} 32 | if((new Date()) - this.then > 50){ 33 | this.updatePosition(); 34 | this.then = new Date(); 35 | } 36 | this.gun.fade(); 37 | this.gottem(); 38 | } 39 | 40 | Game.prototype.updatePosition = function(didShoot){ 41 | this.fbMe.set({id: this.playerId, 42 | posX: this.camera.cameraPos.x, 43 | posZ: this.camera.cameraPos.z, 44 | heading: this.camera.cameraPos.heading, 45 | date: (new Date()).getTime(), 46 | shot: didShoot || false, 47 | flipped: this.camera.flipped}); 48 | } 49 | 50 | Game.prototype.playerUpdate = function(val){ 51 | for(var key in val){ 52 | if(val[key].shot && key !=this.playerId){ 53 | console.log('doin it', key, this.playerId) 54 | this.gun.fire(val[key].posX, val[key].posZ, val[key].heading,true) 55 | } 56 | 57 | if(!this.otherPlayers.hasOwnProperty(key) && key != this.playerId){ 58 | //make a new player 59 | this.otherPlayers[key] = {}; 60 | this.otherPlayers[key].heading = val[key].heading; 61 | this.otherPlayers[key].id = val[key].id; 62 | this.otherPlayers[key].posX = val[key].posX; 63 | this.otherPlayers[key].posZ = val[key].posZ; 64 | var div = document.createElement('img'); 65 | div.className = 'player'; 66 | div.src = 'assets/BOSSB1.PNG'; 67 | div.innerHTML = key; 68 | div.id = key; 69 | 70 | this.otherPlayers[key].ele = div; 71 | document.getElementById('container').appendChild(div) 72 | } else{ 73 | if(this.otherPlayers[key]){ 74 | //update player position 75 | var matrix = new MatrixUtil([[1,0,0,0], 76 | [0,1,0,0], 77 | [0,0,1,0], 78 | [0,0,0,1]]); 79 | matrix.rotateX(Math.PI/2) 80 | matrix.rotateZ(val[key].heading) 81 | if(val[key].flipped){ 82 | matrix.rotateY(Math.PI) 83 | matrix.translateX(-1*val[key].posX); 84 | matrix.translateY(1*val[key].posZ) 85 | matrix.translateZ(1100) 86 | } else{ 87 | matrix.translateX(-1*val[key].posX); 88 | matrix.translateY(-1*val[key].posZ) 89 | matrix.translateZ(300) 90 | } 91 | this.otherPlayers[key].ele.style['-webkit-transform'] = "matrix3d("+ matrix.toString()+")"; 92 | } 93 | if((new Date()).getTime() - val[key].date > 30000){ 94 | //remove old players 95 | this.otherPlayers[key].ele.style['visibility'] = 'hidden'; 96 | (new Firebase("https://doom.firebaseio.com/players/"+key)).remove() 97 | } 98 | } 99 | } 100 | } 101 | 102 | Game.prototype.init = function(){ 103 | this.setupControls(); 104 | this.ui.init(); 105 | this.fb.on('value',function(dat){ 106 | if(dat.val() != null){ 107 | this.players = dat.val(); 108 | this.playerUpdate(dat.val()); 109 | } 110 | }.bind(this)) 111 | window.requestAnimFrame = (function(){ 112 | return window.requestAnimationFrame || 113 | window.webkitRequestAnimationFrame 114 | })(); 115 | this.shouldRender = 0; 116 | var self = this; 117 | (function animloop(){ 118 | requestAnimFrame(animloop); 119 | self.shouldRender++; 120 | if(self.shouldRender % 2){self.render();} 121 | 122 | })(); 123 | } 124 | 125 | Game.prototype.gottem = function(){ 126 | if(this.gottemText[0].style.opacity > .3){ 127 | this.gottemText[0].style.display = 'inline'; 128 | this.gottemText[0].style.opacity -= .02 129 | } 130 | if(this.gottemText[0].style.opacity < .3){ 131 | this.gottemText[0].style.display = 'none'; 132 | } 133 | 134 | }; 135 | -------------------------------------------------------------------------------- /js/map.js: -------------------------------------------------------------------------------- 1 | var Map = function(options){ 2 | 3 | this.mapTiles = []; 4 | this.options = {}; 5 | this.options.floorTexture = options.texture || 'assets/FLOOR5_1.PNG'; 6 | this.options.wallTexture = options.wallTexture || 'assets/MFLR8_1.PNG'; 7 | this.options.floorTextureDim = options.floorTextureDim || 800; 8 | 9 | }; 10 | 11 | Map.prototype.init = function(){ 12 | for(var i = 0; i < 5; i++){ 13 | for(var j = 0 ; j < 5; j++){ 14 | //floor 15 | var img = document.createElement('img'); 16 | img.src = this.options.floorTexture; 17 | img.className = 'floorTile'; 18 | 19 | //apply positioning 20 | var position = {}; 21 | position.x = i*this.options.floorTextureDim; 22 | position.y = j*this.options.floorTextureDim; 23 | position.z = 0; 24 | img.style['-webkit-transform'] = 'translate3d('+position.x+'px,'+position.y+'px,'+ position.z+'px)'; 25 | document.getElementById('container').appendChild(img) 26 | if(i === 4 && j ===4){ 27 | var img = document.createElement('img'); 28 | img.src = 'assets/portal.gif'; 29 | img.className = 'floorTile'; 30 | 31 | img.style['-webkit-transform'] = 'translate3d('+position.x+'px,'+position.y+'px,'+ (position.z+2)+'px)'; 32 | document.getElementById('container').appendChild(img) 33 | } 34 | } 35 | } 36 | 37 | //foward 38 | for(var i = 0; i < 5; i++){ 39 | var box = document.createElement('img'); 40 | box.src = this.options.wallTexture; 41 | box.className = 'wallTile'; 42 | var matrix = new MatrixUtil([[1,0,0,0], 43 | [0,1,0,0], 44 | [0,0,1,0], 45 | [0,0,0,1]]) 46 | matrix.rotateX(Math.PI/2) 47 | matrix.translateX(i*804) 48 | matrix.translateY(-400) 49 | matrix.translateZ(400); 50 | 51 | box.style['-webkit-transform'] = "matrix3d("+ matrix.toString()+")";; 52 | document.getElementById('container').appendChild(box) 53 | } 54 | //left 55 | for(var i = 0; i < 5; i++){ 56 | var box = document.createElement('img'); 57 | box.src = this.options.wallTexture; 58 | box.className = 'wallTile'; 59 | var matrix = new MatrixUtil([[1,0,0,0], 60 | [0,1,0,0], 61 | [0,0,1,0], 62 | [0,0,0,1]]) 63 | matrix.rotateX(Math.PI/2); 64 | matrix.rotateZ(Math.PI/2); 65 | matrix.translateY(i*804) 66 | matrix.translateX(-400) 67 | matrix.translateZ(400); 68 | 69 | box.style['-webkit-transform'] = "matrix3d("+ matrix.toString()+")";; 70 | document.getElementById('container').appendChild(box) 71 | } 72 | 73 | //back 74 | for(var i = 0; i < 5; i++){ 75 | var box = document.createElement('img'); 76 | box.src = this.options.wallTexture; 77 | box.className = 'wallTile'; 78 | var matrix = new MatrixUtil([[1,0,0,0], 79 | [0,1,0,0], 80 | [0,0,1,0], 81 | [0,0,0,1]]) 82 | matrix.rotateX(Math.PI/2) 83 | matrix.translateX(i*804) 84 | matrix.translateY(3600) 85 | matrix.translateZ(400); 86 | 87 | box.style['-webkit-transform'] = "matrix3d("+ matrix.toString()+")";; 88 | document.getElementById('container').appendChild(box) 89 | } 90 | //right 91 | for(var i = 0; i < 5; i++){ 92 | var box = document.createElement('img'); 93 | box.src = this.options.wallTexture; 94 | box.className = 'wallTile'; 95 | var matrix = new MatrixUtil([[1,0,0,0], 96 | [0,1,0,0], 97 | [0,0,1,0], 98 | [0,0,0,1]]) 99 | matrix.rotateX(Math.PI/2); 100 | matrix.rotateZ(Math.PI/2); 101 | matrix.translateY(i*804) 102 | matrix.translateX(3600) 103 | matrix.translateZ(400); 104 | 105 | box.style['-webkit-transform'] = "matrix3d("+ matrix.toString()+")";; 106 | document.getElementById('container').appendChild(box) 107 | } 108 | 109 | 110 | for(var i = 0; i < 5; i++){ 111 | for(var j = 0 ; j < 5; j++){ 112 | var img = document.createElement('img'); 113 | img.src = this.options.floorTexture; 114 | img.className = 'floorTile'; 115 | img.innerHTML = ''+i*800+','+j*800; 116 | 117 | //apply positioning 118 | var position = {}; 119 | position.x = i*this.options.floorTextureDim; 120 | position.y = j*this.options.floorTextureDim; 121 | position.z = 1500; 122 | img.style['-webkit-transform'] = 'translate3d('+position.x+'px,'+position.y+'px,'+ position.z+'px)'; 123 | document.getElementById('container').appendChild(img) 124 | if(i === 4 && j ===4){ 125 | var img = document.createElement('img'); 126 | img.src = 'assets/portal.gif'; 127 | img.className = 'floorTile'; 128 | 129 | img.style['-webkit-transform'] = 'translate3d('+position.x+'px,'+position.y+'px,'+ (position.z-2)+'px)'; 130 | document.getElementById('container').appendChild(img) 131 | } 132 | } 133 | } 134 | 135 | 136 | 137 | }; 138 | -------------------------------------------------------------------------------- /js/camera.js: -------------------------------------------------------------------------------- 1 | var Camera = function(keys){ 2 | 3 | this.keyState = keys; 4 | this.xEle = document.getElementById('x'); 5 | this.yEle = document.getElementById('y'); 6 | this.zEle = document.getElementById('z'); 7 | this.rxEle = document.getElementById('rotateX'); 8 | this.ryEle = document.getElementById('rotateY'); 9 | this.rzEle = document.getElementById('rotateZ'); 10 | 11 | this.x = 0; 12 | this.y = 500; 13 | this.z = 0; 14 | this.rx = 89.99999; 15 | this.ry = 0; 16 | this.rz = 0; 17 | this.angle = 89; 18 | this.deg2rad = Math.PI/180; 19 | 20 | this.cameraPos = {}; 21 | this.cameraPos.x = this.x- window.innerWidth/2; 22 | this.cameraPos.y = this.y; 23 | this.cameraPos.z = this.z - window.innerHeight/2; 24 | this.cameraPos.heading = 0; 25 | 26 | this.velocity = 30; 27 | this.angularVelocity = this.deg2rad*3; 28 | this.flipped = false; 29 | } 30 | 31 | Camera.prototype.init = function(){ 32 | this.cameraMatrix = new MatrixUtil([[1,0,0,0], 33 | [0,1,0,0], 34 | [0,0,1,0], 35 | [0,0,0,1]]) 36 | // this.cameraMatrix.translateY(-800); 37 | this.cameraMatrix.translateY(-window.innerHeight/2) 38 | this.cameraMatrix.rotateX(-this.deg2rad*89); 39 | this.cameraMatrix.translateY(window.innerHeight/2) 40 | // this.cameraMatrix.translateX(-800); 41 | this.cameraMatrix.translateY(400) 42 | var o = "matrix3d("+ this.cameraMatrix.toString()+")"; 43 | this.xEle.style['-webkit-transform'] = o; 44 | } 45 | 46 | Camera.prototype.move = function(direction){ 47 | if(direction === 'forward'){ 48 | this.cameraPos.z += Math.cos(this.cameraPos.heading)*this.velocity; 49 | this.cameraPos.x += Math.sin(this.cameraPos.heading)*this.velocity; 50 | this.cameraMatrix.translateZ(this.velocity) 51 | var o = "matrix3d("+ this.cameraMatrix.toString()+")"; 52 | this.xEle.style['-webkit-transform'] = o; 53 | 54 | // console.log(this.cameraPos) 55 | 56 | } else if(direction === 'backward'){ 57 | this.cameraPos.z -= Math.cos(this.cameraPos.heading)*this.velocity; 58 | this.cameraPos.x -= Math.sin(this.cameraPos.heading)*this.velocity; 59 | this.cameraMatrix.translateZ(-this.velocity) 60 | var o = "matrix3d("+ this.cameraMatrix.toString()+")"; 61 | this.xEle.style['-webkit-transform'] = o; 62 | 63 | 64 | // console.log(this.cameraPos) 65 | 66 | } else if(direction === 'left'){ 67 | this.cameraPos.heading += this.angularVelocity; 68 | if(this.cameraPos.heading > 2*Math.PI){ 69 | this.cameraPos.heading = 0; 70 | } 71 | if(this.cameraPos.heading < .0001 && this.cameraPos.heading > -.0001){this.cameraPos.heading = 0;} 72 | this.cameraMatrix.translateZ(-600) 73 | this.cameraMatrix.rotateY(this.angularVelocity) 74 | this.cameraMatrix.translateZ(600) 75 | var o = "matrix3d("+ this.cameraMatrix.toString()+")"; 76 | this.xEle.style['-webkit-transform'] = o; 77 | 78 | } else if(direction === 'right'){ 79 | this.cameraPos.heading -= this.angularVelocity; 80 | if(this.cameraPos.heading < 0){ 81 | this.cameraPos.heading = 2*Math.PI; 82 | } 83 | if(this.cameraPos.heading < .0001 && this.cameraPos.heading > -.0001){this.cameraPos.heading = 0;} 84 | this.cameraMatrix.translateZ(-600) 85 | this.cameraMatrix.rotateY(-this.angularVelocity) 86 | this.cameraMatrix.translateZ(600) 87 | var o = "matrix3d("+ this.cameraMatrix.toString()+")"; 88 | this.xEle.style['-webkit-transform'] = o; 89 | 90 | } else if(direction === 'strafeRight'){ 91 | 92 | this.cameraPos.z += Math.sin(this.cameraPos.heading)*this.velocity; 93 | this.cameraPos.x += Math.cos(this.cameraPos.heading)*this.velocity; 94 | this.cameraMatrix.translateX(-this.velocity) 95 | var o = "matrix3d("+ this.cameraMatrix.toString()+")"; 96 | this.xEle.style['-webkit-transform'] = o; 97 | 98 | } else if(direction === 'strafeLeft'){ 99 | 100 | this.cameraPos.z -= Math.sin(this.cameraPos.heading)*this.velocity; 101 | this.cameraPos.x -= Math.cos(this.cameraPos.heading)*this.velocity; 102 | this.cameraMatrix.translateX(this.velocity) 103 | var o = "matrix3d("+ this.cameraMatrix.toString()+")"; 104 | this.xEle.style['-webkit-transform'] = o; 105 | } 106 | 107 | if(this.cameraPos.x < -3000 && this.cameraPos.z < -2200 && !this.flipped){ 108 | this.flipped = true; 109 | 110 | this.cameraPos.x = this.x- window.innerWidth/2; 111 | this.cameraPos.y = 1100; 112 | this.cameraPos.z = this.z - window.innerHeight/2; 113 | this.cameraPos.heading = 0; 114 | 115 | this.cameraMatrix = new MatrixUtil([[1,0,0,0], 116 | [0,1,0,0], 117 | [0,0,1,0], 118 | [0,0,0,1]]) 119 | 120 | this.cameraMatrix.translateY(-window.innerHeight/2) 121 | this.cameraMatrix.rotateX(this.deg2rad*89); 122 | this.cameraMatrix.translateY(window.innerHeight/2) 123 | 124 | this.cameraMatrix.translateY(-1100) 125 | var o = "matrix3d("+ this.cameraMatrix.toString()+")"; 126 | this.xEle.style['-webkit-transform'] = o; 127 | } 128 | 129 | if(this.cameraPos.x < -3000 && this.cameraPos.z > 2800 && this.flipped){ 130 | this.flipped = false; 131 | 132 | this.cameraPos.x = this.x- window.innerWidth/2; 133 | this.cameraPos.y = this.y; 134 | this.cameraPos.z = this.z - window.innerHeight/2; 135 | this.cameraPos.heading = 0; 136 | 137 | this.cameraMatrix = new MatrixUtil([[1,0,0,0], 138 | [0,1,0,0], 139 | [0,0,1,0], 140 | [0,0,0,1]]) 141 | this.cameraMatrix.translateY(-window.innerHeight/2) 142 | this.cameraMatrix.rotateX(-this.deg2rad*89); 143 | this.cameraMatrix.translateY(window.innerHeight/2) 144 | 145 | this.cameraMatrix.translateY(400) 146 | var o = "matrix3d("+ this.cameraMatrix.toString()+")"; 147 | this.xEle.style['-webkit-transform'] = o; 148 | } 149 | 150 | } --------------------------------------------------------------------------------