fixed shield pop out bug, game balance

This commit is contained in:
landgreen
2019-12-23 16:47:11 -08:00
parent 989ebc478b
commit 13fabd8480
10 changed files with 326 additions and 273 deletions

View File

@@ -19,10 +19,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Browser-based side scrolling video game with the matter.js physics engine.">
<meta name="author" content="Ross Landgreen">
<meta property="og:description" content="Browser-based side scrolling video game with the matter.js physics engine.">
<meta property="og:description"
content="Browser-based side scrolling video game with the matter.js physics engine.">
<meta property="og:title" content="n-gon">
<meta name="twitter:title" content="n-gon">
<meta name="twitter:description" content="Browser-based side scrolling video game with the matter.js physics engine.">
<meta name="twitter:description"
content="Browser-based side scrolling video game with the matter.js physics engine.">
<title>n-gon</title>
<link rel="stylesheet" href="style.css">
@@ -86,6 +88,17 @@
</div>
</details>
</div> -->
<!-- <div id="choose-grid">
<div class="build-grid-module" style="font-size: 1.05em; line-height: 170%;">
Choose five power ups.<br>Click start to begin.
</div>
<div class="build-grid-module" style="font-size: 1.05em; line-height: 170%;">
Choose five power ups.<br>Click start to begin.
</div>
<div class="build-grid-module" style="font-size: 1.05em; line-height: 170%;">
Choose five power ups.<br>Click start to begin.
</div>
</div> -->
<div id="build-grid"></div>
<!-- <button type="button" id="build-button">challenge run</button> -->
<svg class="SVG-button" id="build-button" width="110" height="40">
@@ -98,7 +111,9 @@
<details>
<summary>settings</summary>
<div style="line-height: 150%;" id="details-div">
<label for="difficulty-select" title="effects: number of mobs, damage done by mobs, damage done to mobs, mob speed">combat difficulty:</label>
<label for="difficulty-select"
title="effects: number of mobs, damage done by mobs, damage done to mobs, mob speed">combat
difficulty:</label>
<select name="difficulty-select" id="difficulty-select">
<option value="easy">easy</option>
<option value="0" selected>normal</option>
@@ -106,7 +121,8 @@
<option value="8">why...</option>
</select>
<br>
<label for="body-damage" title="allow damage from heavy, fast moving blocks">collision damage from blocks:</label>
<label for="body-damage" title="allow damage from heavy, fast moving blocks">collision damage from
blocks:</label>
<input type="checkbox" id="body-damage" name="body-damage" checked style="width:16px; height:16px;">
<br>
<label for="fps-select" title="use this to slow the game down">frames per second cap:</label>
@@ -166,23 +182,28 @@
fill: #1B1F23;
}
</style>
<path class="st0" d="M142.8 120.1c-5.7 0-10.2 4.9-10.2 11s4.6 11 10.2 11c5.7 0 10.2-4.9 10.2-11s-4.6-11-10.2-11zM106.3 120.1c-5.7 0-10.2 4.9-10.2 11s4.6 11 10.2 11c5.7 0 10.2-4.9 10.2-11 .1-6.1-4.5-11-10.2-11z" />
<path class="st0" d="M191.4 36.9h-134c-11.3 0-20.5 9.2-20.5 20.5v134c0 11.3 9.2 20.5 20.5 20.5h113.4l-5.3-18.3 12.8 11.8 12.1 11.1 21.6 18.7V57.4c-.1-11.3-9.3-20.5-20.6-20.5zm-38.6 129.5s-3.6-4.3-6.6-8c13.1-3.7 18.1-11.8 18.1-11.8-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.4-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.6-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.2-1.8-1-2.8-1.7-2.8-1.7s4.8 7.9 17.5 11.7c-3 3.8-6.7 8.2-6.7 8.2-22.1-.7-30.5-15.1-30.5-15.1 0-31.9 14.4-57.8 14.4-57.8 14.4-10.7 28-10.4 28-10.4l1 1.2c-18 5.1-26.2 13-26.2 13s2.2-1.2 5.9-2.8c10.7-4.7 19.2-5.9 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.5 0 0-7.9-7.5-24.9-12.6l1.4-1.6s13.7-.3 28 10.4c0 0 14.4 25.9 14.4 57.8 0-.1-8.4 14.3-30.5 15zM303.8 79.7h-33.2V117l22.1 19.9v-36.2h11.8c7.5 0 11.2 3.6 11.2 9.4v27.7c0 5.8-3.5 9.7-11.2 9.7h-34v21.1h33.2c17.8.1 34.5-8.8 34.5-29.2v-29.8c.1-20.8-16.6-29.9-34.4-29.9zm174 59.7v-30.6c0-11 19.8-13.5 25.8-2.5l18.3-7.4c-7.2-15.8-20.3-20.4-31.2-20.4-17.8 0-35.4 10.3-35.4 30.3v30.6c0 20.2 17.6 30.3 35 30.3 11.2 0 24.6-5.5 32-19.9l-19.6-9c-4.8 12.3-24.9 9.3-24.9-1.4zM417.3 113c-6.9-1.5-11.5-4-11.8-8.3.4-10.3 16.3-10.7 25.6-.8l14.7-11.3c-9.2-11.2-19.6-14.2-30.3-14.2-16.3 0-32.1 9.2-32.1 26.6 0 16.9 13 26 27.3 28.2 7.3 1 15.4 3.9 15.2 8.9-.6 9.5-20.2 9-29.1-1.8l-14.2 13.3c8.3 10.7 19.6 16.1 30.2 16.1 16.3 0 34.4-9.4 35.1-26.6 1-21.7-14.8-27.2-30.6-30.1zm-67 55.5h22.4V79.7h-22.4v88.8zM728 79.7h-33.2V117l22.1 19.9v-36.2h11.8c7.5 0 11.2 3.6 11.2 9.4v27.7c0 5.8-3.5 9.7-11.2 9.7h-34v21.1H728c17.8.1 34.5-8.8 34.5-29.2v-29.8c0-20.8-16.7-29.9-34.5-29.9zm-162.9-1.2c-18.4 0-36.7 10-36.7 30.5v30.3c0 20.3 18.4 30.5 36.9 30.5 18.4 0 36.7-10.2 36.7-30.5V109c0-20.4-18.5-30.5-36.9-30.5zm14.4 60.8c0 6.4-7.2 9.7-14.3 9.7-7.2 0-14.4-3.1-14.4-9.7V109c0-6.5 7-10 14-10 7.3 0 14.7 3.1 14.7 10v30.3zM682.4 109c-.5-20.8-14.7-29.2-33-29.2h-35.5v88.8h22.7v-28.2h4l20.6 28.2h28L665 138.1c10.7-3.4 17.4-12.7 17.4-29.1zm-32.6 12h-13.2v-20.3h13.2c14.1 0 14.1 20.3 0 20.3z" />
<path class="st0"
d="M142.8 120.1c-5.7 0-10.2 4.9-10.2 11s4.6 11 10.2 11c5.7 0 10.2-4.9 10.2-11s-4.6-11-10.2-11zM106.3 120.1c-5.7 0-10.2 4.9-10.2 11s4.6 11 10.2 11c5.7 0 10.2-4.9 10.2-11 .1-6.1-4.5-11-10.2-11z" />
<path class="st0"
d="M191.4 36.9h-134c-11.3 0-20.5 9.2-20.5 20.5v134c0 11.3 9.2 20.5 20.5 20.5h113.4l-5.3-18.3 12.8 11.8 12.1 11.1 21.6 18.7V57.4c-.1-11.3-9.3-20.5-20.6-20.5zm-38.6 129.5s-3.6-4.3-6.6-8c13.1-3.7 18.1-11.8 18.1-11.8-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.4-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.6-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.2-1.8-1-2.8-1.7-2.8-1.7s4.8 7.9 17.5 11.7c-3 3.8-6.7 8.2-6.7 8.2-22.1-.7-30.5-15.1-30.5-15.1 0-31.9 14.4-57.8 14.4-57.8 14.4-10.7 28-10.4 28-10.4l1 1.2c-18 5.1-26.2 13-26.2 13s2.2-1.2 5.9-2.8c10.7-4.7 19.2-5.9 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.5 0 0-7.9-7.5-24.9-12.6l1.4-1.6s13.7-.3 28 10.4c0 0 14.4 25.9 14.4 57.8 0-.1-8.4 14.3-30.5 15zM303.8 79.7h-33.2V117l22.1 19.9v-36.2h11.8c7.5 0 11.2 3.6 11.2 9.4v27.7c0 5.8-3.5 9.7-11.2 9.7h-34v21.1h33.2c17.8.1 34.5-8.8 34.5-29.2v-29.8c.1-20.8-16.6-29.9-34.4-29.9zm174 59.7v-30.6c0-11 19.8-13.5 25.8-2.5l18.3-7.4c-7.2-15.8-20.3-20.4-31.2-20.4-17.8 0-35.4 10.3-35.4 30.3v30.6c0 20.2 17.6 30.3 35 30.3 11.2 0 24.6-5.5 32-19.9l-19.6-9c-4.8 12.3-24.9 9.3-24.9-1.4zM417.3 113c-6.9-1.5-11.5-4-11.8-8.3.4-10.3 16.3-10.7 25.6-.8l14.7-11.3c-9.2-11.2-19.6-14.2-30.3-14.2-16.3 0-32.1 9.2-32.1 26.6 0 16.9 13 26 27.3 28.2 7.3 1 15.4 3.9 15.2 8.9-.6 9.5-20.2 9-29.1-1.8l-14.2 13.3c8.3 10.7 19.6 16.1 30.2 16.1 16.3 0 34.4-9.4 35.1-26.6 1-21.7-14.8-27.2-30.6-30.1zm-67 55.5h22.4V79.7h-22.4v88.8zM728 79.7h-33.2V117l22.1 19.9v-36.2h11.8c7.5 0 11.2 3.6 11.2 9.4v27.7c0 5.8-3.5 9.7-11.2 9.7h-34v21.1H728c17.8.1 34.5-8.8 34.5-29.2v-29.8c0-20.8-16.7-29.9-34.5-29.9zm-162.9-1.2c-18.4 0-36.7 10-36.7 30.5v30.3c0 20.3 18.4 30.5 36.9 30.5 18.4 0 36.7-10.2 36.7-30.5V109c0-20.4-18.5-30.5-36.9-30.5zm14.4 60.8c0 6.4-7.2 9.7-14.3 9.7-7.2 0-14.4-3.1-14.4-9.7V109c0-6.5 7-10 14-10 7.3 0 14.7 3.1 14.7 10v30.3zM682.4 109c-.5-20.8-14.7-29.2-33-29.2h-35.5v88.8h22.7v-28.2h4l20.6 28.2h28L665 138.1c10.7-3.4 17.4-12.7 17.4-29.1zm-32.6 12h-13.2v-20.3h13.2c14.1 0 14.1 20.3 0 20.3z" />
</svg>
</a>
Chat about n-gon in the <a href="https://discord.gg/2eC9pgJ">discord</a>.<br> Let me know about ideas, or bugs.
Chat about n-gon in the <a href="https://discord.gg/2eC9pgJ">discord</a>.<br> Let me know about ideas,
or bugs.
<br>
<br>
<br>
<a href="https://github.com/landgreen/n-gon">
<svg viewBox="0 0 100 16" xmlns="http://www.w3.org/2000/svg" fill="#1B1F23">
<path d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z" />
<path
d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z" />
<g stroke='none' font-size="8px" font-family="Arial Black, sans-serif">
<text x="19" y="11">Github</text>
</g>
</svg>
</a>
<a href="https://github.com/landgreen/n-gon">Github</a> hosts the source code for n-gon.<br> It's written in JavaScript, CSS, and HTML.
<a href="https://github.com/landgreen/n-gon">Github</a> hosts the source code for n-gon.<br> It's
written in JavaScript, CSS, and HTML.
<!-- <br>
<br>
n-gon is also hosted at <a href="https://lilgreenland.itch.io/n-gon">itch.io</a>.
@@ -268,23 +289,33 @@
<g class="fade-in" transform="translate(100,210) scale(34)" fill='#bbb' stroke='none'>
<path d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" />
<rect x="4" y="1.25" width="1" height="0.5" rx='0.03' />
<path transform="translate(6.9,0) scale(1.25)" d="M0 0 h1 l 0.7 0.7 v2.3 l-0.2 0.2 h-1.8 v-0.5 h1.4 L 1.1 2.4 h-1.1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" />
<path transform="translate(10.9,0) scale(1.25)" d="M0 0 h1 l 0.7 0.7 v1 l -0.7 0.7 h-1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" />
<path transform="translate(6.9,0) scale(1.25)"
d="M0 0 h1 l 0.7 0.7 v2.3 l-0.2 0.2 h-1.8 v-0.5 h1.4 L 1.1 2.4 h-1.1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" />
<path transform="translate(10.9,0) scale(1.25)"
d="M0 0 h1 l 0.7 0.7 v1 l -0.7 0.7 h-1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" />
<path transform="translate(14,0)" d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" />
</g>
<g class="draw-lines" transform="translate(100,210) scale(34)" fill='none' stroke='#222' stroke-linejoin="round" stroke-linecap="round">
<g class="draw-lines" transform="translate(100,210) scale(34)" fill='none' stroke='#222' stroke-linejoin="round"
stroke-linecap="round">
<path d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" stroke-width='0.0875' />
<rect x="4" y="1.25" width="1" height="0.5" stroke-width='0.0875' rx='0.03' />
<path transform="translate(6.9,0) scale(1.25)" d="M0 0 h1 l 0.7 0.7 v2.3 l-0.2 0.2 h-1.8 v-0.5 h1.4 L 1.1 2.4 h-1.1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" stroke-width='0.07' />
<path transform="translate(10.9,0) scale(1.25)" d="M0 0 h1 l 0.7 0.7 v1 l -0.7 0.7 h-1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" stroke-width='0.07' />
<path transform="translate(14,0)" d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" stroke-width='0.0875' />
<path transform="translate(6.9,0) scale(1.25)"
d="M0 0 h1 l 0.7 0.7 v2.3 l-0.2 0.2 h-1.8 v-0.5 h1.4 L 1.1 2.4 h-1.1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z"
stroke-width='0.07' />
<path transform="translate(10.9,0) scale(1.25)"
d="M0 0 h1 l 0.7 0.7 v1 l -0.7 0.7 h-1 l -0.7 -0.7 v-1 l 0.7 -0.7 Z" stroke-width='0.07' />
<path transform="translate(14,0)" d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z"
stroke-width='0.0875' />
</g>
<!-- mouse -->
<g class="draw-lines3" transform="translate(290,430) scale(0.28)" stroke-linecap="round" stroke-linejoin="round" stroke-width="10px" stroke="#222" fill="none">
<path class="fade-in" d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z" fill="rgb(0, 200, 255)" stroke="none" />
<g class="draw-lines3" transform="translate(290,430) scale(0.28)" stroke-linecap="round" stroke-linejoin="round"
stroke-width="10px" stroke="#222" fill="none">
<path class="fade-in" d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z"
fill="rgb(0, 200, 255)" stroke="none" />
<!-- <path class="fade-in" d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z" fill="#789" stroke="none" />
<path class="fade-in" d="M827,112 h30 a140,140,0,0,1,140,140 v68 h-167 z" fill="#7ce" stroke="none" /> -->
<path d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" />
<path
d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" />
<path d="M657 317 h 340 h-170 v-207 s 21 -59, -5 -59 S 807 7, 807 7" />
<ellipse fill="#fff" cx="827.57" cy="218.64" rx="29" ry="68" />
</g>
@@ -304,7 +335,8 @@
<!-- <rect x="70" y="70" width="60" height="60" rx='3' /> -->
<!-- <rect x="140" y="70" width="60" height="60" rx='3' /> -->
</g>
<g class="draw-lines4" text-anchor="middle" stroke='#000' fill='none' stroke-width="2" font-size="38px" font-family="Arial Black, sans-serif">
<g class="draw-lines4" text-anchor="middle" stroke='#000' fill='none' stroke-width="2" font-size="38px"
font-family="Arial Black, sans-serif">
<!-- <text class="fade-in" fill='#aaa' stroke="none" x="30" y="45">Q</text>
<text class="fade-in" fill='#aaa' stroke="none" x="170" y="45">E</text> -->
<text x="30" y="45" stroke-width="2">Q</text>
@@ -335,13 +367,16 @@
<text x="420" y="438">fire</text>
<text x="599" y="438">field</text>
</g>
<g id="gamepad" transform="translate(700,700) scale(0.2)" style="display: none;" stroke="#333" stroke-width="0.5" fill="#444">
<g id="gamepad" transform="translate(700,700) scale(0.2)" style="display: none;" stroke="#333"
stroke-width="0.5" fill="#444">
<path style="fill:#FB7686;" d="M122.578,86.897H68.276c-6.184,0-11.196,5.013-11.196,11.196v12.126h76.692V98.091
C133.772,91.908,128.76,86.897,122.578,86.897z" />
<rect x="57.08" y="100.766" style="opacity:0.4;fill:#FF4E64;enable-background:new ;" width="76.69" height="9.453" />
<rect x="57.08" y="100.766" style="opacity:0.4;fill:#FF4E64;enable-background:new ;" width="76.69"
height="9.453" />
<path style="fill:#FB7686;" d="M389.422,86.897h54.303c6.182,0,11.194,5.013,11.194,11.196v12.126h-76.693V98.091
C378.228,91.908,383.241,86.897,389.422,86.897z" />
<rect x="378.229" y="100.766" style="opacity:0.4;fill:#FF4E64;enable-background:new ;" width="76.69" height="9.453" />
<rect x="378.229" y="100.766" style="opacity:0.4;fill:#FF4E64;enable-background:new ;" width="76.69"
height="9.453" />
<rect x="101.947" y="130.449" style="fill:#89BBE4;" width="308.094" height="144.099" />
<path style="opacity:0.1;fill:#145587;enable-background:new ;" d="M336.726,130.443l-6.391,28.154
c-6.438,28.363-7.324,57.602-2.745,86.134H184.41c4.577-28.531,3.692-57.77-2.746-86.134l-6.39-28.154h-73.323v144.103h308.097

