raintalon24

iii | retro arcade

Jul 28th, 2021 (edited)
2,630
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.77 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html>
  3. <!---
  4. UNDEAD MAGIKARP THEMES
  5. iii | retro arcade
  6. http://undeadmagikarp.tumblr.com/
  7.  
  8. General theme/page rules apply. Thank you!
  9.  
  10. --->
  11.  
  12. <head>
  13. <title>{Title}</title>
  14. {block:Description}
  15. <meta name="description" content="{MetaDescription}" />
  16. {/block:Description}
  17. <link rel="shorcut icon" href="{Favicon}" />
  18.  
  19. <!---FONTS--->
  20. <link rel="preconnect" href="https://fonts.gstatic.com" />
  21. <link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet" />
  22.  
  23. <!-- script on DOM load -->
  24. <script>
  25. document.addEventListener("DOMContentLoaded", function () {
  26. // Number leaderboard
  27. var numbers = document.getElementsByClassName("col-number");
  28. for (var i = 1; i < numbers.length; i++) {
  29. numbers[i].innerHTML = i;
  30. }
  31. // Randomly generate follow and message points
  32. var following = document.getElementsByClassName("following");
  33. for (var j = 0; j < following.length; j++) {
  34. var nameLength = following[j].getElementsByClassName("name")[0].innerText.length;
  35. var followPoints = nameLength * 13 + 24;
  36. var messagePoints = nameLength * 2 + 23;
  37. following[j].getElementsByClassName("follow-link")[0].innerHTML = "+" + followPoints.toString();
  38. following[j].getElementsByClassName("message-link")[0].innerHTML = "-" + messagePoints.toString();
  39. }
  40. });
  41. </script>
  42.  
  43. <style type="text/css">
  44. body {
  45. margin: 0;
  46. padding: 0;
  47. word-wrap: break-word;
  48. color: black;
  49. background-color: black;
  50. font-family: "Press Start 2P", cursive;
  51. }
  52.  
  53. /**gets rid of iframe**/
  54. body > iframe:first-child {
  55. display: none !important;
  56. }
  57.  
  58. a {
  59. text-decoration: none;
  60. }
  61.  
  62. #container {
  63. position: absolute;
  64. width: 80%;
  65. height: 80%;
  66. top: 10%;
  67. left: 10%;
  68. background-color: black;
  69. background-image: url(https://static.tumblr.com/bkdoxe7/8ysqwxt6g/pixel-gif-stars-2.gif);
  70. background-repeat: repeat;
  71. border-radius: 65px;
  72. }
  73.  
  74. /**line effect across screen**/
  75. #container:after {
  76. content: "";
  77. position: fixed;
  78. top: 0;
  79. left: 0;
  80. height: 100%;
  81. width: 100%;
  82. overflow: hidden;
  83. background: -webkit-gradient(linear, left top, left bottom, color-stop(50%, transparent), color-stop(50%, rgba(0, 0, 0, 0.25)));
  84. background: linear-gradient(180deg, transparent 50%, rgba(0, 0, 0, 0.25) 0);
  85. background-size: 100% 4px;
  86. opacity: 0.5;
  87. z-index: 100;
  88. pointer-events: none;
  89. }
  90.  
  91. #title {
  92. position: absolute;
  93. top: 50%;
  94. left: 50%;
  95. z-index: 90;
  96. transform: translate(-50%, calc(-50% - 30px));
  97. color: white;
  98. width: 700px;
  99. text-align: center;
  100. -webkit-touch-callout: none; /* iOS Safari */
  101. -webkit-user-select: none; /* Safari */
  102. -khtml-user-select: none; /* Konqueror HTML */
  103. -moz-user-select: none; /* Old versions of Firefox */
  104. -ms-user-select: none; /* Internet Explorer/Edge */
  105. user-select: none;
  106. }
  107.  
  108. #title h1 {
  109. color: white;
  110. font-size: 58px;
  111. animation: glow 3s ease-in-out infinite alternate;
  112. -webkit-animation: glow 3s ease-in-out infinite alternate;
  113. -moz-animation: glow 3s ease-in-out infinite alternate;
  114. }
  115.  
  116. @-webkit-keyframes glow {
  117. from {
  118. text-shadow: 0 0 5px #ff006c, 0 0 10px #ff006c, 0 0 15px #ff006c, 0 0 20px #ff417d, 0 0 35px #ff417d, 0 0 40px #ff417d, 0 0 50px #ff417d, 0 0 75px #ff417d;
  119. }
  120. to {
  121. text-shadow: 0 0 10px #ff006c, 0 0 20px #ff006c, 0 0 30px #ff006c, 0 0 40px #ff417d, 0 0 70px #ff417d, 0 0 80px #ff417d, 0 0 100px #ff417d, 0 0 150px #ff417d;
  122. }
  123. }
  124.  
  125. .subtitle1 {
  126. position: absolute;
  127. bottom: 90%;
  128. color: #00ff38;
  129. font-family: inherit;
  130. font-size: 32px;
  131. width: 700px;
  132. height: auto;
  133. }
  134.  
  135. .subtitle2 {
  136. position: absolute;
  137. top: 90%;
  138. color: #ccc;
  139. font-family: inherit;
  140. font-size: 16px;
  141. width: 700px;
  142. height: auto;
  143. }
  144.  
  145. .navbar {
  146. position: absolute;
  147. top: 0;
  148. display: flex;
  149. justify-content: space-evenly;
  150. overflow: hidden;
  151. width: 100%;
  152. height: 75px;
  153. z-index: 50;
  154. }
  155.  
  156. /* Style the buttons that are used to open the tab content */
  157. .navbar button {
  158. background-color: inherit;
  159. border: none;
  160. outline: none;
  161. cursor: pointer; /**CHANGE***/
  162. padding: 14px 5px;
  163. text-transform: uppercase;
  164. }
  165.  
  166. .navbar button.active p {
  167. text-decoration: underline 3px white;
  168. text-shadow: 0 0 5px #ff006c, 0 0 10px #ff006c, 0 0 15px #ff006c, 0 0 20px #ff417d, 0 0 25px #ff417d;
  169. }
  170.  
  171. .navbar button p,
  172. .navbar button a {
  173. font-family: "Press Start 2P", cursive;
  174. display: inline-block;
  175. font-size: 16px;
  176. color: white;
  177. transition: all 0.5s ease;
  178. -webkit-transition: all 0.5s ease;
  179. -moz-transition: all 0.5s ease;
  180. -ms-transition: all 0.5s ease;
  181. -o-transition: all 0.5s ease;
  182. }
  183.  
  184. .navbar button p:hover,
  185. .navbar button a:hover {
  186. text-shadow: 0 0 5px #ff006c, 0 0 10px #ff006c, 0 0 15px #ff006c, 0 0 20px #ff417d, 0 0 25px #ff417d;
  187. }
  188.  
  189. /* Style the tab content */
  190. .tabcontent {
  191. display: none;
  192. position: absolute;
  193. top: 75px;
  194. height: calc(100% - 105px); /* note: takes up space behind navbar */
  195. width: 100%;
  196. animation: fadeIn 1s;
  197. color: white;
  198. font-size: 13px;
  199. overflow: hidden;
  200. overflow-y: scroll;
  201. padding-bottom: 30px;
  202. -ms-overflow-style: none; /* Internet Explorer 10+ */
  203. scrollbar-width: none; /* Firefox */
  204. }
  205.  
  206. .tabcontent::-webkit-scrollbar {
  207. display: none; /* Safari and Chrome */
  208. }
  209.  
  210. .tabcontent table {
  211. margin: 0 auto;
  212. width: 95%;
  213. border-collapse: separate;
  214. border-spacing: 4px;
  215. border-radius: 0;
  216. border: 2px solid black;
  217. background: none;
  218. }
  219.  
  220. .tabcontent th {
  221. border: 0;
  222. margin-bottom: 2px;
  223. text-align: center;
  224. vertical-align: middle;
  225. padding: 0.5em;
  226. background: black;
  227. padding: 12px;
  228. }
  229.  
  230. .tabcontent a {
  231. color: #00ff38;
  232. text-decoration: underline;
  233. }
  234.  
  235. .tabcontent a:hover {
  236. color: white;
  237. }
  238.  
  239. .col-number,
  240. .follow,
  241. .message {
  242. width: 0;
  243. }
  244.  
  245. .avatar {
  246. width: 0;
  247. padding-top: 2px;
  248. padding-bottom: 2px;
  249. }
  250.  
  251. .avatar img {
  252. border-radius: 50%;
  253. height: 37px;
  254. width: 37px;
  255. }
  256.  
  257. .name {
  258. word-break: break-all;
  259. min-width: 55px;
  260. max-width: 250px;
  261. }
  262.  
  263. .catchphrase {
  264. min-width: 143px;
  265. word-break: break-word;
  266. }
  267.  
  268. @keyframes fadeIn {
  269. from {
  270. opacity: 0;
  271. }
  272. to {
  273. opacity: 1;
  274. }
  275. }
  276.  
  277. @keyframes fadeOut {
  278. from {
  279. opacity: 1;
  280. }
  281. to {
  282. opacity: 0;
  283. }
  284. }
  285.  
  286. .emoji {
  287. position: relative;
  288. font-family: inherit;
  289. font-size: 16px;
  290. display: inline-block;
  291. line-height: 16px;
  292. top: -3px;
  293. margin-right: 7px;
  294. }
  295.  
  296. .emoji img {
  297. position: relative;
  298. width: 20px;
  299. height: 20px;
  300. display: inline-block;
  301. margin-right: 4px;
  302. top: 4px;
  303. }
  304.  
  305. .number {
  306. font-family: "Press Start 2P", cursive;
  307. font-size: 16px;
  308. color: #00ff38;
  309. margin-left: 8px;
  310. }
  311.  
  312. #play {
  313. text-transform: uppercase;
  314. background-color: #ffdd57;
  315. border-radius: 290486px;
  316. color: rgba(0, 0, 0, 0.7);
  317. position: absolute;
  318. top: calc(90% + 75px);
  319. font-family: inherit;
  320. font-size: 16px;
  321. padding: 12px;
  322. width: max-content;
  323. height: auto;
  324. display: block;
  325. left: 50%;
  326. -webkit-transform: translateX(-50%);
  327. transform: translateX(-50%);
  328. padding-left: 18px;
  329. cursor: pointer;
  330. }
  331.  
  332. #back {
  333. margin-left: 15px;
  334. }
  335.  
  336. canvas {
  337. display: block;
  338. height: 100%;
  339. width: 100%;
  340. border-radius: 65px;
  341. animation: fadeIn 1s;
  342. }
  343.  
  344. .dialogue__content h1 {
  345. font-size: 3rem;
  346. margin-bottom: 0.5em;
  347. line-height: 1.2em;
  348. color: white;
  349. animation: glow 3s ease-in-out infinite alternate;
  350. -webkit-animation: glow 3s ease-in-out infinite alternate;
  351. -moz-animation: glow 3s ease-in-out infinite alternate;
  352. }
  353.  
  354. .dialogue__content ul {
  355. margin-bottom: 2rem;
  356. }
  357.  
  358. .dialogue__content li {
  359. color: #00ff38;
  360. font-size: 0.8rem;
  361. margin-bottom: 1em;
  362. text-transform: uppercase;
  363. list-style-type: none;
  364. }
  365.  
  366. .dialogue__content button {
  367. border-radius: 5px;
  368. appearance: none;
  369. background-color: white;
  370. border: 1px solid white;
  371. cursor: pointer;
  372. font-family: inherit;
  373. font-size: 1rem;
  374. outline: none;
  375. padding: 0.7em 0.85em 0.6em 1em;
  376. text-transform: uppercase;
  377. transition: all 0.2s linear;
  378. }
  379.  
  380. .dialogue__content button:hover,
  381. .dialogue__content button:active {
  382. background-color: transparent;
  383. border: 1px solid #00ff38;
  384. color: #00ff38;
  385. }
  386.  
  387. .dialogue {
  388. z-index: 20;
  389. align-items: center;
  390. background-color: transparent;
  391. bottom: 0;
  392. display: flex;
  393. justify-content: center;
  394. left: 0;
  395. opacity: 1;
  396. position: fixed;
  397. right: 0;
  398. text-align: center;
  399. top: 0;
  400. transform: translateX(0);
  401. animation: fadeIn 1s;
  402. }
  403.  
  404. .dialogue--hidden {
  405. $duration: 0.3s;
  406. opacity: 0;
  407. transform: translateX(-100vw);
  408. transition: opacity $duration linear 0s, transform 0s linear $duration;
  409. }
  410.  
  411. .dialogue__content {
  412. max-width: 31.25rem; // 500px / 16px
  413. padding: 18px;
  414. }
  415.  
  416. .key {
  417. border: 1px solid white;
  418. border-radius: 5px;
  419. display: inline-block;
  420. padding: 0.8em;
  421. border-color: white;
  422. color: white;
  423. }
  424.  
  425. .key--arrow {
  426. font-size: 1.8rem;
  427. padding: 0.35em 0.1em 0.6em;
  428. position: relative;
  429. line-height: 0.3;
  430. top: 0.05em;
  431. }
  432.  
  433. .hud {
  434. box-sizing: border-box;
  435. display: flex;
  436. justify-content: flex-start;
  437. margin-top: 0;
  438. margin-left: 15px;
  439. list-style-type: none;
  440. color: #00ff38;
  441. opacity: 1;
  442. padding: 1rem;
  443. position: fixed;
  444. transition: opacity 0.07s linear 0.5s;
  445. width: 100%;
  446. }
  447.  
  448. .hud--hidden {
  449. opacity: 0;
  450. }
  451.  
  452. .hud__score {
  453. margin: 0;
  454. }
  455. </style>
  456. </head>
  457.  
  458. <body>
  459. <div id="container">
  460. <!-- Navbar links -->
  461. <div class="navbar">
  462. <button class="tablinks" onclick="openCity(event, 'Home')" id="defaultOpen"><p>home</p></button>
  463. <button class="tablinks" title="Blogroll" onclick="openCity(event, 'Leaderboard')">
  464. <span class="emoji">🏆</span>
  465. <p>leaderboard</p>
  466. </button>
  467.  
  468. <button class="tablinks">
  469. <span class="emoji"><img src="https://static.tumblr.com/bkdoxe7/Bgyqs5z1p/coin.gif" /></span>
  470. <!---CUSTOM LINK HERE--->
  471. <a href="/">link 1</a>
  472. </button>
  473.  
  474. <button class="tablinks"><span class="emoji">⭐</span><a href="http://undeadmagikarp.tumblr.com/">credits</a><span class="number">1</span></button><!---DO NOT REMOVE THE CREDIT.--->
  475. <button class="tablinks" id="quit"><a href="/" title="Return to blog">quit</a></button>
  476. </div>
  477.  
  478. <!-- Navbar content -->
  479. <div id="Home" class="tabcontent">
  480. <div id="title">
  481. <div class="subtitle1">SUBTITLE 1</div>
  482. <h1>PAGE TITLE</h1>
  483. <div class="subtitle2">SUBTITLE 2</div>
  484. <button id="play">Play now!</button>
  485. </div>
  486. </div>
  487.  
  488. <div id="Leaderboard" class="tabcontent">
  489. <table>
  490. <tr>
  491. <th class="col-number">#</th>
  492. <th class="avatar">Avatar</th>
  493. <th class="name" title="Username">Name</th>
  494. <th class="catchphrase" title="Blog title">Catchphrase</th>
  495. <th class="follow">Follow</th>
  496. <th class="message">Message</th>
  497. </tr>
  498. {block:Following} {block:Followed}
  499. <tr class="following">
  500. <th class="col-number"></th>
  501. <th class="avatar" style="padding: 8px;"><img src="{FollowedPortraitURL-40}" /></th>
  502. <th class="name"><a href="{FollowedURL}">{FollowedName}</a></th>
  503. <th class="catchphrase">{FollowedTitle}</th>
  504. <th class="follow"><a class="follow-link" title="Follow {FollowedName}" href="https://tumblr.com/follow/{FollowedName}">+0</a></th>
  505. <th class="message"><a class="message-link" title="Message {FollowedName}" href="https://www.tumblr.com/message/{FollowedName}">-0</a></th>
  506. </tr>
  507. {/block:Followed} {/block:Following}
  508. </table>
  509. </div>
  510. </div>
  511.  
  512. <!---JAVASCRIPT STARTS HERE--->
  513. <script>
  514. function openCity(evt, tabName) {
  515. var i, tabcontent, tablinks;
  516. tabcontent = document.getElementsByClassName("tabcontent");
  517. for (i = 0; i < tabcontent.length; i++) {
  518. tabcontent[i].style.display = "none";
  519. }
  520. tablinks = document.getElementsByClassName("tablinks");
  521. for (i = 0; i < tablinks.length; i++) {
  522. tablinks[i].className = tablinks[i].className.replace(" active", "");
  523. }
  524. document.getElementById(tabName).style.display = "block";
  525. evt.currentTarget.className += " active";
  526. }
  527.  
  528. var homePage;
  529.  
  530. function clearHome(store) {
  531. var parent = document.getElementById("Home");
  532. if (store) {
  533. homePage = parent.innerHTML;
  534. };
  535. while (parent.firstChild) parent.removeChild(parent.firstChild);
  536. return parent;
  537. }
  538.  
  539. function goBackHome() {
  540. document.getElementById("container").removeChild(stage);
  541. const parent = clearHome(false);
  542. parent.innerHTML = homePage;
  543. document.getElementById("play").addEventListener("click", playNow);
  544. }
  545.  
  546. // game code start
  547.  
  548. const DEV_MODE = false;
  549.  
  550. const stage = document.createElement("canvas");
  551. var ctx;
  552. var dialogue;
  553. var hud;
  554. var scoreNode;
  555.  
  556. let ship,
  557. lasers = [],
  558. enemies = [],
  559. playing = false,
  560. gameStarted = false,
  561. speedMultiplier,
  562. enemySeedFrameInterval,
  563. score = 0,
  564. tick = 0,
  565. laserTick = 0;
  566.  
  567. function randomBetween(min, max) {
  568. return Math.floor(Math.random() * (max - min + 1)) + min;
  569. }
  570.  
  571. function calcScore(x) {
  572. return Math.floor((1 / x) * 500);
  573. }
  574.  
  575. function Ship(options) {
  576. this.radius = 15;
  577. this.x = options.x || stage.width * 0.5 - this.radius - 0.5;
  578. this.y = options.y || stage.height - this.radius - 30;
  579. this.width = this.radius * 2;
  580. this.height = this.width;
  581. this.color = options.color || "red";
  582. this.left = false;
  583. this.right = false;
  584. this.speed = 10;
  585. this.active = true;
  586.  
  587. document.addEventListener("keydown", this.onKeyDown.bind(this));
  588. document.addEventListener("keyup", this.onKeyUp.bind(this));
  589. }
  590.  
  591. Ship.prototype.update = function (x) {
  592. this.x = x;
  593. this.y = stage.height - this.radius - 30;
  594. };
  595.  
  596. Ship.prototype.draw = function () {
  597. ctx.save();
  598.  
  599. if (DEV_MODE) {
  600. ctx.fillStyle = "skyblue";
  601. ctx.fillRect(this.x, this.y, this.width, this.width);
  602. }
  603.  
  604. ctx.fillStyle = this.color;
  605. ctx.fillRect(this.x + this.radius - 5, this.y, 10, this.radius);
  606. ctx.fillRect(this.x, this.y + this.radius, this.width, 10);
  607. ctx.fillRect(this.x, this.y + this.radius + 10, 10, 5);
  608. ctx.fillRect(this.x + this.width - 10, this.y + this.radius + 10, 10, 5);
  609.  
  610. ctx.restore();
  611. };
  612.  
  613. Ship.prototype.onKeyDown = function (e) {
  614. if (ship.active) {
  615. if (e.keyCode === 39) this.right = true;
  616. else if (e.keyCode === 37) this.left = true;
  617.  
  618. if (e.keyCode == 32 && !this.shooting) {
  619. this.shooting = true;
  620. laserTick = 0;
  621. }
  622. }
  623. };
  624.  
  625. Ship.prototype.onKeyUp = function (e) {
  626. if (e.key === "ArrowRight") this.right = false;
  627. else if (e.key === "ArrowLeft") this.left = false;
  628. else if (e.keyCode == 32) this.shooting = false;
  629. };
  630.  
  631. function Laser(options) {
  632. this.x = options.x - 0.5;
  633. this.y = options.y || stage.height - 50;
  634. this.width = 6;
  635. this.height = 20;
  636. this.speed = 15;
  637. this.color = options.color || "white";
  638. this.active = true;
  639. }
  640.  
  641. Laser.prototype.update = function (y) {
  642. this.y = y;
  643. };
  644.  
  645. Laser.prototype.draw = function () {
  646. ctx.save();
  647. ctx.fillStyle = this.color;
  648. ctx.beginPath();
  649. ctx.rect(this.x, this.y, this.width, this.height);
  650. ctx.closePath();
  651. ctx.fill();
  652. ctx.restore();
  653. };
  654.  
  655. function Enemy(options) {
  656. this.radius = randomBetween(10, 40);
  657. this.width = this.radius * 2;
  658. this.height = this.width;
  659. this.x = randomBetween(0, stage.width - this.width);
  660. this.y = -this.radius * 2;
  661. this.color = options != undefined && options.color ? options.color : "#896ce5";
  662. this.speed = 2;
  663. this.active = true;
  664. }
  665.  
  666. Enemy.prototype.update = function (x, y) {
  667. this.x = x;
  668. this.y = y;
  669. };
  670.  
  671. Enemy.prototype.draw = function () {
  672. if (DEV_MODE) {
  673. ctx.fillStyle = "skyblue";
  674. ctx.fillRect(this.x, this.y, this.width, this.width);
  675. }
  676.  
  677. ctx.save();
  678. ctx.fillStyle = this.color;
  679. ctx.beginPath();
  680. ctx.arc(this.x + this.radius, this.y + this.radius, this.radius, 0, Math.PI * 2);
  681. ctx.closePath();
  682. ctx.fill();
  683. ctx.restore();
  684. };
  685.  
  686. function hitTest(item1, item2) {
  687. let collision = true;
  688. if (item1.x > item2.x + item2.width || item1.y > item2.y + item2.height || item2.x > item1.x + item1.width || item2.y > item1.y + item1.height) {
  689. collision = false;
  690. }
  691. return collision;
  692. }
  693.  
  694. function handleLaserCollision() {
  695. for (let enemy of enemies) {
  696. for (let laser of lasers) {
  697. let collision = hitTest(laser, enemy);
  698. if (collision && laser.active) {
  699. console.log("you destroyed an enemy");
  700. enemy.active = false;
  701. laser.active = false;
  702.  
  703. // increase enemy speed and frequency of enemy spawns
  704. speedMultiplier += 0.025;
  705. if (enemySeedFrameInterval > 20) {
  706. enemySeedFrameInterval -= 2;
  707. }
  708.  
  709. // increase score
  710. score += calcScore(enemy.radius);
  711. scoreNode.textContent = score;
  712. }
  713. }
  714. }
  715. }
  716.  
  717. function handleShipCollision() {
  718. // check for collisions between ship and enemies
  719. if (enemies.length) {
  720. for (let enemy of enemies) {
  721. let collision = hitTest(ship, enemy);
  722. if (collision) {
  723. console.log("your ship was destroyed");
  724. ship.active = false;
  725. setTimeout(() => {
  726. ship.active = true;
  727. speedMultiplier = 1;
  728. enemySeedFrameInterval = 100;
  729. score = 0;
  730. scoreNode.textContent = score;
  731. }, 2000);
  732. }
  733. }
  734. }
  735. }
  736.  
  737. function drawShip(xPosition) {
  738. if (ship.active) {
  739. ship.update(xPosition);
  740. ship.draw();
  741. }
  742. }
  743.  
  744. function drawEnemies() {
  745. if (enemies.length) {
  746. for (let enemy of enemies) {
  747. // draw an enemy if it's active
  748. if (enemy.active) {
  749. enemy.update(enemy.x, (enemy.y += enemy.speed * speedMultiplier));
  750. enemy.draw();
  751. }
  752. }
  753. }
  754. }
  755.  
  756. function enemyCleanup() {
  757. if (enemies.length) {
  758. enemies = enemies.filter((enemy) => {
  759. let visible = enemy.y < stage.height + enemy.width;
  760. let active = enemy.active === true;
  761. return visible && active;
  762. });
  763. }
  764. }
  765.  
  766. function drawLasers() {
  767. if (lasers.length) {
  768. for (let laser of lasers) {
  769. if (laser.active) {
  770. laser.update((laser.y -= laser.speed));
  771. laser.draw();
  772. }
  773. }
  774. }
  775. }
  776.  
  777. function laserCleanup() {
  778. lasers = lasers.filter((laser) => {
  779. let visible = laser.y > -laser.height;
  780. let active = laser.active === true;
  781. return visible && active;
  782. });
  783. }
  784.  
  785. function render(delta) {
  786. if (playing) {
  787. let xPos = ship.x;
  788.  
  789. // seed new enemies
  790. if (tick % enemySeedFrameInterval === 0 && ship.active) {
  791. const enemy = new Enemy();
  792. enemies.push(enemy);
  793. console.log({ enemySeedFrameInterval, speedMultiplier });
  794. }
  795.  
  796. // background
  797. ctx.save();
  798. ctx.fillStyle = "#272744";
  799. ctx.fillRect(0, 0, stage.width, stage.height);
  800. ctx.restore();
  801.  
  802. // ship movement
  803. if (ship.left) xPos = ship.x -= ship.speed;
  804. else if (ship.right) xPos = ship.x += ship.speed;
  805.  
  806. // stage boundaries
  807. if (gameStarted) {
  808. if (xPos < 0) xPos = 0;
  809. else if (xPos > stage.width - ship.width) xPos = stage.width - ship.width;
  810. }
  811.  
  812. // create lasers, if shooting
  813. if (ship.active && ship.shooting) {
  814. if (laserTick === 0 || laserTick % 10 === 0) {
  815. let laser = new Laser({
  816. color: "skyblue",
  817. x: ship.x + ship.radius - 3,
  818. });
  819. lasers.push(laser);
  820. }
  821. }
  822.  
  823. drawShip(xPos);
  824.  
  825. handleShipCollision();
  826. handleLaserCollision();
  827.  
  828. drawLasers();
  829. drawEnemies();
  830.  
  831. enemyCleanup();
  832. laserCleanup();
  833.  
  834. if (ship.shooting) laserTick++;
  835. tick++;
  836. }
  837.  
  838. requestAnimationFrame(render);
  839. }
  840.  
  841. function quitGame() {
  842. console.log("stopping game");
  843. const quit = document.getElementById("quit");
  844. quit.title = "";
  845. quit.style.textShadow = "none";
  846. quit.innerHTML = '<a href="/" title="Return to blog">quit</a>';
  847. window.removeEventListener("resize", onResize);
  848. ship.x = -100;
  849. ship.y = -100;
  850. gameStarted = false;
  851. playing = false;
  852. goBackHome();
  853. }
  854.  
  855. function startGame(e) {
  856. console.log("starting game");
  857. // redo quit button
  858. const quit = document.getElementById("quit");
  859. quit.addEventListener("click", quitGame);
  860. quit.innerHTML = "<p>quit</p>";
  861. quit.title = "Quit game";
  862. quit.style.textShadow = "0 0 5px #ff006c, 0 0 10px #ff006c, 0 0 15px #ff006c, 0 0 20px #ff417d, 0 0 25px #ff417d";
  863.  
  864. dialogue.classList.add("dialogue--hidden");
  865. hud.classList.remove("hud--hidden");
  866. e.currentTarget.blur();
  867.  
  868. // reset the demo/intro to the actual game settings:
  869. speedMultiplier = 1;
  870. enemySeedFrameInterval = 100;
  871. ship.x = stage.width * 0.5 - ship.radius - 0.5;
  872. ship.y = stage.height - ship.radius - 30;
  873. enemies = [];
  874. gameStarted = true;
  875. }
  876.  
  877. function onResize() {
  878. stage.width = window.innerWidth;
  879. stage.height = window.innerHeight;
  880. }
  881.  
  882. // game code end
  883.  
  884. function playNow() {
  885. // clear out home panel
  886. const parent = clearHome(true);
  887. // add start menu instructions
  888. parent.innerHTML =
  889. '<div class="dialogue"><div class="dialogue__content"><h1>Space Shooter</h1><ul><li>Use the <span class="key key--arrow">&larr;</span> and <span class="key key--arrow">&rarr;</span> keys to move.</li><li>Use <span class="key">spacebar</span> to fire lasers.</li></ul><button id="start">Start</button><button id="back">Back</button></div></div><ul class="hud hud--hidden"><li class="hud__score">Score: <span>0</span></li></ul>';
  890.  
  891. document.getElementById("start").addEventListener("click", startGame);
  892. document.getElementById("back").addEventListener("click", goBackHome);
  893.  
  894. (ctx = stage.getContext("2d")), (dialogue = document.querySelector(".dialogue"));
  895. (hud = document.querySelector(".hud")), (scoreNode = hud.querySelector(".hud__score span"));
  896.  
  897. window.addEventListener("resize", onResize);
  898.  
  899. document.getElementById("container").appendChild(stage);
  900. onResize();
  901.  
  902. //start the ship off-screen:
  903. ship = new Ship({ color: "#FF3188", x: -100, y: -100 });
  904. // up some ridiculous enemy speeds for the intro:
  905. (speedMultiplier = 6), (enemySeedFrameInterval = 20);
  906. playing = true;
  907. render();
  908. }
  909.  
  910. document.getElementById("defaultOpen").click();
  911. document.getElementById("play").addEventListener("click", playNow);
  912. </script>
  913. </body>
  914. </html>
Add Comment
Please, Sign In to add comment