├── .idea ├── .name ├── BabyJs.iml ├── codeStyleSettings.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── jsLibraryMappings.xml ├── libraries │ ├── BabylonJS.xml │ └── bGUI.xml ├── misc.xml ├── modules.xml ├── vcs.xml └── workspace.xml ├── README.md ├── gfx ├── crosshair.png ├── dirt.jpg ├── doom │ ├── acid.png │ ├── fire.png │ ├── sheets │ │ ├── TMPimp_sheet.png │ │ ├── imp_anims.png │ │ ├── imp_spritesheet.png │ │ ├── impsheet.gif │ │ └── marine_anims.png │ ├── shotgun_front.png │ └── skulls.png ├── doomguy.png ├── flare.png └── grass.png ├── index.html ├── js ├── scene.js └── utils │ └── babylon.2.3.js ├── snds ├── E1M1.mp3 ├── dspopain.wav └── dsshotgn.wav └── style.css /.idea/.name: -------------------------------------------------------------------------------- 1 | BabyJs -------------------------------------------------------------------------------- /.idea/BabyJs.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/codeStyleSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 27 | 29 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/libraries/BabylonJS.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/libraries/bGUI.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 18 | 19 | 20 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 91 | 92 | 93 | 100 | 102 | 103 | 115 | 116 | 117 | 118 | 119 | true 120 | 121 | 122 | 123 | 124 | 125 | 126 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | Bitwise operation issuesJavaScript 140 | 141 | 142 | CSS 143 | 144 | 145 | Code quality toolsJavaScript 146 | 147 | 148 | Code style issuesJavaScript 149 | 150 | 151 | CoffeeScript 152 | 153 | 154 | Control flow issuesJavaScript 155 | 156 | 157 | Data flow issuesJavaScript 158 | 159 | 160 | Error handlingJavaScript 161 | 162 | 163 | General 164 | 165 | 166 | GeneralCoffeeScript 167 | 168 | 169 | GeneralJavaScript 170 | 171 | 172 | GeneralPHP 173 | 174 | 175 | HAML 176 | 177 | 178 | HTML 179 | 180 | 181 | Ini Files 182 | 183 | 184 | Invalid elementsCSS 185 | 186 | 187 | JSON 188 | 189 | 190 | JavaScript 191 | 192 | 193 | PHP 194 | 195 | 196 | PHPDocPHP 197 | 198 | 199 | Potentially confusing code constructsJavaScript 200 | 201 | 202 | Probable bugsCoffeeScript 203 | 204 | 205 | Probable bugsJavaScript 206 | 207 | 208 | Probable bugsPHP 209 | 210 | 211 | RELAX NG 212 | 213 | 214 | SQL 215 | 216 | 217 | Spelling 218 | 219 | 220 | TypeScript 221 | 222 | 223 | UndefinedPHP 224 | 225 | 226 | UnusedPHP 227 | 228 | 229 | XML 230 | 231 | 232 | XPath 233 | 234 | 235 | XSLT 236 | 237 | 238 | 239 | 240 | Blade files 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 279 | 280 | 281 | 282 | 285 | 286 | 289 | 290 | 291 | 292 | 295 | 296 | 299 | 300 | 303 | 304 | 305 | 306 | 309 | 310 | 313 | 314 | 317 | 318 | 319 | 320 | 323 | 324 | 327 | 328 | 331 | 332 | 335 | 336 | 337 | 338 | 341 | 342 | 345 | 346 | 349 | 350 | 351 | 352 | 355 | 356 | 359 | 360 | 363 | 364 | 367 | 368 | 369 | 370 | 373 | 374 | 377 | 378 | 381 | 382 | 385 | 386 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 1455902954729 457 | 460 | 461 | 1456168584516 462 | 466 | 467 | 1456169742163 468 | 472 | 473 | 1456241664289 474 | 478 | 479 | 1456314718035 480 | 484 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 544 | 547 | 548 | 549 | 551 | 552 | 559 | 560 | 561 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BABYDOOM 2 | ## Clone of DOOM using the JavaScript [Babylon.js](http://www.babylonjs.com/) engine. 3 | 4 | [Github hosting of the game](http://arc0re.github.io/) 5 | 6 | 7 | [Azure hosting of the game](http://babydoom.azurewebsites.net/) 8 | 9 | __This is an "early alpha", more of a technical demo. More content will be added (like a purpose to play the game)__ 10 | 11 | Current features: 12 | 13 | + Random enemy placement 14 | + Sprite animation (static and 2 death animations) 15 | + Random "world" generation (wall placement) 16 | + Gun shot 17 | + Bullet collisions 18 | + Keyboard layout selection 19 | 20 | TODO: 21 | 22 | + Remove unused assets. 23 | + Better stuff than a couple of alert() at loading 24 | + Prevent sprites from spawning inside the cubes 25 | + Fix starting position 26 | + Cooldown on guns 27 | + Death animations for monsters 28 | + AI / Pathfinding 29 | + A real HUD, at least centered (don't tell me this one is) 30 | + Add weapons? 31 | + DOOM's original shotgun behaviour (more than 1 pellet) 32 | + Fix buggy collisions [x] 33 | + Add other enemies 34 | + Make fix levels? Or improved random placement of "walls". 35 | + Console to enter cheats and stuff like that? 36 | 37 | Thanks a lot Demonixis, if you ever come across this repo, your [micro fps tutorial](http://www.demonixis.net/blog/un-micro-fps-en-javascript-avec-babylonjs/) 38 | has been very useful. (And I even borrowed some of your stuff like the getForwardVector() function). 39 | 40 | 41 | ## DISCLAIMER 42 | 43 | NONE OF THE ASSETS USED ARE MINE. ALL THE GRAPHICS AND SOUNDS ARE PROPERTY OF ID SOFTWARE (aka BETHESDA). -------------------------------------------------------------------------------- /gfx/crosshair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/crosshair.png -------------------------------------------------------------------------------- /gfx/dirt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/dirt.jpg -------------------------------------------------------------------------------- /gfx/doom/acid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/doom/acid.png -------------------------------------------------------------------------------- /gfx/doom/fire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/doom/fire.png -------------------------------------------------------------------------------- /gfx/doom/sheets/TMPimp_sheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/doom/sheets/TMPimp_sheet.png -------------------------------------------------------------------------------- /gfx/doom/sheets/imp_anims.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/doom/sheets/imp_anims.png -------------------------------------------------------------------------------- /gfx/doom/sheets/imp_spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/doom/sheets/imp_spritesheet.png -------------------------------------------------------------------------------- /gfx/doom/sheets/impsheet.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/doom/sheets/impsheet.gif -------------------------------------------------------------------------------- /gfx/doom/sheets/marine_anims.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/doom/sheets/marine_anims.png -------------------------------------------------------------------------------- /gfx/doom/shotgun_front.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/doom/shotgun_front.png -------------------------------------------------------------------------------- /gfx/doom/skulls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/doom/skulls.png -------------------------------------------------------------------------------- /gfx/doomguy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/doomguy.png -------------------------------------------------------------------------------- /gfx/flare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/flare.png -------------------------------------------------------------------------------- /gfx/grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/gfx/grass.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DOOOOOOOOOOOOOOOOOOOOOM 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /js/scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by arc on 19/02/2016. 3 | */ 4 | 5 | var CANVAS = document.getElementById("renderCanvas"); 6 | var KB_LAYOUT = "AZERTY"; 7 | 8 | if (confirm("Would you like to use a QWERTY layout?")) { 9 | console.log("Keyboard layout set to QWERTY"); 10 | KB_LAYOUT = "QWERTY"; 11 | } else { 12 | console.log("Keyboard layout defaults to AZERTY"); 13 | } 14 | 15 | alert("Move with either WASD (QWERTY) or ZQSD(AZERTY), click the game screen once for it to grab your mouse. Escape to free the pointer. THIS IS AN EARLY EARLY ALPHA"); 16 | 17 | // Disable right click menu 18 | document.addEventListener("contextmenu", function (e) { 19 | e.preventDefault(); 20 | }); 21 | 22 | // DEBUG: Turns off music, shows hitboxes, and bullet mesh 23 | var DEBUG = false; 24 | 25 | if (BABYLON.Engine.isSupported()) { 26 | 27 | // CONSTANTS 28 | 29 | var CUBE_SIZE = 5.5; 30 | var ENGINE = new BABYLON.Engine(CANVAS, false); // true = enable smoothing/antialiasing 31 | var SPRITES = []; // Array containing all the sprites 32 | var BULLETS = []; // Array containing all the bullets 33 | var BULLET_SPEED = 1; 34 | var SHOTGUN_BULLET_SIZE = 3; // Should be lots of little pellets, but one big bullet does the trick 35 | var MUSIC_VOLUME = 0.1; 36 | 37 | // MONSTER CONSTANTS 38 | var IMP_MAX_HP = 10; 39 | var MARINE_MAX_HP = 5; 40 | 41 | // UTILS 42 | 43 | var getRandomInt = function (min, max) { 44 | return Math.floor(Math.random() * (max - min)) + min; 45 | }; 46 | 47 | var getForwardVector = function (rotation) { 48 | var rotationMatrix = BABYLON.Matrix.RotationYawPitchRoll(rotation.y, rotation.x, rotation.z); 49 | return BABYLON.Vector3.TransformCoordinates(new BABYLON.Vector3(0, 0, 1), rotationMatrix); 50 | }; 51 | 52 | // Thats because I'm lazy af 53 | function LOG(txt) { 54 | console.log(txt); 55 | } 56 | 57 | // GAME 58 | 59 | /** 60 | * Creates an instance of Monster. 61 | * @param {BABYLON.Scene} scene 62 | * @param frames 63 | * @param animationDelay 64 | * @param number 65 | * @param {string} type 66 | * @param cellSize 67 | * @param {boolean} isAnimated 68 | * @constructor 69 | */ 70 | var Monster = function (scene, frames, animationDelay, number, type, cellSize, isAnimated) { 71 | var self = this; 72 | this.animationFrames = frames; 73 | this.animationDelay = animationDelay; 74 | this.numberOfUnits = number; 75 | this.type = type; 76 | this.health = IMP_MAX_HP; 77 | this.cellSize = cellSize; 78 | this.isAnimated = isAnimated; // BOOL 79 | var painSfx = new BABYLON.Sound("shotgunSfx", "snds/dspopain.wav", scene); 80 | 81 | switch (this.type) { 82 | case "imp": 83 | this.spritePath = "gfx/doom/sheets/imp_anims.png"; 84 | break; 85 | case "doomguy": 86 | this.spritePath = "gfx/doomguy.png"; 87 | break; 88 | case "marine": 89 | this.spritePath = "gfx/doom/sheets/marine_anims.png"; 90 | break; 91 | default: 92 | LOG("Wrong sprite name."); 93 | break; 94 | } 95 | 96 | this.spriteManager = new BABYLON.SpriteManager("spriteManager", this.spritePath, this.numberOfUnits, this.cellSize, scene); 97 | 98 | this.hitbox = new BABYLON.Mesh.CreatePlane("plane", 3, scene); 99 | this.material = new BABYLON.StandardMaterial("hitboxTxt", scene); 100 | if (DEBUG) { 101 | this.material.alpha = 0.4; 102 | } else { 103 | this.material.alpha = 0; 104 | } 105 | this.hitbox.billboardMode = BABYLON.Mesh.BILLBOARDMODE_Y; // ALL 106 | this.hitbox.material = this.material; 107 | this.hitbox.checkCollisions = true; 108 | this.hitbox.tag = "plane"; 109 | 110 | this.hitbox.sprite = new BABYLON.Sprite("sprite", this.spriteManager); 111 | this.hitbox.sprite.checkCollisions = true; 112 | 113 | this.render = function () { 114 | if (this.isAnimated) { 115 | this.hitbox.sprite.playAnimation(0, this.animationFrames, true, this.animationDelay); 116 | this.hitbox.sprite.position.y = 1; 117 | this.hitbox.sprite.size = 2.5; 118 | this.hitbox.position = this.hitbox.sprite.position; 119 | SPRITES.push(this); 120 | } else { 121 | this.hitbox.sprite.stopAnimation(); 122 | this.hitbox.sprite.position.y = 1; 123 | this.hitbox.sprite.size = 2.5; 124 | this.hitbox.position = this.hitbox.sprite.position; 125 | SPRITES.push(this); 126 | } 127 | }; 128 | 129 | this.playAnimation = function (from, to, delay) { 130 | this.hitbox.sprite.playAnimation(from, to, false, delay); 131 | LOG("ANIMATION PLAYED"); 132 | }; 133 | 134 | this.suffer = function () { 135 | painSfx.play(); 136 | }; 137 | 138 | this.dispose = function () { 139 | if (this.isAnimated) { 140 | var rnum = getRandomInt(1, 5); 141 | switch (rnum) { 142 | case 1: 143 | case 2: 144 | case 3: 145 | switch (this.type) { 146 | case "imp": 147 | this.playAnimation(3, 7, 150); // death animation 148 | break; 149 | case "marine": 150 | this.playAnimation(3, 8, 150); 151 | break; 152 | } 153 | break; 154 | case 4: 155 | case 5: 156 | switch (this.type) { 157 | case "imp": 158 | this.playAnimation(8, 15, 150); // death animation 159 | break; 160 | case "marine": 161 | this.playAnimation(9, 16, 150); 162 | break; 163 | } 164 | break; 165 | } 166 | } 167 | 168 | setTimeout(function () { 169 | self.hitbox.sprite.dispose(); 170 | self.hitbox.dispose(); 171 | LOG("monster instance deleted"); 172 | }, 5000); 173 | }; 174 | }; 175 | 176 | /** 177 | * Creates an instance of a 3D bullet. 178 | * @param {BABYLON.Camera} camera 179 | * @param {BABYLON.Scene} scene 180 | * @constructor 181 | */ 182 | var Bullet = function (camera, scene) { 183 | var self = this; // HAXX 184 | self.mesh = BABYLON.Mesh.CreateSphere("bullet", 3, SHOTGUN_BULLET_SIZE, scene); 185 | self.mesh.material = new BABYLON.StandardMaterial("bulletTexture", scene); 186 | self.mesh.position = camera.position.clone(); 187 | if (DEBUG) { 188 | self.mesh.material.alpha = 0.8; 189 | } else { 190 | self.mesh.material.alpha = 0; 191 | } 192 | self.speed = BULLET_SPEED; 193 | self.isAlive = true; 194 | self.lifeDuration = null; // How long will the bullet stay "alive" 195 | self.scene = scene; 196 | self.mesh.checkCollisions = true; 197 | 198 | var direction = getForwardVector(camera.rotation); 199 | direction.normalize(); 200 | 201 | var deleteBullet = function () { 202 | if (self.isAlive) { 203 | if (self.lifeDuration) { 204 | window.clearTimeout(self.lifeDuration); 205 | } 206 | 207 | // Mesh destruction 208 | self.mesh.dispose(); 209 | self.lifeDuration = null; 210 | self.isAlive = false; 211 | } 212 | }; 213 | 214 | // After X seconds, delete the bullet from the screen 215 | self.lifeDuration = setTimeout(function () { 216 | deleteBullet(); 217 | BULLETS.splice(self, 1); 218 | }, 1000); 219 | 220 | self.update = function () { 221 | if (!self.isAlive) { 222 | return false; 223 | } 224 | 225 | // Moving the bullet according to the speed 226 | self.mesh.position.x += direction.x * self.speed; 227 | self.mesh.position.y += direction.y * self.speed; 228 | self.mesh.position.z += direction.z * self.speed; 229 | 230 | // Collision testing 231 | 232 | //for ( var i = 0; i < self.scene.meshes.length; i++ ) { 233 | // 234 | // if ( self.mesh.intersectsMesh( self.scene.meshes[ i ], false ) ) { 235 | // 236 | // //for ( var s = 0; s < SPRITES.length; s++ ) { 237 | // if ( self.scene.meshes[ i ].tag === "plane" ) { 238 | // LOG( "TOUCHED PLANE" ); 239 | // self.scene.meshes[ i ].dispose(); 240 | // 241 | // //if ( SPRITES[ i ].hitbox === undefined ) { 242 | // // SPRITES[ i ].dispose(); 243 | // // SPRITES.splice( i, 1 ); 244 | // //} 245 | // //for ( var s = 0; s < SPRITES.length; s++ ) { 246 | // // LOG( "Line 171:" + typeof SPRITES[ s ].type ); 247 | // //} 248 | // } 249 | // //} 250 | // 251 | // } 252 | //} 253 | for (var i = 0; i < SPRITES.length; i++) { 254 | if (self.mesh.intersectsMesh(SPRITES[i].hitbox, false)) { 255 | SPRITES[i].suffer(); 256 | SPRITES[i].dispose(); 257 | SPRITES.splice(i, 1); 258 | self.dispose(); 259 | return true; 260 | } 261 | } 262 | return false; 263 | }; 264 | 265 | self.dispose = function () { 266 | deleteBullet(); 267 | }; 268 | }; 269 | 270 | var playBackgroundMusic = function (scene) { 271 | return new BABYLON.Sound("E1M1", "snds/E1M1.mp3", scene, null, { 272 | loop: true, 273 | autoplay: true, 274 | volume: MUSIC_VOLUME 275 | }); 276 | }; 277 | 278 | var genCubes = function (scene) { 279 | var cubeMaterial = new BABYLON.StandardMaterial("txtCube", scene); 280 | cubeMaterial.diffuseTexture = new BABYLON.Texture("gfx/doom/skulls.png", scene); 281 | 282 | for (var i = 0; i < 20; i++) { 283 | var cube = new BABYLON.Mesh.CreateBox("cube", CUBE_SIZE, scene); 284 | cube.tag = "cube"; 285 | // Random pos 286 | cube.position = new BABYLON.Vector3(getRandomInt(0, 50), CUBE_SIZE / 2, getRandomInt(0, 50)); 287 | cube.material = cubeMaterial; 288 | cube.checkCollisions = true; 289 | } 290 | }; 291 | 292 | // Unused. 293 | var renderWeapon = function (scene, camera) { 294 | var gun = BABYLON.Mesh.CreateBox("gun", 1, scene); 295 | gun.material = new BABYLON.StandardMaterial("gunTxt", scene); 296 | gun.material.diffuseTexture = new BABYLON.Texture("gfx/grass.png", scene); 297 | 298 | gun.scaling = new BABYLON.Vector3(.2, .2, .5); 299 | gun.position.x = .4; 300 | gun.position.y = -0.3; 301 | gun.position.z = 1; 302 | gun.parent = camera; 303 | }; 304 | 305 | var renderDoomguys = function (scene) { 306 | for (var i = 0; i < 10; i++) { 307 | var doomguy = new Monster(scene, null, null, 10, "doomguy", 64, false); 308 | doomguy.checkCollisions = true; 309 | doomguy.hitbox.sprite.position.x = getRandomInt(0, 50); 310 | doomguy.hitbox.sprite.position.z = getRandomInt(0, 50); 311 | doomguy.hitbox.sprite.position.y = 1; 312 | doomguy.hitbox.sprite.size = 2.5; 313 | doomguy.render(); 314 | } 315 | }; 316 | 317 | var renderAnimatedMonsters = function (scene) { 318 | var frames = 2; //2 319 | var delay = 200; // 300 320 | 321 | for (var i = 0; i < 30; i++) { 322 | var imp = new Monster(scene, frames, delay, 100, "imp", 64, true); 323 | imp.checkCollisions = true; 324 | imp.hitbox.sprite.position.x = getRandomInt(0, 50); 325 | imp.hitbox.sprite.position.z = getRandomInt(0, 50); 326 | imp.render(); 327 | } 328 | }; 329 | 330 | var renderAnimatedMarines = function (scene) { 331 | var frames = 3; 332 | var delay = 300; 333 | 334 | for (var i = 0; i < 40; i++) { 335 | var marine = new Monster(scene, frames, delay, 100, "marine", 64, true); 336 | marine.checkCollisions = true; 337 | marine.hitbox.sprite.position.x = getRandomInt(0, 50); 338 | marine.hitbox.sprite.position.z = getRandomInt(0, 50); 339 | marine.render(); 340 | } 341 | }; 342 | 343 | // ============================================================================================================================ 344 | // ============================================================================================================================ 345 | var createScene = function () { 346 | var scene = new BABYLON.Scene(ENGINE); 347 | scene.fogMode = BABYLON.Scene.FOGMODE_EXP; 348 | scene.gravity = new BABYLON.Vector3(0, -9.81, 0); 349 | scene.collisionsEnabled = true; 350 | 351 | var camera = new BABYLON.FreeCamera('camera', new BABYLON.Vector3(0, 10, -20), scene); 352 | camera.applyGravity = true; 353 | camera.checkCollisions = true; 354 | camera.setTarget(BABYLON.Vector3.Zero()); 355 | camera.attachControl(CANVAS, false); 356 | 357 | if (KB_LAYOUT === "QWERTY") { 358 | // QWERTY (master race) 359 | camera.keysUp = [87]; 360 | camera.keysLeft = [65]; 361 | camera.keysRight = [68]; 362 | camera.keysDown = [83]; 363 | } else { 364 | // AZERTY 365 | camera.keysUp = [90]; 366 | camera.keysLeft = [81]; 367 | camera.keysRight = [68]; 368 | camera.keysDown = [83]; 369 | } 370 | 371 | // Request pointer lock 372 | var canvas = ENGINE.getRenderingCanvas(); 373 | canvas.addEventListener("click", function (evt) { 374 | canvas.requestPointerLock = canvas.requestPointerLock || canvas.msRequestPointerLock || canvas.mozRequestPointerLock || canvas.webkitRequestPointerLock; 375 | if (canvas.requestPointerLock) { 376 | canvas.requestPointerLock(); 377 | } 378 | }, false); 379 | // Event listener when the pointerlock event is updated. 380 | var pointerLockChange = function (event) { 381 | this.controlEnabled = (document.mozPointerLockElement === canvas || document.webkitPointerLockElement === canvas || document.msPointerLockElement === canvas || document.pointerLockElement === canvas); 382 | if (this.controlEnabled) { 383 | this.camera.detachControl(canvas); 384 | } else { 385 | this.camera.attachControl(canvas); 386 | } 387 | }; 388 | document.addEventListener("pointerlockchange", pointerLockChange, false); 389 | document.addEventListener("mspointerlockchange", pointerLockChange, false); 390 | document.addEventListener("mozpointerlockchange", pointerLockChange, false); 391 | document.addEventListener("webkitpointerlockchange", pointerLockChange, false); 392 | 393 | var light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene); 394 | 395 | var ground = BABYLON.Mesh.CreatePlane('ground', 500, scene); 396 | ground.tag = "ground"; 397 | ground.rotation.x = Math.PI / 2; // TODO: simplify this (CreateGround()) 398 | ground.checkCollisions = true; 399 | ground.material = new BABYLON.StandardMaterial("txtGround", scene); 400 | ground.material.diffuseTexture = new BABYLON.Texture("gfx/doom/acid.png", scene); 401 | ground.material.diffuseTexture.uScale = 20.0; 402 | ground.material.diffuseTexture.vScale = 20.0; 403 | 404 | genCubes(scene); 405 | renderAnimatedMonsters(scene); 406 | renderAnimatedMarines(scene); 407 | 408 | if (!DEBUG) { 409 | playBackgroundMusic(scene); 410 | } 411 | 412 | var shotgunSfx = new BABYLON.Sound("shotgunSfx", "snds/dsshotgn.wav", scene); 413 | window.addEventListener("click", function (e) { 414 | if (e.button === 0) { 415 | shotgunSfx.play(); 416 | } 417 | 418 | var bullet = new Bullet(camera, scene); 419 | BULLETS.push(bullet); 420 | LOG("Sprites remaining: " + SPRITES.length); 421 | }); 422 | 423 | return scene; 424 | }; 425 | 426 | var scene = createScene(); 427 | 428 | ENGINE.runRenderLoop(function () { 429 | LOG("BULLETS ON SCREEN: " + BULLETS.length); 430 | for (var i = 0; i < BULLETS.length; i++) { 431 | if (BULLETS[i].update()) { 432 | BULLETS[i].dispose(); 433 | BULLETS.splice(i, 1); 434 | } 435 | } 436 | 437 | scene.render(); 438 | }); 439 | } else { 440 | alert("YOUR BROWSER IS NOT SUPPORTED. YOU NEED A RECENT/MODERN WEBGL COMPATIBLE WEB BROWSER TO PLAY THIS GAME."); 441 | } 442 | 443 | window.addEventListener('resize', function () { 444 | ENGINE.resize(); 445 | }); -------------------------------------------------------------------------------- /snds/E1M1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/snds/E1M1.mp3 -------------------------------------------------------------------------------- /snds/dspopain.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/snds/dspopain.wav -------------------------------------------------------------------------------- /snds/dsshotgn.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arc0re/arc0re.github.io/811400e4dd3f98d4d7288b287c84324fadfcba1e/snds/dsshotgn.wav -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | overflow: hidden; 3 | width: 100%; 4 | height: 100%; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | #crosshair { 10 | position: absolute; 11 | top: 50%; 12 | left: 50%; 13 | margin-top: -8px; 14 | margin-left: -8px; 15 | } 16 | 17 | #shotgun { 18 | position: absolute; 19 | width: 240px; 20 | bottom: 0; 21 | left: 50%; 22 | margin-left: -127px; 23 | } 24 | 25 | #renderCanvas { 26 | width: 100%; 27 | height: 100%; 28 | touch-action: none; 29 | } --------------------------------------------------------------------------------