View File

@@ -424,16 +424,16 @@ const b = {
});
//player damage and knock back
sub = Matter.Vector.sub(where, player.position);
dist = Matter.Vector.magnitude(sub);
sub = Vector.sub(where, player.position);
dist = Vector.magnitude(sub);
if (dist < radius) {
if (!b.isModImmuneExplosion) mech.damage(radius * 0.0002);
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), -Math.sqrt(dmg) * player.mass / 30);
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg) * player.mass / 30);
player.force.x += knock.x;
player.force.y += knock.y;
mech.drop();
} else if (dist < alertRange) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), -Math.sqrt(dmg) * player.mass / 55);
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg) * player.mass / 55);
player.force.x += knock.x;
player.force.y += knock.y;
mech.drop();
@@ -441,14 +441,14 @@ const b = {
//body knock backs
for (let i = 0, len = body.length; i < len; ++i) {
sub = Matter.Vector.sub(where, body[i].position);
dist = Matter.Vector.magnitude(sub);
sub = Vector.sub(where, body[i].position);
dist = Vector.magnitude(sub);
if (dist < radius) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) / 18);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) / 18);
body[i].force.x += knock.x;
body[i].force.y += knock.y;
} else if (dist < alertRange) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) / 40);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) / 40);
body[i].force.x += knock.x;
body[i].force.y += knock.y;
}
@@ -456,14 +456,14 @@ const b = {
//power up knock backs
for (let i = 0, len = powerUp.length; i < len; ++i) {
sub = Matter.Vector.sub(where, powerUp[i].position);
dist = Matter.Vector.magnitude(sub);
sub = Vector.sub(where, powerUp[i].position);
dist = Vector.magnitude(sub);
if (dist < radius) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg) * powerUp[i].mass) / 26);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * powerUp[i].mass) / 30);
powerUp[i].force.x += knock.x;
powerUp[i].force.y += knock.y;
} else if (dist < alertRange) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg) * powerUp[i].mass) / 40);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * powerUp[i].mass) / 45);
powerUp[i].force.x += knock.x;
powerUp[i].force.y += knock.y;
}
@@ -473,19 +473,19 @@ const b = {
let damageScale = 1.5; // reduce dmg for each new target to limit total AOE damage
for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i].alive) {
sub = Matter.Vector.sub(where, mob[i].position);
dist = Matter.Vector.magnitude(sub) - mob[i].radius;
sub = Vector.sub(where, mob[i].position);
dist = Vector.magnitude(sub) - mob[i].radius;
if (dist < radius) {
mob[i].damage(dmg * damageScale);
mob[i].locatePlayer();
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 18);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 30);
mob[i].force.x += knock.x;
mob[i].force.y += knock.y;
radius *= 0.9 //reduced range for each additional explosion target
damageScale *= 0.75 //reduced damage for each additional explosion target
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
mob[i].locatePlayer();
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 35);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 50);
mob[i].force.x += knock.x;
mob[i].force.y += knock.y;
}
@@ -517,16 +517,16 @@ const b = {
});
//player damage and knock back
sub = Matter.Vector.sub(bullet[me].position, player.position);
dist = Matter.Vector.magnitude(sub);
sub = Vector.sub(bullet[me].position, player.position);
dist = Vector.magnitude(sub);
if (dist < radius) {
if (!b.isModImmuneExplosion) mech.damage(radius * 0.0002);
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), -Math.sqrt(dmg) * player.mass / 30);
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg) * player.mass / 30);
player.force.x += knock.x;
player.force.y += knock.y;
mech.drop();
} else if (dist < alertRange) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), -Math.sqrt(dmg) * player.mass / 55);
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg) * player.mass / 55);
player.force.x += knock.x;
player.force.y += knock.y;
mech.drop();
@@ -534,14 +534,14 @@ const b = {
//body knock backs
for (let i = 0, len = body.length; i < len; ++i) {
sub = Matter.Vector.sub(bullet[me].position, body[i].position);
dist = Matter.Vector.magnitude(sub);
sub = Vector.sub(bullet[me].position, body[i].position);
dist = Vector.magnitude(sub);
if (dist < radius) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) / 18);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) / 18);
body[i].force.x += knock.x;
body[i].force.y += knock.y;
} else if (dist < alertRange) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) / 40);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * body[i].mass) / 40);
body[i].force.x += knock.x;
body[i].force.y += knock.y;
}
@@ -549,14 +549,14 @@ const b = {
//power up knock backs
for (let i = 0, len = powerUp.length; i < len; ++i) {
sub = Matter.Vector.sub(bullet[me].position, powerUp[i].position);
dist = Matter.Vector.magnitude(sub);
sub = Vector.sub(bullet[me].position, powerUp[i].position);
dist = Vector.magnitude(sub);
if (dist < radius) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg) * powerUp[i].mass) / 26);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * powerUp[i].mass) / 30);
powerUp[i].force.x += knock.x;
powerUp[i].force.y += knock.y;
} else if (dist < alertRange) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg) * powerUp[i].mass) / 40);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg) * powerUp[i].mass) / 45);
powerUp[i].force.x += knock.x;
powerUp[i].force.y += knock.y;
}
@@ -566,26 +566,26 @@ const b = {
let damageScale = 1.5; // reduce dmg for each new target to limit total AOE damage
for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i].alive) {
sub = Matter.Vector.sub(bullet[me].position, mob[i].position);
dist = Matter.Vector.magnitude(sub) - mob[i].radius;
sub = Vector.sub(bullet[me].position, mob[i].position);
dist = Vector.magnitude(sub) - mob[i].radius;
if (dist < radius) {
mob[i].damage(dmg * damageScale);
mob[i].locatePlayer();
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 18);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 30);
mob[i].force.x += knock.x;
mob[i].force.y += knock.y;
radius *= 0.9 //reduced range for each additional explosion target
damageScale *= 0.75 //reduced damage for each additional explosion target
} else if (!mob[i].seePlayer.recall && dist < alertRange) {
mob[i].locatePlayer();
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 35);
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 50);
mob[i].force.x += knock.x;
mob[i].force.y += knock.y;
}
}
}
// Matter.Vector.magnitudeSquared(Matter.Vector.sub(bullet[me].position, mob[i].position))
// Vector.magnitudeSquared(Vector.sub(bullet[me].position, mob[i].position))
},
spore(who) { //used with the mod upgrade in mob.death()
const bIndex = bullet.length;
@@ -619,12 +619,12 @@ const b = {
for (let i = 0, len = mob.length; i < len; ++i) {
if (Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
// Matter.Query.ray(body, this.position, mob[i].position).length === 0
const targetVector = Matter.Vector.sub(this.position, mob[i].position)
const dist = Matter.Vector.magnitude(targetVector);
const targetVector = Vector.sub(this.position, mob[i].position)
const dist = Vector.magnitude(targetVector);
if (dist < closeDist) {
this.closestTarget = mob[i].position;
closeDist = dist;
this.lockedOn = Matter.Vector.normalise(targetVector);
this.lockedOn = Vector.normalise(targetVector);
if (0.3 > Math.random()) break //doesn't always target the closest mob
}
}
@@ -693,8 +693,8 @@ const b = {
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0
) {
const TARGET_VECTOR = Matter.Vector.sub(this.position, mob[i].position)
const DIST = Matter.Vector.magnitude(TARGET_VECTOR);
const TARGET_VECTOR = Vector.sub(this.position, mob[i].position)
const DIST = Vector.magnitude(TARGET_VECTOR);
if (DIST < closeDist) {
closeDist = DIST;
this.lockedOn = mob[i]
@@ -710,8 +710,8 @@ const b = {
Matter.Query.ray(map, this.position, powerUp[i].position).length === 0 &&
Matter.Query.ray(body, this.position, powerUp[i].position).length === 0
) {
const TARGET_VECTOR = Matter.Vector.sub(this.position, powerUp[i].position)
const DIST = Matter.Vector.magnitude(TARGET_VECTOR);
const TARGET_VECTOR = Vector.sub(this.position, powerUp[i].position)
const DIST = Vector.magnitude(TARGET_VECTOR);
if (DIST < closeDist) {
if (DIST < 50) { //eat the power up if close enough
powerUp[i].effect();
@@ -727,9 +727,9 @@ const b = {
}
}
if (this.lockedOn) { //accelerate towards mobs
this.force = Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(this.position, this.lockedOn.position)), -this.mass * THRUST)
this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, this.lockedOn.position)), -this.mass * THRUST)
} else { //accelerate towards mouse
this.force = Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(this.position, game.mouseInGame)), -this.mass * THRUST)
this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, game.mouseInGame)), -this.mass * THRUST)
}
// speed cap instead of friction to give more agility
if (this.speed > 6) {
@@ -907,7 +907,7 @@ const b = {
if (!mech.isBodiesAsleep) {
this.cycle++
const THRUST = wiggleMag * Math.cos(this.cycle * 0.3)
this.force = Matter.Vector.mult(Matter.Vector.normalise(this.direction), this.mass * THRUST) //wiggle
this.force = Vector.mult(Vector.normalise(this.direction), this.mass * THRUST) //wiggle
if (this.cycle > 0 && !(Math.floor(this.cycle) % 6)) Matter.Body.scale(this, SCALE, SCALE); //shrink
}
@@ -920,11 +920,11 @@ const b = {
x: SPEED * Math.cos(dir),
y: SPEED * Math.sin(dir)
});
bullet[me].direction = Matter.Vector.perp(bullet[me].velocity)
bullet[me].direction = Vector.perp(bullet[me].velocity)
// if (mech.angle + Math.PI / 2 > 0) {
// bullet[me].direction = Matter.Vector.perp(bullet[me].velocity, true)
// bullet[me].direction = Vector.perp(bullet[me].velocity, true)
// } else {
// bullet[me].direction = Matter.Vector.perp(bullet[me].velocity)
// bullet[me].direction = Vector.perp(bullet[me].velocity)
// }
World.add(engine.world, bullet[me]); //add bullet to world
@@ -985,25 +985,25 @@ const b = {
player.force.y -= KNOCK * Math.sin(mech.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
//push away blocks when firing
let range = 450 * this.charge
let range = 700 * this.charge
for (let i = 0, len = body.length; i < len; ++i) {
const SUB = Matter.Vector.sub(body[i].position, mech.pos)
const DISTANCE = Matter.Vector.magnitude(SUB)
const SUB = Vector.sub(body[i].position, mech.pos)
const DISTANCE = Vector.magnitude(SUB)
if (DISTANCE < range) {
const DEPTH = Math.max(range - DISTANCE, 100)
const FORCE = Matter.Vector.mult(Matter.Vector.normalise(SUB), 0.005 * Math.sqrt(DEPTH) * Math.sqrt(body[i].mass))
const DEPTH = Math.min(range - DISTANCE, 300)
const FORCE = Vector.mult(Vector.normalise(SUB), 0.003 * Math.sqrt(DEPTH) * body[i].mass)
body[i].force.x += FORCE.x;
body[i].force.y += FORCE.y - body[i].mass * (game.g * 1.5); //kick up a bit to give them some arc
}
}
for (let i = 0, len = mob.length; i < len; ++i) {
const SUB = Matter.Vector.sub(mob[i].position, mech.pos)
const DISTANCE = Matter.Vector.magnitude(SUB)
const SUB = Vector.sub(mob[i].position, mech.pos)
const DISTANCE = Vector.magnitude(SUB)
if (DISTANCE < range) {
const DEPTH = Math.max(range - DISTANCE, 100)
const FORCE = Matter.Vector.mult(Matter.Vector.normalise(SUB), 0.005 * Math.sqrt(DEPTH) * Math.sqrt(mob[i].mass))
const DEPTH = Math.min(range - DISTANCE, 300)
const FORCE = Vector.mult(Vector.normalise(SUB), 0.003 * Math.sqrt(DEPTH) * mob[i].mass)
mob[i].force.x += 1.5 * FORCE.x;
mob[i].force.y += 1.5 * FORCE.y;
}
@@ -1011,11 +1011,11 @@ const b = {
//push mobs around player when firing
// range = 600 * this.charge
// for (let i = 0, len = mob.length; i < len; ++i) {
// const SUB = Matter.Vector.sub(mob[i].position, mech.pos)
// const DISTANCE = Matter.Vector.magnitude(SUB)
// const SUB = Vector.sub(mob[i].position, mech.pos)
// const DISTANCE = Vector.magnitude(SUB)
// if (DISTANCE < range) {
// const DEPTH = range - DISTANCE
// const FORCE = Matter.Vector.mult(Matter.Vector.normalise(SUB), 0.00000001 * DEPTH * DEPTH * DEPTH * Math.sqrt(mob[i].mass))
// const FORCE = Vector.mult(Vector.normalise(SUB), 0.00000001 * DEPTH * DEPTH * DEPTH * Math.sqrt(mob[i].mass))
// mob[i].force.x += FORCE.x
// mob[i].force.y += FORCE.y
// }
@@ -1031,16 +1031,16 @@ const b = {
//gently push away mobs while charging
// const RANGE = 270 * this.charge
// for (let i = 0, len = mob.length; i < len; ++i) {
// const SUB = Matter.Vector.sub(mob[i].position, mech.pos)
// const DISTANCE = Matter.Vector.magnitude(SUB)
// const SUB = Vector.sub(mob[i].position, mech.pos)
// const DISTANCE = Vector.magnitude(SUB)
// // if (DISTANCE < RANGE) {
// // Matter.Body.setVelocity(mob[i], Matter.Vector.rotate(mob[i].velocity, 0.1))
// // Matter.Body.setVelocity(mob[i], Vector.rotate(mob[i].velocity, 0.1))
// // }
// // const DRAIN = 0.0002 //&& mech.fieldMeter > DRAIN
// if (DISTANCE < RANGE) {
// // mech.fieldMeter -= DRAIN + mech.fieldRegen;
// const DEPTH = RANGE - DISTANCE
// const FORCE = Matter.Vector.mult(Matter.Vector.normalise(SUB), 0.000000001 * DEPTH * DEPTH * DEPTH * Math.sqrt(mob[i].mass))
// const FORCE = Vector.mult(Vector.normalise(SUB), 0.000000001 * DEPTH * DEPTH * DEPTH * Math.sqrt(mob[i].mass))
// mob[i].force.x += FORCE.x
// mob[i].force.y += FORCE.y
// }
@@ -1132,8 +1132,8 @@ const b = {
//draw magnetic field
const X = mech.pos.x
const Y = mech.pos.y
const unitVector = Matter.Vector.normalise(Matter.Vector.sub(game.mouseInGame, mech.pos))
const unitVectorPerp = Matter.Vector.perp(unitVector)
const unitVector = Vector.normalise(Vector.sub(game.mouseInGame, mech.pos))
const unitVectorPerp = Vector.perp(unitVector)
function magField(mag, arc) {
ctx.moveTo(X, Y);
@@ -1195,24 +1195,29 @@ const b = {
this.lockedOn = null;
let closeDist = Infinity;
//look for targets
//look for closest target to where the missile will be in 30 cycles
const futurePos = Vector.add(this.position, Vector.mult(this.velocity, 30))
// ctx.beginPath(); //draw future pos
// ctx.arc(futurePos.x, futurePos.y, 20, 0, 2 * Math.PI);
// ctx.fillStyle = "rgba(0,0,0,0.5)";
// ctx.fill();
for (let i = 0, len = mob.length; i < len; ++i) {
if (
mob[i].alive &&
mob[i].dropPowerUp &&
mob[i].alive && mob[i].dropPowerUp &&
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0
) {
const dist = Matter.Vector.magnitude(Matter.Vector.sub(this.position, mob[i].position));
if (dist < closeDist) {
closeDist = dist;
const futureDist = Vector.magnitude(Vector.sub(futurePos, mob[i].position));
if (futureDist < closeDist) {
closeDist = futureDist;
this.lockedOn = mob[i];
this.frictionAir = 0.05; //extra friction once a target it locked
}
}
}
//explode when bullet is close enough to target
if (this.lockedOn && closeDist < this.explodeRad * 0.6) {
if (this.lockedOn && Vector.magnitude(Vector.sub(this.position, this.lockedOn.position)) < this.explodeRad * 0.7) {
this.endCycle = 0; //bullet ends cycle after doing damage //also triggers explosion
const dmg = b.dmgScale * 3;
this.lockedOn.damage(dmg); //does extra damage to target
@@ -1225,9 +1230,9 @@ const b = {
x: Math.cos(this.angle),
y: Math.sin(this.angle)
};
const target = Matter.Vector.normalise(Matter.Vector.sub(this.position, this.lockedOn.position));
if (Matter.Vector.dot(target, face) > -0.98) {
if (Matter.Vector.cross(target, face) > 0) {
const target = Vector.normalise(Vector.sub(this.position, this.lockedOn.position));
if (Vector.dot(target, face) > -0.98) {
if (Vector.cross(target, face) > 0) {
Matter.Body.rotate(this, 0.08);
} else {
Matter.Body.rotate(this, -0.08);
@@ -1332,7 +1337,7 @@ const b = {
fire() {
const me = bullet.length;
const dir = mech.angle;
bullet[me] = Bodies.circle(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 26 * b.modBulletSize, b.fireAttributes(dir, false));
bullet[me] = Bodies.circle(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 35 * b.modBulletSize, b.fireAttributes(dir, false));
bullet[me].radius = 22; //used from drawing timer
b.fireProps(10, mech.crouch ? 42 : 26, dir, me); //cd , speed
@@ -1372,10 +1377,10 @@ const b = {
function suck(who, radius = that.explodeRad * 2) {
for (i = 0, len = who.length; i < len; i++) {
const sub = Matter.Vector.sub(that.position, who[i].position);
const dist = Matter.Vector.magnitude(sub);
const sub = Vector.sub(that.position, who[i].position);
const dist = Vector.magnitude(sub);
if (dist < radius && dist > 150) {
knock = Matter.Vector.mult(Matter.Vector.normalise(sub), mag * who[i].mass / Math.sqrt(dist));
knock = Vector.mult(Vector.normalise(sub), mag * who[i].mass / Math.sqrt(dist));
who[i].force.x += knock.x;
who[i].force.y += knock.y;
}
@@ -1425,7 +1430,7 @@ const b = {
//draw clock on timer
ctx.fillStyle = "#f04";
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius * 0.5, 0, 2 * Math.PI);
ctx.arc(this.position.x, this.position.y, this.radius * 0.7, 0, 2 * Math.PI);
ctx.fill();
}
}
@@ -1458,13 +1463,13 @@ const b = {
const targets = []
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].dropPowerUp) {
const sub = Matter.Vector.sub(this.position, mob[i].position);
const dist = Matter.Vector.magnitude(sub);
const sub = Vector.sub(this.position, mob[i].position);
const dist = Vector.magnitude(sub);
if (dist < 1400 &&
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
targets.push(
Matter.Vector.add(mob[i].position, Matter.Vector.mult(mob[i].velocity, dist / 60))
Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 60))
)
}
}
@@ -1478,7 +1483,7 @@ const b = {
x: targets[index].x + SPREAD * (Math.random() - 0.5),
y: targets[index].y + SPREAD * (Math.random() - 0.5)
}
needle(this.position, Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(WHERE, this.position)), speed))
needle(this.position, Vector.mult(Vector.normalise(Vector.sub(WHERE, this.position)), speed))
} else { // aim in random direction
const ANGLE = 2 * Math.PI * Math.random()
needle(this.position, {
@@ -1595,7 +1600,7 @@ const b = {
this.lockedOn = null;
let closeDist = this.range;
for (let i = 0, len = mob.length; i < len; ++i) {
const DIST = Matter.Vector.magnitude(Matter.Vector.sub(this.vertices[0], mob[i].position));
const DIST = Vector.magnitude(Vector.sub(this.vertices[0], mob[i].position));
if (DIST - mob[i].radius < closeDist &&
Matter.Query.ray(map, this.vertices[0], mob[i].position).length === 0 &&
Matter.Query.ray(body, this.vertices[0], mob[i].position).length === 0) {
@@ -1609,7 +1614,7 @@ const b = {
mech.fieldMeter -= 0.0016
//make sure you can still see target
const DIST = Matter.Vector.magnitude(Matter.Vector.sub(this.vertices[0], this.lockedOn.position));
const DIST = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.position));
if (DIST - this.lockedOn.radius < this.range + 150 &&
Matter.Query.ray(map, this.vertices[0], this.lockedOn.position).length === 0 &&
Matter.Query.ray(body, this.vertices[0], this.lockedOn.position).length === 0) {
@@ -1617,7 +1622,7 @@ const b = {
let bestVertexDistance = Infinity
let bestVertex = null
for (let i = 0; i < this.lockedOn.vertices.length; i++) {
const dist = Matter.Vector.magnitude(Matter.Vector.sub(this.vertices[0], this.lockedOn.vertices[i]));
const dist = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.vertices[i]));
if (dist < bestVertexDistance) {
bestVertex = i
bestVertexDistance = dist
@@ -1644,14 +1649,14 @@ const b = {
}
}
const distanceToPlayer = Matter.Vector.magnitude(Matter.Vector.sub(this.position, mech.pos))
const distanceToPlayer = Vector.magnitude(Vector.sub(this.position, mech.pos))
if (distanceToPlayer > this.range * 0.2) { //if far away move towards player
this.force = Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(mech.pos, this.position)), this.mass * this.acceleration)
this.force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, this.position)), this.mass * this.acceleration)
this.frictionAir = 0.02
} else { //close to player
this.frictionAir = 0
//add player's velocity
Matter.Body.setVelocity(this, Matter.Vector.add(Matter.Vector.mult(this.velocity, 1), Matter.Vector.mult(player.velocity, 0.02)));
Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 1), Vector.mult(player.velocity, 0.02)));
}
}
})
@@ -1752,11 +1757,11 @@ const b = {
const reflection = function () {
// https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector
const n = Matter.Vector.perp(Matter.Vector.normalise(Matter.Vector.sub(best.v1, best.v2)));
const d = Matter.Vector.sub(path[path.length - 1], path[path.length - 2]);
const nn = Matter.Vector.mult(n, 2 * Matter.Vector.dot(d, n));
const r = Matter.Vector.normalise(Matter.Vector.sub(d, nn));
path[path.length] = Matter.Vector.add(Matter.Vector.mult(r, range), path[path.length - 1]);
const n = Vector.perp(Vector.normalise(Vector.sub(best.v1, best.v2)));
const d = Vector.sub(path[path.length - 1], path[path.length - 2]);
const nn = Vector.mult(n, 2 * Vector.dot(d, n));
const r = Vector.normalise(Vector.sub(d, nn));
path[path.length] = Vector.add(Vector.mult(r, range), path[path.length - 1]);
};
//beam before reflection
checkForCollisions();
@@ -1827,7 +1832,7 @@ const b = {
fire() {
//calculate laser collision
let best;
let range = 4000
let range = 3000
const path = [{
x: mech.pos.x + 20 * Math.cos(mech.angle),
y: mech.pos.y + 20 * Math.sin(mech.angle)
@@ -1918,8 +1923,8 @@ const b = {
ctx.stroke();
//draw little dots along the laser path
const sub = Matter.Vector.sub(path[1], path[0])
const mag = Matter.Vector.magnitude(sub)
const sub = Vector.sub(path[1], path[0])
const mag = Vector.magnitude(sub)
for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) {
const dist = Math.random()
game.drawList.push({
@@ -1940,13 +1945,13 @@ const b = {
have: false,
isStarterGun: true,
fire() {
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 12 : 4) * b.modFireRate); // cool down
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 12 : 5) * b.modFireRate); // cool down
const me = bullet.length;
const dir = mech.angle + 0.2 * (Math.random() - 0.5)
const RADIUS = (8 + 16 * Math.random()) * b.modBulletSize
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 25, RADIUS, {
angle: dir,
density: 0.000005, // 0.001 is normal density
density: 0.00001, // 0.001 is normal density
inertia: Infinity,
frictionAir: 0.003,
friction: 0.2,
@@ -1972,7 +1977,7 @@ const b = {
let bestVertexDistance = Infinity
let bestVertex = null
for (let i = 0; i < this.target.vertices.length; i++) {
const dist = Matter.Vector.magnitude(Matter.Vector.sub(this.position, this.target.vertices[i]));
const dist = Vector.magnitude(Vector.sub(this.position, this.target.vertices[i]));
if (dist < bestVertexDistance) {
bestVertex = i
bestVertexDistance = dist
@@ -2007,9 +2012,9 @@ const b = {
if (this.target && this.target.alive) { //if stuck to a target
Matter.Body.setPosition(this, this.target.vertices[this.targetVertex])
Matter.Body.setVelocity(this.target, Matter.Vector.mult(this.target.velocity, 0.94))
Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.94))
Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.94)
this.target.damage(b.dmgScale * 0.004);
this.target.damage(b.dmgScale * 0.0045);
} else if (this.target !== null) { //look for a new target
this.target = null
this.collisionFilter.category = cat.bullet;
@@ -2065,8 +2070,8 @@ const b = {
// const dmg = b.dmgScale * 0.02
// for (let i = 0, len = mob.length; i < len; ++i) {
// if (mob[i].alive) {
// sub = Matter.Vector.sub(this.position, mob[i].position);
// dist = Matter.Vector.magnitude(sub) - mob[i].radius;
// sub = Vector.sub(this.position, mob[i].position);
// dist = Vector.magnitude(sub) - mob[i].radius;
// if (dist < this.range) {
// mob[i].damage(dmg);
// mob[i].locatePlayer();
@@ -2076,8 +2081,8 @@ const b = {
// //pull in body, and power ups?, and bullets?
// for (let i = 0, len = body.length; i < len; ++i) {
// sub = Matter.Vector.sub(this.position, body[i].position);
// dist = Matter.Vector.magnitude(sub)
// sub = Vector.sub(this.position, body[i].position);
// dist = Vector.magnitude(sub)
// if (dist < this.range) {
// this.range += body[i].mass * 2
// Matter.World.remove(engine.world, body[i]);
@@ -2155,7 +2160,7 @@ const b = {
// onEnd() {},
// do() {
// if (this.lockedOn) { //accelerate towards mobs
// this.force = Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(this.position, this.lockedOn.position)), -this.mass * 0.01)
// this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, this.lockedOn.position)), -this.mass * 0.01)
// Matter.Body.setVelocity(this, {
// x: this.velocity.x * 0.93,
// y: this.velocity.y * 0.93
@@ -2175,8 +2180,8 @@ const b = {
// Matter.Query.ray(map, bullet[me].position, mob[i].position).length === 0 &&
// Matter.Query.ray(body, bullet[me].position, mob[i].position).length === 0
// ) {
// const TARGET_VECTOR = Matter.Vector.sub(bullet[me].position, mob[i].position)
// const DIST = Matter.Vector.magnitude(TARGET_VECTOR);
// const TARGET_VECTOR = Vector.sub(bullet[me].position, mob[i].position)
// const DIST = Vector.magnitude(TARGET_VECTOR);
// if (DIST < closeDist) {
// closeDist = DIST;
// bullet[me].lockedOn = mob[i]

View File

@@ -9,7 +9,8 @@ const Engine = Matter.Engine,
Vertices = Matter.Vertices,
Query = Matter.Query,
Body = Matter.Body,
Bodies = Matter.Bodies;
Bodies = Matter.Bodies,
Vector = Matter.Vector;
// create an engine
const engine = Engine.create();
@@ -88,7 +89,7 @@ function mobCollisionChecks(event) {
function collidePlayer(obj, speedThreshold = 12, massThreshold = 2) {
if (obj.classType === "body" && obj.speed > speedThreshold && obj.mass > massThreshold) { //dmg from hitting a body
const v = Matter.Vector.magnitude(Matter.Vector.sub(player.velocity, obj.velocity));
const v = Vector.magnitude(Vector.sub(player.velocity, obj.velocity));
if (v > speedThreshold) {
mech.damageImmune = mech.cycle + 30; //player is immune to collision damage for 30 cycles
let dmg = Math.sqrt((v - speedThreshold + 0.1) * (obj.mass - massThreshold)) * 0.01;
@@ -177,17 +178,15 @@ function mobCollisionChecks(event) {
}
//mob + bullet collisions
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
// const dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Matter.Vector.magnitude(Matter.Vector.sub(mob[k].velocity, obj.velocity)));
let dmg = b.dmgScale * (obj.dmg + b.modExtraDmg + 0.15 * obj.mass * Matter.Vector.magnitude(Matter.Vector.sub(mob[k].velocity, obj.velocity)))
// const dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)));
let dmg = b.dmgScale * (obj.dmg + b.modExtraDmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
if (b.modIsCrit && !mob[k].seePlayer.recall) dmg *= 5
mob[k].foundPlayer();
mob[k].damage(dmg);
obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn
game.drawList.push({
//add dmg to draw queue
game.drawList.push({ //add dmg to draw queue
x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y,
// radius: Math.sqrt(dmg) * 40,
radius: Math.log(2 * dmg + 1.1) * 40,
color: game.playerDmgColor,
time: game.drawTime
@@ -196,7 +195,7 @@ function mobCollisionChecks(event) {
}
//mob + body collisions
if (obj.classType === "body" && obj.speed > 5) {
const v = Matter.Vector.magnitude(Matter.Vector.sub(mob[k].velocity, obj.velocity));
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
if (v > 8) {
let dmg = b.dmgScale * v * Math.sqrt(obj.mass) * 0.05;
mob[k].damage(dmg);

View File

@@ -2,17 +2,15 @@
/* TODO: *******************************************
*****************************************************
add builds with combinations of gun, field and mobs
use the pull down menu
new game loop structure: game loop is an object with named methods
when looping each method is called in order like an array
allows me to dynamically add and remove functions to the game
dynamically generate html about fields, guns and mods
mod: if you fire when out of ammo you gain 1 ammo pack at the cost of
10% max health
20% of your current health
add grid check to improve queries over large body arrays
something about broad phase
having trouble with this, might give up
gun: like drones, but fast moving and short lived
dies after doing damage
mod: increase range of shield block
gun: Spirit Bomb (singularity)
use charge up like rail gun
@@ -21,16 +19,6 @@ gun: Spirit Bomb (singularity)
sucked in stuff increase size
uses energy
mod: auto pick up guns, heals, ammo
use the same rule for drones
maybe give some other bonus too?
rework junk bot
it's behavior is too unpredictable
range is unclear
having the bullets last long after doing dmg isn't fun
we want a fun gun that acts like a melee weapon
atmosphere levels
large rotating fan that the player has to move through
give the user a rest, between combat
@@ -62,13 +50,7 @@ new map with repeating endlessness
field power up effects
field allows player to hold and throw living mobs
mod power ups ideas
double jump
bullet on mob damage effects
add to the array mob.do new mob behaviors
add a damage over time
add a freeze
of hack mobs
give mobs more animal-like behaviors
like rain world
@@ -99,6 +81,8 @@ game mechanics
bouncy ground
*/
//collision groups
// cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet | cat.mobShield
const cat = {

View File

@@ -14,7 +14,7 @@ const level = {
start() {
if (level.levelsCleared === 0) {
// game.difficulty = 6; //for testing to simulate possible mobs spawns
// b.giveGuns(15)
// b.giveGuns(5)
// mech.fieldUpgrades[2].effect();
// b.giveMod(21)
@@ -97,19 +97,24 @@ const level = {
spawn.spawnBuilding(-200, -250, 275, 240, false, true, "left"); //far left; player spawns in side
// spawn.boost(350, 0, -1000);
// for (let i = 0; i < 10; i++) {
powerUps.spawn(950, -425, "gun", false);
powerUps.spawn(950, -425, "gun", false);
// powerUps.spawn(950, -425, "gun", false);
// powerUps.spawn(950, -425, "gun", false);
// }
// spawn.nodeBoss(-500, -600, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
// spawn.lineBoss(-500, -600, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
spawn.bodyRect(-135, -50, 50, 50);
spawn.bodyRect(-140, -100, 50, 50);
// powerUps.spawn(420, -400, "ammo", false);
// spawn.bodyRect(-135, -50, 50, 50);
// spawn.bodyRect(-140, -100, 50, 50);
powerUps.spawn(420, -400, "field", false);
powerUps.spawn(420, -400, "field", false);
powerUps.spawn(420, -400, "field", false);
powerUps.spawn(420, -400, "field", false);
// powerUps.spawn(450, -400, "mod", false, 6);
// powerUps.spawn(450, -400, "mod", false);
// spawn.bodyRect(-45, -100, 40, 50);
spawn.shooter(800, -1050);
// spawn.shooter(800, -1050);
// spawn.shooter(400, -1050);
// spawn.shooter(1200, -1050);
// spawn.groupBoss(-600, -550);
// spawn.hopper(800, -150);
// spawn.beamer(800, -150);

View File

@@ -185,14 +185,14 @@ const mobs = {
}
},
isLookingAtPlayer(threshold) {
const diff = Matter.Vector.normalise(Matter.Vector.sub(player.position, this.position));
const diff = Vector.normalise(Vector.sub(player.position, this.position));
//make a vector for the mob's direction of length 1
const dir = {
x: Math.cos(this.angle),
y: Math.sin(this.angle)
};
//the dot product of diff and dir will return how much over lap between the vectors
const dot = Matter.Vector.dot(dir, diff);
const dot = Vector.dot(dir, diff);
// console.log(Math.cos(dot)*180/Math.PI)
if (dot > threshold) {
return true;
@@ -247,7 +247,7 @@ const mobs = {
this.hackedTarget = null
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i] !== this) {
// const DIST = Matter.Vector.magnitude(Matter.Vector.sub(this.position, mob[j]));
// const DIST = Vector.magnitude(Vector.sub(this.position, mob[j]));
if (Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
this.hackedTarget = mob[i]
@@ -258,7 +258,7 @@ const mobs = {
//acceleration towards targets
if (this.hackedTarget) {
this.force = Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(this.hackedTarget.position, this.position)), this.mass * 0.0015)
this.force = Vector.mult(Vector.normalise(Vector.sub(this.hackedTarget.position, this.position)), this.mass * 0.0015)
}
},
@@ -508,7 +508,7 @@ const mobs = {
alertNearByMobs() {
//this.alertRange2 is set at the very bottom of this mobs, after mob is made
for (let i = 0; i < mob.length; i++) {
if (!mob[i].seePlayer.recall && Matter.Vector.magnitudeSquared(Matter.Vector.sub(this.position, mob[i].position)) < this.alertRange2) {
if (!mob[i].seePlayer.recall && Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < this.alertRange2) {
mob[i].locatePlayer();
}
}
@@ -576,12 +576,12 @@ const mobs = {
//cause all mobs, and bodies to rotate in a circle
applyCurl = function (center, array) {
for (let i = 0; i < array.length; ++i) {
const sub = Matter.Vector.sub(center, array[i].position)
const radius2 = Matter.Vector.magnitudeSquared(sub);
const sub = Vector.sub(center, array[i].position)
const radius2 = Vector.magnitudeSquared(sub);
//if too close, like center mob or shield, don't curl // if too far don't curl
if (radius2 < range * range && radius2 > 10000) {
const curlVector = Matter.Vector.mult(Matter.Vector.perp(Matter.Vector.normalise(sub)), mag)
const curlVector = Vector.mult(Vector.perp(Vector.normalise(sub)), mag)
//apply curl force
Matter.Body.setVelocity(array[i], {
x: array[i].velocity.x * 0.94 + curlVector.x * 0.06,
@@ -610,7 +610,7 @@ const mobs = {
// ctx.fill();
},
pullPlayer() {
if (this.seePlayer.yes && Matter.Vector.magnitudeSquared(Matter.Vector.sub(this.position, player.position)) < 1000000) {
if (this.seePlayer.yes && Vector.magnitudeSquared(Vector.sub(this.position, player.position)) < 1000000) {
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
player.force.x -= game.accelScale * 1.13 * Math.cos(angle) * (mech.onGround ? 2 * player.mass * game.g : player.mass * game.g);
player.force.y -= game.accelScale * 0.84 * player.mass * game.g * Math.sin(angle);
@@ -733,15 +733,15 @@ const mobs = {
}
};
const sub = Matter.Vector.sub(this.searchTarget, this.position);
if (Matter.Vector.magnitude(sub) > this.radius * 2) {
const sub = Vector.sub(this.searchTarget, this.position);
if (Vector.magnitude(sub) > this.radius * 2) {
// ctx.beginPath();
// ctx.strokeStyle = "#aaa";
// ctx.moveTo(this.position.x, this.position.y);
// ctx.lineTo(this.searchTarget.x,this.searchTarget.y);
// ctx.stroke();
//accelerate at 0.1 of normal acceleration
this.force = Matter.Vector.mult(Matter.Vector.normalise(sub), this.accelMag * this.mass * 0.2);
this.force = Vector.mult(Vector.normalise(sub), this.accelMag * this.mass * 0.2);
} else {
//after reaching random target switch to new target
newTarget(this);
@@ -755,13 +755,13 @@ const mobs = {
strike() {
//teleport to player when close enough on CD
if (this.seePlayer.recall && this.cd < game.cycle) {
const dist = Matter.Vector.sub(this.seePlayer.position, this.position);
const distMag = Matter.Vector.magnitude(dist);
const dist = Vector.sub(this.seePlayer.position, this.position);
const distMag = Vector.magnitude(dist);
if (distMag < 400) {
this.cd = game.cycle + this.delay;
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
Matter.Body.translate(this, Matter.Vector.mult(Matter.Vector.normalise(dist), distMag - 20 - radius));
Matter.Body.translate(this, Vector.mult(Vector.normalise(dist), distMag - 20 - radius));
ctx.lineTo(this.position.x, this.position.y);
ctx.lineWidth = radius * 2;
ctx.strokeStyle = this.fill; //"rgba(0,0,0,0.5)"; //'#000'
@@ -774,14 +774,14 @@ const mobs = {
if (this.seePlayer.recall && !(game.cycle % this.blinkRate)) {
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
const dist = Matter.Vector.sub(this.seePlayer.position, this.position);
const distMag = Matter.Vector.magnitude(dist);
const unitVector = Matter.Vector.normalise(dist);
const dist = Vector.sub(this.seePlayer.position, this.position);
const distMag = Vector.magnitude(dist);
const unitVector = Vector.normalise(dist);
const rando = (Math.random() - 0.5) * 50;
if (distMag < this.blinkLength) {
Matter.Body.translate(this, Matter.Vector.mult(unitVector, distMag + rando));
Matter.Body.translate(this, Vector.mult(unitVector, distMag + rando));
} else {
Matter.Body.translate(this, Matter.Vector.mult(unitVector, this.blinkLength + rando));
Matter.Body.translate(this, Vector.mult(unitVector, this.blinkLength + rando));
}
ctx.lineTo(this.position.x, this.position.y);
ctx.lineWidth = radius * 2;
@@ -795,9 +795,9 @@ const mobs = {
// && !mech.lookingAtMob(this,0.5)){
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
const dist = Matter.Vector.sub(this.seePlayer.position, this.position);
const distMag = Matter.Vector.magnitude(dist);
const vector = Matter.Vector.mult(Matter.Vector.normalise(dist), this.blinkLength);
const dist = Vector.sub(this.seePlayer.position, this.position);
const distMag = Vector.magnitude(dist);
const vector = Vector.mult(Vector.normalise(dist), this.blinkLength);
if (distMag < this.blinkLength) {
Matter.Body.setPosition(this, this.seePlayer.position);
Matter.Body.translate(this, {
@@ -845,7 +845,7 @@ const mobs = {
if (this.seePlayer.recall) {
//set direction to turn to fire
if (!(game.cycle % this.seePlayerFreq)) {
this.fireDir = Matter.Vector.normalise(Matter.Vector.sub(this.seePlayer.position, this.position));
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc
this.fireAngle = Math.atan2(this.fireDir.y, this.fireDir.x);
}
@@ -901,7 +901,7 @@ const mobs = {
}
},
facePlayer() {
const unitVector = Matter.Vector.normalise(Matter.Vector.sub(this.seePlayer.position, this.position));
const unitVector = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
const angle = Math.atan2(unitVector.y, unitVector.x);
Matter.Body.setAngle(this, angle - Math.PI);
},

View File

@@ -637,7 +637,6 @@ const mech = {
holdingMassScale: 0,
throwChargeRate: 0,
throwChargeMax: 0,
fieldFireCD: 0,
fieldShieldingScale: 0,
grabRange: 0,
fieldArc: 0,
@@ -653,7 +652,6 @@ const mech = {
this.isStealth = false;
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
this.holdingMassScale = 0.5;
this.fieldFireCD = 15;
this.fieldShieldingScale = 1; //scale energy loss after collision with mob
this.grabRange = 175;
this.fieldArc = 0.2; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
@@ -674,15 +672,15 @@ const mech = {
},
lookingAt(who) {
//calculate a vector from body to player and make it length 1
const diff = Matter.Vector.normalise(Matter.Vector.sub(who.position, mech.pos));
const diff = Vector.normalise(Vector.sub(who.position, mech.pos));
//make a vector for the player's direction of length 1
const dir = {
x: Math.cos(mech.angle),
y: Math.sin(mech.angle)
};
//the dot product of diff and dir will return how much over lap between the vectors
// console.log(Matter.Vector.dot(dir, diff))
if (Matter.Vector.dot(dir, diff) > this.fieldThreshold) {
// console.log(Vector.dot(dir, diff))
if (Vector.dot(dir, diff) > this.fieldThreshold) {
return true;
}
return false;
@@ -776,7 +774,7 @@ const mech = {
}
} else if (this.throwCharge > 0) {
//throw the body
this.fireCDcycle = mech.cycle + this.fieldFireCD;
this.fieldCDcycle = mech.cycle + 15;
this.isHolding = false;
//bullet-like collisions
this.holdingTarget.collisionFilter.category = cat.body;
@@ -876,7 +874,7 @@ const mech = {
}
},
pushMass(who) {
const speed = Matter.Vector.magnitude(Matter.Vector.sub(who.velocity, player.velocity))
const speed = Vector.magnitude(Vector.sub(who.velocity, player.velocity))
const fieldBlockCost = 0.03 + Math.sqrt(who.mass) * speed * 0.003 //0.012
if (mech.fieldMeter > fieldBlockCost * 0.6) { //shield needs at least some of the cost to block
mech.fieldMeter -= fieldBlockCost * mech.fieldShieldingScale;
@@ -885,7 +883,7 @@ const mech = {
mech.fieldCDcycle = mech.cycle + 10;
mech.holdingTarget = null
//knock backs
const unit = Matter.Vector.normalise(Matter.Vector.sub(player.position, who.position))
const unit = Vector.normalise(Vector.sub(player.position, who.position))
const massRoot = Math.sqrt(Math.min(12, Math.max(0.15, who.mass))); // masses above 12 can start to overcome the push back
Matter.Body.setVelocity(who, {
x: player.velocity.x - (15 * unit.x) / massRoot,
@@ -908,7 +906,7 @@ const mech = {
pushMobsFacing() { // find mobs in range and in direction looking
for (let i = 0, len = mob.length; i < len; ++i) {
if (
Matter.Vector.magnitude(Matter.Vector.sub(mob[i].position, player.position)) < this.grabRange &&
Vector.magnitude(Vector.sub(mob[i].position, player.position)) < this.grabRange &&
this.lookingAt(mob[i]) &&
Matter.Query.ray(map, mob[i].position, this.pos).length === 0
) {
@@ -920,7 +918,7 @@ const mech = {
pushMobs360(range = this.grabRange * 0.75) { // find mobs in range in any direction
for (let i = 0, len = mob.length; i < len; ++i) {
if (
Matter.Vector.magnitude(Matter.Vector.sub(mob[i].position, this.pos)) < range &&
Vector.magnitude(Vector.sub(mob[i].position, this.pos)) < range &&
Matter.Query.ray(map, mob[i].position, this.pos).length === 0
) {
mob[i].locatePlayer();
@@ -932,7 +930,7 @@ const mech = {
for (let i = 0, len = body.length; i < len; ++i) {
if (
body[i].speed > 12 && body[i].mass > 2 &&
Matter.Vector.magnitude(Matter.Vector.sub(body[i].position, this.pos)) < this.grabRange &&
Vector.magnitude(Vector.sub(body[i].position, this.pos)) < this.grabRange &&
this.lookingAt(body[i]) &&
Matter.Query.ray(map, body[i].position, this.pos).length === 0
) {
@@ -944,7 +942,7 @@ const mech = {
for (let i = 0, len = body.length; i < len; ++i) {
if (
body[i].speed > 12 && body[i].mass > 2 &&
Matter.Vector.magnitude(Matter.Vector.sub(body[i].position, this.pos)) < range &&
Vector.magnitude(Vector.sub(body[i].position, this.pos)) < range &&
this.lookingAt(body[i]) &&
Matter.Query.ray(map, body[i].position, this.pos).length === 0 &&
body[i].collisionFilter.category === cat.body
@@ -963,7 +961,7 @@ const mech = {
for (let i = 0, len = body.length; i < len; ++i) {
if (Matter.Query.ray(map, body[i].position, this.pos).length === 0) {
//is this next body a better target then my current best
const dist = Matter.Vector.magnitude(Matter.Vector.sub(body[i].position, this.pos));
const dist = Vector.magnitude(Vector.sub(body[i].position, this.pos));
const looking = this.lookingAt(body[i]);
// if (dist < grabbing.targetRange && (looking || !grabbing.lookingAt) && !body[i].isNotHoldable) {
if (dist < grabbing.targetRange && looking && !body[i].isNotHoldable) {
@@ -998,8 +996,8 @@ const mech = {
//triggers when a hold target exits and field button is released
this.isHolding = true;
//conserve momentum when player mass changes
totalMomentum = Matter.Vector.add(Matter.Vector.mult(player.velocity, player.mass), Matter.Vector.mult(this.holdingTarget.velocity, this.holdingTarget.mass))
Matter.Body.setVelocity(player, Matter.Vector.mult(totalMomentum, 1 / (mech.defaultMass + this.holdingTarget.mass)));
totalMomentum = Vector.add(Vector.mult(player.velocity, player.mass), Vector.mult(this.holdingTarget.velocity, this.holdingTarget.mass))
Matter.Body.setVelocity(player, Vector.mult(totalMomentum, 1 / (mech.defaultMass + this.holdingTarget.mass)));
this.definePlayerMass(mech.defaultMass + this.holdingTarget.mass * this.holdingMassScale)
//make block collide with nothing
@@ -1060,7 +1058,7 @@ const mech = {
mech.lookForPickUp();
mech.pushBodyFacing();
mech.pushMobsFacing();
} else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
mech.pickUp();
} else {
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
@@ -1126,7 +1124,7 @@ const mech = {
mech.wakeCheck();
mech.fieldCDcycle = mech.cycle + 120;
}
} else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
mech.wakeCheck();
mech.pickUp();
} else {
@@ -1158,6 +1156,9 @@ const mech = {
const DRAIN = 0.0006
if (mech.fieldMeter > DRAIN) {
mech.fieldMeter -= DRAIN;
mech.grabPowerUp();
mech.lookForPickUp();
mech.pushMobs360(120);
//calculate laser collision
let best;
@@ -1236,7 +1237,7 @@ const mech = {
best.who.locatePlayer();
//push mobs away
const force = Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(mech.pos, path[1])), -0.01 * Math.sqrt(best.who.mass))
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.01 * Math.sqrt(best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
// const angle = Math.atan2(player.position.y - best.who.position.y, player.position.x - best.who.position.x);
// const mass = Math.min(Math.sqrt(best.who.mass), 6);
@@ -1255,7 +1256,7 @@ const mech = {
});
} else if (!best.who.isStatic) {
//push blocks away
const force = Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(mech.pos, path[1])), -0.006 * Math.sqrt(Math.sqrt(best.who.mass)))
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.006 * Math.sqrt(Math.sqrt(best.who.mass)))
Matter.Body.applyForce(best.who, path[1], force)
}
}
@@ -1291,15 +1292,11 @@ const mech = {
ctx.arc(mech.pos.x, mech.pos.y, 110, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(255,0,255,0.05)"
ctx.fill();
mech.grabPowerUp();
mech.lookForPickUp();
mech.pushMobs360(120);
// mech.pushBody360(100); //disabled because doesn't work at short range
} else {
mech.fieldCDcycle = mech.cycle + 120; //if out of energy
}
} else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
mech.pickUp();
} else {
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
@@ -1331,8 +1328,8 @@ const mech = {
//look for nearby objects to make zero-g
function zeroG(who, mag = 1.06) {
for (let i = 0, len = who.length; i < len; ++i) {
sub = Matter.Vector.sub(who[i].position, mech.pos);
dist = Matter.Vector.magnitude(sub);
sub = Vector.sub(who[i].position, mech.pos);
dist = Vector.magnitude(sub);
if (dist < mech.grabRange) {
who[i].force.y -= who[i].mass * (game.g * mag); //add a bit more then standard gravity
}
@@ -1384,7 +1381,7 @@ const mech = {
//trigger cool down
mech.fieldCDcycle = mech.cycle + 120;
}
} else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
mech.pickUp();
mech.grabRange = 0
} else {
@@ -1397,7 +1394,7 @@ const mech = {
},
{
name: "standing wave harmonics",
description: "three oscillating <strong>shields</strong> are perminantly active<br><strong class='color-f'>energy</strong> regenerates while field is active",
description: "three oscillating <strong>shields</strong> are permanently active<br><strong class='color-f'>energy</strong> regenerates while field is active",
effect: () => {
mech.fieldMode = 4;
mech.fieldText();
@@ -1410,10 +1407,10 @@ const mech = {
mech.drawHold(mech.holdingTarget);
mech.holding();
mech.throw();
} else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0)) { //not hold but field button is pressed
} else if (((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle && mech.fieldMeter > 0)) { //not hold but field button is pressed
mech.grabPowerUp();
mech.lookForPickUp(180);
} else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle) { //holding, but field button is released
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
mech.pickUp();
} else {
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
@@ -1464,7 +1461,7 @@ const mech = {
mech.lookForPickUp();
mech.pushMobsFacing();
mech.pushBodyFacing();
} else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
mech.pickUp();
} else {
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
@@ -1511,7 +1508,7 @@ const mech = {
} else {
mech.fieldCDcycle = mech.cycle + 120;
}
} else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
mech.pickUp();
} else {
mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
@@ -1545,7 +1542,7 @@ const mech = {
// //try to hack a mob
// for (let i = 0, len = mob.length; i < len; ++i) {
// if (
// Matter.Vector.magnitude(Matter.Vector.sub(mob[i].position, this.pos)) < this.grabRange &&
// Vector.magnitude(Vector.sub(mob[i].position, this.pos)) < this.grabRange &&
// this.lookingAt(mob[i]) &&
// Matter.Query.ray(map, mob[i].position, this.pos).length === 0
// ) {

View File

@@ -3,7 +3,7 @@ let powerUp = [];
const powerUps = {
heal: {
name: "heal",
color: "#0fb",
color: "#0eb",
size() {
return 40 * Math.sqrt(0.1 + Math.random() * 0.5);
},
@@ -61,20 +61,25 @@ const powerUps = {
},
effect() {
const previousMode = mech.fieldMode
if (!this.mode) { //this.mode is set if the power up has been ejected from player
mode = mech.fieldMode
while (mode === mech.fieldMode) {
mode = Math.ceil(Math.random() * (mech.fieldUpgrades.length - 1))
}
mech.fieldUpgrades[mode].effect(); //choose random field upgrade that you don't already have
} else {
if (this.mode) { //this.mode is set if the power up has been ejected from player
mech.fieldUpgrades[this.mode].effect(); //set a predetermined power up
} else { //choose a random mode that you don't already have
availableModes = []
for (let i = 1; i < mech.fieldUpgrades.length; i++) { //start on 1 to skip the default field
if (i !== previousMode) {
availableModes.push(i)
}
}
const mode = availableModes[Math.floor(Math.random() * availableModes.length)]
mech.fieldUpgrades[mode].effect();
}
//pop the old field out in case player wants to swap back
if (previousMode !== 0) {
mech.fieldCDcycle = mech.cycle + 40; //trigger fieldCD to stop power up grab automatic pick up of spawn
powerUps.spawn(mech.pos.x, mech.pos.y - 15, "field", false, previousMode);
setTimeout(function () {
powerUps.spawn(mech.pos.x, mech.pos.y - 15, "field", false, previousMode);
}, 100);
}
}
},
@@ -208,10 +213,10 @@ const powerUps = {
},
spawn(x, y, target, moving = true, mode = null) {
if (!level.isBuildRun || target === "heal" || target === "ammo") {
let i = powerUp.length;
let index = powerUp.length;
target = powerUps[target];
size = target.size();
powerUp[i] = Matter.Bodies.polygon(x, y, 0, size, {
powerUp[index] = Matter.Bodies.polygon(x, y, 0, size, {
density: 0.001,
frictionAir: 0.01,
restitution: 0.8,
@@ -223,17 +228,20 @@ const powerUps = {
},
color: target.color,
effect: target.effect,
mode: mode,
name: target.name,
size: size
});
if (mode) {
console.log(mode)
powerUp[index].mode = mode
}
if (moving) {
Matter.Body.setVelocity(powerUp[i], {
Matter.Body.setVelocity(powerUp[index], {
x: (Math.random() - 0.5) * 15,
y: Math.random() * -9 - 3
});
}
World.add(engine.world, powerUp[i]); //add to world
World.add(engine.world, powerUp[index]); //add to world
}
},
};

View File

@@ -104,7 +104,7 @@ const spawn = {
ctx.beginPath();
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i] != this && mob[i].dropPowerUp) { //don't tether to self, bullets, shields, ...
const distance2 = Matter.Vector.magnitudeSquared(Matter.Vector.sub(this.position, mob[i].position))
const distance2 = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position))
if (distance2 < this.groupingRangeMax) {
if (!mob[i].seePlayer.recall) mob[i].seePlayerByDistAndLOS(); //wake up sleepy mobs
if (distance2 > this.groupingRangeMin) {
@@ -159,8 +159,8 @@ const spawn = {
// let closeDist = Infinity;
// for (let i = 0; i < mob.length; i++) {
// if (mob[i] != this && Matter.Query.ray(map, this.position, mob[i].position).length === 0) {
// const TARGET_VECTOR = Matter.Vector.sub(this.position, mob[i].position)
// const DIST = Matter.Vector.magnitude(TARGET_VECTOR) * mob[i].health * mob[i].health * mob[i].health; //distance is multiplied by mob health to prioritize low health mobs
// const TARGET_VECTOR = Vector.sub(this.position, mob[i].position)
// const DIST = Vector.magnitude(TARGET_VECTOR) * mob[i].health * mob[i].health * mob[i].health; //distance is multiplied by mob health to prioritize low health mobs
// if (DIST < closeDist) {
// closeDist = DIST;
// this.lockedOn = mob[i]
@@ -171,15 +171,15 @@ const spawn = {
// //move away from player if too close
// if (this.distanceToPlayer2() < 400000) {
// const TARGET_VECTOR = Matter.Vector.sub(this.position, player.position)
// this.force = Matter.Vector.mult(Matter.Vector.normalise(TARGET_VECTOR), this.mass * this.accelMag * 1.4)
// const TARGET_VECTOR = Vector.sub(this.position, player.position)
// this.force = Vector.mult(Vector.normalise(TARGET_VECTOR), this.mass * this.accelMag * 1.4)
// if (this.lockedOn) this.lockedOn = null
// } else if (this.lockedOn && this.lockedOn.alive) {
// //move towards and heal locked on target
// const TARGET_VECTOR = Matter.Vector.sub(this.position, this.lockedOn.position)
// const DIST = Matter.Vector.magnitude(TARGET_VECTOR);
// const TARGET_VECTOR = Vector.sub(this.position, this.lockedOn.position)
// const DIST = Vector.magnitude(TARGET_VECTOR);
// if (DIST > 250) {
// this.force = Matter.Vector.mult(Matter.Vector.normalise(TARGET_VECTOR), -this.mass * this.accelMag)
// this.force = Vector.mult(Vector.normalise(TARGET_VECTOR), -this.mass * this.accelMag)
// } else {
// if (this.lockedOn.health < 1) {
// this.lockedOn.health += 0.002;
@@ -202,15 +202,15 @@ const spawn = {
// that.searchTarget = mob[Math.floor(Math.random() * (mob.length - 1))].position;
// };
// const sub = Matter.Vector.sub(this.searchTarget, this.position);
// if (Matter.Vector.magnitude(sub) > this.radius * 2) {
// const sub = Vector.sub(this.searchTarget, this.position);
// if (Vector.magnitude(sub) > this.radius * 2) {
// ctx.beginPath();
// ctx.strokeStyle = "#aaa";
// ctx.moveTo(this.position.x, this.position.y);
// ctx.lineTo(this.searchTarget.x, this.searchTarget.y);
// ctx.stroke();
// //accelerate at 0.6 of normal acceleration
// this.force = Matter.Vector.mult(Matter.Vector.normalise(sub), this.accelMag * this.mass * 0.6);
// this.force = Vector.mult(Vector.normalise(sub), this.accelMag * this.mass * 0.6);
// } else {
// //after reaching random target switch to new target
// newTarget(this);
@@ -367,11 +367,11 @@ const spawn = {
if (this.cdBurst2 < game.cycle && this.angularSpeed < 0.01) {
this.cdBurst2 = Infinity;
this.cdBurst1 = game.cycle + 40;
this.burstDir = Matter.Vector.normalise(Matter.Vector.sub(this.seePlayer.position, this.position));
this.burstDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
} else if (this.cdBurst1 < game.cycle) {
this.cdBurst2 = game.cycle + this.delay;
this.cdBurst1 = Infinity;
this.force = Matter.Vector.mult(this.burstDir, this.mass * 0.25);
this.force = Vector.mult(this.burstDir, this.mass * 0.25);
this.fill = this.rememberFill;
} else if (this.cdBurst1 != Infinity) {
this.torque += 0.000035 * this.inertia;
@@ -383,7 +383,7 @@ const spawn = {
ctx.strokeStyle = "rgba(0,0,0,0.2)";
ctx.lineWidth = 3;
ctx.setLineDash([10, 20]); //30
const dir = Matter.Vector.add(this.position, Matter.Vector.mult(this.burstDir, mag));
const dir = Vector.add(this.position, Vector.mult(this.burstDir, mag));
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
ctx.lineTo(dir.x, dir.y);
@@ -442,7 +442,7 @@ const spawn = {
ctx.fill();
//when player is inside event horizon
if (Matter.Vector.magnitude(Matter.Vector.sub(this.position, player.position)) < eventHorizon && !mech.isStealth) {
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon && !mech.isStealth) {
mech.damage(0.00015 * game.dmgScale);
if (mech.fieldMeter > 0.1) mech.fieldMeter -= 0.007
@@ -532,7 +532,7 @@ const spawn = {
ctx.fillStyle = "rgba(0,0,0,0.05)";
ctx.fill();
//when player is inside event horizon
if (Matter.Vector.magnitude(Matter.Vector.sub(this.position, player.position)) < eventHorizon && !mech.isStealth) {
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon && !mech.isStealth) {
mech.damage(0.00015 * game.dmgScale);
if (mech.fieldMeter > 0.1) mech.fieldMeter -= 0.007
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
@@ -595,8 +595,8 @@ const spawn = {
this.attraction();
const rangeWidth = 2000; //this is sqrt of 4000000 from above if()
//targeting laser will slowly move from the mob to the player's position
this.laserPos = Matter.Vector.add(this.laserPos, Matter.Vector.mult(Matter.Vector.sub(player.position, this.laserPos), 0.1));
let targetDist = Matter.Vector.magnitude(Matter.Vector.sub(this.laserPos, mech.pos));
this.laserPos = Vector.add(this.laserPos, Vector.mult(Vector.sub(player.position, this.laserPos), 0.1));
let targetDist = Vector.magnitude(Vector.sub(this.laserPos, mech.pos));
const r = 10;
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
@@ -616,14 +616,14 @@ const spawn = {
}
if (dist2 > 80000) {
const laserWidth = 0.002;
let laserOffR = Matter.Vector.rotateAbout(this.laserPos, (targetDist - r) * laserWidth, this.position);
let sub = Matter.Vector.normalise(Matter.Vector.sub(laserOffR, this.position));
laserOffR = Matter.Vector.add(laserOffR, Matter.Vector.mult(sub, rangeWidth));
let laserOffR = Vector.rotateAbout(this.laserPos, (targetDist - r) * laserWidth, this.position);
let sub = Vector.normalise(Vector.sub(laserOffR, this.position));
laserOffR = Vector.add(laserOffR, Vector.mult(sub, rangeWidth));
ctx.lineTo(laserOffR.x, laserOffR.y);
let laserOffL = Matter.Vector.rotateAbout(this.laserPos, (targetDist - r) * -laserWidth, this.position);
sub = Matter.Vector.normalise(Matter.Vector.sub(laserOffL, this.position));
laserOffL = Matter.Vector.add(laserOffL, Matter.Vector.mult(sub, rangeWidth));
let laserOffL = Vector.rotateAbout(this.laserPos, (targetDist - r) * -laserWidth, this.position);
sub = Vector.normalise(Vector.sub(laserOffL, this.position));
laserOffL = Vector.add(laserOffL, Vector.mult(sub, rangeWidth));
ctx.lineTo(laserOffL.x, laserOffL.y);
ctx.fillStyle = `rgba(0,0,255,${Math.max(0,0.3*r/targetDist)})`
ctx.fill();
@@ -806,8 +806,8 @@ const spawn = {
// this.isBig = false;
// }
// } else if (this.seePlayer.yes && this.cd < game.cycle) {
// const dist = Matter.Vector.sub(this.seePlayer.position, this.position);
// const distMag2 = Matter.Vector.magnitudeSquared(dist);
// const dist = Vector.sub(this.seePlayer.position, this.position);
// const distMag2 = Vector.magnitudeSquared(dist);
// if (distMag2 < 80000) {
// this.cd = game.cycle + this.delay;
// Matter.Body.scale(this, this.scaleMag, this.scaleMag);

View File

@@ -4,7 +4,7 @@ body {
/* overflow: hidden; */
background-color: #fff;
user-select: none;
/*cursor: crosshair;*/
cursor: auto;
}
canvas {
@@ -60,6 +60,25 @@ summary {
z-index: 12;
}
#choose-grid {
padding: 10px;
margin: 0px;
border-radius: 7px;
position: absolute;
bottom: 0px;
left: 0px;
z-index: 12;
background-color: #c4ccd8;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
grid-auto-rows: minmax(auto, auto);
grid-gap: 10px;
z-index: 12;
font-size: 1.3em;
cursor: "auto";
}
#build-grid {
padding: 16px;
margin: 0px;
@@ -91,9 +110,10 @@ summary {
font-size: 0.65em;
/* display: flex; */
}
.grid-title {
padding-bottom: 6px;
font-size:1.3em;
font-size: 1.3em;
font-weight: 600;
}