added 5 new mods, power up display, game balance
This commit is contained in:
93
index.html
93
index.html
@@ -30,7 +30,6 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<!-- <body oncontextmenu="return false"> -->
|
<!-- <body oncontextmenu="return false"> -->
|
||||||
<div id='guns'></div>
|
<div id='guns'></div>
|
||||||
<div id='field'></div>
|
<div id='field'></div>
|
||||||
@@ -77,34 +76,82 @@
|
|||||||
<canvas id="canvas"></canvas>
|
<canvas id="canvas"></canvas>
|
||||||
<!-- ********** intro page ***********************************************
|
<!-- ********** intro page ***********************************************
|
||||||
******************************************************************************* -->
|
******************************************************************************* -->
|
||||||
|
|
||||||
|
<!-- <div id="build-details">
|
||||||
|
<div class="build-grid-module"></div>
|
||||||
|
<details>
|
||||||
|
<summary>build</summary>
|
||||||
|
<div id="details-div">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</div> -->
|
||||||
|
<div id="build-grid">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<button type="button" id="build-button">builds</button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <div id="build">
|
||||||
|
<details>
|
||||||
|
<summary>builds</summary>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
|
||||||
<div id="controls">
|
<div id="controls">
|
||||||
<details>
|
<details>
|
||||||
<summary>info</summary>
|
<summary>about</summary>
|
||||||
<div id="details-div">
|
<div id="details-div">
|
||||||
|
<div style="line-height: 150%;">
|
||||||
|
<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>
|
||||||
|
<option value="4">hard</option>
|
||||||
|
<option value="8">why...</option>
|
||||||
|
</select>
|
||||||
|
<br>
|
||||||
|
<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>
|
||||||
|
<select name="fps-select" id="fps-select">
|
||||||
|
<option value="max">no fps cap</option>
|
||||||
|
<option value="72" selected>72 fps cap</option>
|
||||||
|
<option value="60">60 fps cap</option>
|
||||||
|
<option value="45">45 fps cap</option>
|
||||||
|
<option value="30">30 fps cap</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>FIRE</td>
|
<th>FIRE</th>
|
||||||
<td>left mouse</td>
|
<td>left mouse</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>FIELD</td>
|
<th>FIELD</th>
|
||||||
<td>right mouse / spacebar</td>
|
<td>right mouse / spacebar</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>MOVE</td>
|
<th>MOVE</th>
|
||||||
<td>WASD / arrows</td>
|
<td>WASD / arrows</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>GUNS</td>
|
<th>GUNS</th>
|
||||||
<td>Q / E / mouse wheel</td>
|
<td>Q / E / mouse wheel</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>ZOOM</td>
|
<th>ZOOM</th>
|
||||||
<td>+ / -</td>
|
<td>+ / -</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>PAUSE</td>
|
<th>PAUSE</th>
|
||||||
<td>P</td>
|
<td>P</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- <tr>
|
<!-- <tr>
|
||||||
@@ -140,35 +187,9 @@
|
|||||||
<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>
|
||||||
<br>
|
<br>
|
||||||
N-gon is also on <a href="https://lilgreenland.itch.io/n-gon">itch.io</a>.
|
n-gon is also hosted at <a href="https://lilgreenland.itch.io/n-gon">itch.io</a>.
|
||||||
|
<br>
|
||||||
<br>
|
<br>
|
||||||
</div>
|
|
||||||
</details>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="settings">
|
|
||||||
<details>
|
|
||||||
<summary>settings</summary>
|
|
||||||
<div id="details-div">
|
|
||||||
<label for="body-damage" title="allow damage from heavy, fast moving blocks">block collision damage:</label>
|
|
||||||
<input type="checkbox" id="body-damage" name="body-damage" checked>
|
|
||||||
<br><br>
|
|
||||||
<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>
|
|
||||||
<option value="4">hard</option>
|
|
||||||
<option value="8">why...</option>
|
|
||||||
</select>
|
|
||||||
<br><br>
|
|
||||||
<label for="fps-select" title="use this to slow the game down">FPS cap:</label>
|
|
||||||
<select name="fps-select" id="fps-select">
|
|
||||||
<option value="max">no fps cap</option>
|
|
||||||
<option value="72" selected>72 fps cap</option>
|
|
||||||
<option value="60">60 fps cap</option>
|
|
||||||
<option value="45">45 fps cap</option>
|
|
||||||
<option value="30">30 fps cap</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
186
js/bullets.js
186
js/bullets.js
@@ -19,7 +19,12 @@ const b = {
|
|||||||
modExtraDmg: null,
|
modExtraDmg: null,
|
||||||
annihilation: null,
|
annihilation: null,
|
||||||
fullHeal: null,
|
fullHeal: null,
|
||||||
modSquirrelFx: 1,
|
modSquirrelFx: null,
|
||||||
|
modIsCrit: null,
|
||||||
|
modMoreDrops: null,
|
||||||
|
isModLowHealthDmg: null,
|
||||||
|
isModFarAwayDmg: null,
|
||||||
|
isModMonogamy: null,
|
||||||
setModDefaults() {
|
setModDefaults() {
|
||||||
b.modCount = 0;
|
b.modCount = 0;
|
||||||
b.modFireRate = 1;
|
b.modFireRate = 1;
|
||||||
@@ -37,6 +42,11 @@ const b = {
|
|||||||
b.modAnnihilation = false;
|
b.modAnnihilation = false;
|
||||||
b.isModFullHeal = false;
|
b.isModFullHeal = false;
|
||||||
b.modSquirrelFx = 1;
|
b.modSquirrelFx = 1;
|
||||||
|
b.modIsCrit = false;
|
||||||
|
b.modMoreDrops = 0;
|
||||||
|
b.isModLowHealthDmg = false;
|
||||||
|
b.isModFarAwayDmg = false;
|
||||||
|
b.isModMonogamy = false;
|
||||||
mech.Fx = 0.015;
|
mech.Fx = 0.015;
|
||||||
mech.jumpForce = 0.38;
|
mech.jumpForce = 0.38;
|
||||||
mech.throwChargeRate = 2;
|
mech.throwChargeRate = 2;
|
||||||
@@ -47,17 +57,17 @@ const b = {
|
|||||||
},
|
},
|
||||||
mods: [{
|
mods: [{
|
||||||
name: "depleted uranium rounds",
|
name: "depleted uranium rounds",
|
||||||
description: "your <strong class='color-b'>bullets</strong> are larger and do more physical <span class='color-d'>damage</span>",
|
description: "your <strong>bullets</strong> are 10% larger<br>increased momentum and physical <strong class='color-d'>damage</strong>",
|
||||||
have: false, //0
|
have: false, //0
|
||||||
effect: () => {
|
effect: () => {
|
||||||
//good for guns that do mostly projectile damage:
|
//good for guns that do mostly projectile damage:
|
||||||
//testing at 1.08: spray(point blank)(+0.25), one shot(+0.16), wave beam(point blank)(+0.14)
|
//testing at 1.08: spray(point blank)(+0.25), one shot(+0.16), wave beam(point blank)(+0.14)
|
||||||
b.modBulletSize = 1.07;
|
b.modBulletSize = 1.1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "auto-loading heuristics",
|
name: "auto-loading heuristics",
|
||||||
description: "your rate of fire is 15% higher",
|
description: "your <strong>rate of fire</strong> is 15% higher",
|
||||||
have: false, //1
|
have: false, //1
|
||||||
effect: () => { //good for guns with extra ammo: needles, M80, rapid fire, flak, super balls
|
effect: () => { //good for guns with extra ammo: needles, M80, rapid fire, flak, super balls
|
||||||
b.modFireRate = 0.85
|
b.modFireRate = 0.85
|
||||||
@@ -65,7 +75,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "desublimated ammunition",
|
name: "desublimated ammunition",
|
||||||
description: "use 50% less <strong class='color-b'>ammo</strong> when <strong>crouching</strong>",
|
description: "use 50% less <strong>ammo</strong> when <strong>crouching</strong>",
|
||||||
have: false, //2
|
have: false, //2
|
||||||
effect: () => { //good with guns that have less ammo: one shot, grenades, missiles, super balls, spray
|
effect: () => { //good with guns that have less ammo: one shot, grenades, missiles, super balls, spray
|
||||||
b.modNoAmmo = 1
|
b.modNoAmmo = 1
|
||||||
@@ -73,7 +83,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Lorentzian topology",
|
name: "Lorentzian topology",
|
||||||
description: "your <strong class='color-b'>bullets</strong> last 40% longer",
|
description: "your <strong>bullets</strong> last 40% <strong>longer</strong>",
|
||||||
have: false, //3
|
have: false, //3
|
||||||
effect: () => { //good with: drones, super balls, spore, missiles, wave beam(range), rapid fire(range), flak(range)
|
effect: () => { //good with: drones, super balls, spore, missiles, wave beam(range), rapid fire(range), flak(range)
|
||||||
b.isModBulletsLastLonger = 1.40
|
b.isModBulletsLastLonger = 1.40
|
||||||
@@ -81,7 +91,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "anti-matter cores",
|
name: "anti-matter cores",
|
||||||
description: "the radius of your <strong class='color-e'>explosions</strong> is doubled<br><span style='opacity:0.3;'>be careful</span>",
|
description: "the <strong>radius</strong> of your <strong class='color-e'>explosions</strong> is doubled<br><strong style='opacity:0.3;'>be careful</strong>",
|
||||||
have: false, //4
|
have: false, //4
|
||||||
effect: () => { //at 1.4 gives a flat 40% increase, and increased range, balanced by limited guns and self damage
|
effect: () => { //at 1.4 gives a flat 40% increase, and increased range, balanced by limited guns and self damage
|
||||||
//testing at 1.3: grenade(+0.3), missiles, flak, M80
|
//testing at 1.3: grenade(+0.3), missiles, flak, M80
|
||||||
@@ -90,7 +100,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ceramic plating",
|
name: "ceramic plating",
|
||||||
description: "you take no damage from area effects<br>immune to <strong class='color-e'>explosions</strong> and enemy fields",
|
description: "<strong>immune</strong> to <strong class='color-e'>explosions</strong> and enemy fields",
|
||||||
have: false, //5
|
have: false, //5
|
||||||
effect: () => {
|
effect: () => {
|
||||||
b.isModAoEImmunity = true; //good for guns with explosions
|
b.isModAoEImmunity = true; //good for guns with explosions
|
||||||
@@ -98,7 +108,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ablative synthesis",
|
name: "ablative synthesis",
|
||||||
description: "after taking <span class='color-d'>damage</span>, there is a chance that your damaged parts will be rebuilt as <strong class='color-b'>drones</strong>",
|
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after taking <strong class='color-d'>damage</strong>",
|
||||||
have: false, //6
|
have: false, //6
|
||||||
effect: () => { //makes dangerous situations more survivable
|
effect: () => { //makes dangerous situations more survivable
|
||||||
b.isModDroneOnDamage = true;
|
b.isModDroneOnDamage = true;
|
||||||
@@ -106,7 +116,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "zoospore vector",
|
name: "zoospore vector",
|
||||||
description: "when an enemy <span style='color: #888;'>dies</span> it has a 20% chance to release <strong class='color-s'>spores</strong>",
|
description: "enemies can discharge <strong class='color-s'>spores</strong> on <strong>death</strong><br><strong class='color-s'>spores</strong> seek out enemies",
|
||||||
have: false, //7
|
have: false, //7
|
||||||
effect: () => { //good late game maybe?
|
effect: () => { //good late game maybe?
|
||||||
b.modSpores = 0.20;
|
b.modSpores = 0.20;
|
||||||
@@ -114,16 +124,15 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "field siphon",
|
name: "field siphon",
|
||||||
description: "regenerate <span class='color-f'>field energy</span> proportional to your <span class='color-d'>damage</span> done",
|
description: "gain <strong class='color-f'>energy</strong> proportional to <strong class='color-d'>damage</strong> done",
|
||||||
have: false, //8
|
have: false, //8
|
||||||
effect: () => { //good with laser, and all fields
|
effect: () => { //good with laser, and all fields
|
||||||
|
b.modEnergySiphon = 0.15;
|
||||||
b.modEnergySiphon = 0.2;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "entropy transfer",
|
name: "entropy transfer",
|
||||||
description: "<span class='color-h'>heal</span> proportional to your <span class='color-d'>damage</span> done",
|
description: "<strong class='color-h'>heal</strong> proportional to <strong class='color-d'>damage</strong> done",
|
||||||
have: false, //9
|
have: false, //9
|
||||||
effect: () => { //good with guns that overkill: one shot, grenade
|
effect: () => { //good with guns that overkill: one shot, grenade
|
||||||
b.modHealthDrain = 0.01;
|
b.modHealthDrain = 0.01;
|
||||||
@@ -131,7 +140,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "quantum immortality",
|
name: "quantum immortality",
|
||||||
description: "after you <strong style='color: #606;'>die</strong> continue in an <em>alternate reality</em><br>guns, ammo, and field are randomized",
|
description: "after <strong>dying</strong>, continue in an <em>alternate reality</em><br>guns, ammo, and field are randomized",
|
||||||
have: false, //10
|
have: false, //10
|
||||||
effect: () => {
|
effect: () => {
|
||||||
b.modIsImmortal = true;
|
b.modIsImmortal = true;
|
||||||
@@ -139,7 +148,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "fluoroantimonic acid",
|
name: "fluoroantimonic acid",
|
||||||
description: "your bullets do extra chemical <span class='color-d'>damage</span> each time they make contact",
|
description: "each bullet does extra chemical <strong class='color-d'>damage</strong>",
|
||||||
have: false, //11
|
have: false, //11
|
||||||
effect: () => { //good with guns that fire many bullets at low speeds, minigun, drones, junk-bots, shotgun, superballs, wavebeam
|
effect: () => { //good with guns that fire many bullets at low speeds, minigun, drones, junk-bots, shotgun, superballs, wavebeam
|
||||||
b.modExtraDmg = 0.1
|
b.modExtraDmg = 0.1
|
||||||
@@ -147,7 +156,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "annihilation",
|
name: "annihilation",
|
||||||
description: "after you touch any enemy, they are <strong class='color-l'>annihilated</strong><br><em>touching enemies <span class='color-d'>damages</span> you, but <span class='color-d'>destroys</span> them</em>",
|
description: "after <strong>touching</strong> enemies, they are annihilated",
|
||||||
have: false, //12
|
have: false, //12
|
||||||
effect: () => { //good with mods that heal: superconductive healing, entropy transfer
|
effect: () => { //good with mods that heal: superconductive healing, entropy transfer
|
||||||
b.modAnnihilation = true
|
b.modAnnihilation = true
|
||||||
@@ -155,17 +164,16 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "recursive healing",
|
name: "recursive healing",
|
||||||
description: "<span class='color-h'>heals</span> bring you to full health",
|
description: "<strong class='color-h'>healing</strong> power ups bring you to <strong>full health</strong>",
|
||||||
have: false, //13
|
have: false, //13
|
||||||
effect: () => { // good with ablative synthesis, electrostatic field
|
effect: () => { // good with ablative synthesis, melee builds
|
||||||
b.isModFullHeal = true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Gauss rifle",
|
name: "Gauss rifle",
|
||||||
description: "<span style='color:#f0f;'>magnetically</span> <strong>launch blocks</strong> at much higher speeds<br>carry more massive blocks<br><em>hold right click to charge up a throw and release to fire</em>",
|
description: "<strong>launch blocks</strong> at much higher speeds<br>carry more massive blocks",
|
||||||
have: false, //14
|
have: false, //14
|
||||||
effect: () => { // good with ablative synthesis, electrostatic field
|
effect: () => { // good with guns that run out of ammo
|
||||||
b.isModFullHeal = true
|
b.isModFullHeal = true
|
||||||
mech.throwChargeRate = 4;
|
mech.throwChargeRate = 4;
|
||||||
mech.throwChargeMax = 150;
|
mech.throwChargeMax = 150;
|
||||||
@@ -174,15 +182,54 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "squirrel-cage rotor",
|
name: "squirrel-cage rotor",
|
||||||
description: "jump higher and move faster",
|
description: "your legs produce 20% more force<br><strong>jump</strong> higher and <strong>move</strong> faster",
|
||||||
have: false, //15
|
have: false, //15
|
||||||
effect: () => { //
|
effect: () => { // good with melee builds, content skipping builds
|
||||||
b.modSquirrelFx = 1.2;
|
b.modSquirrelFx = 1.2;
|
||||||
mech.Fx = 0.015 * b.modSquirrelFx;
|
mech.Fx = 0.015 * b.modSquirrelFx;
|
||||||
mech.jumpForce = 0.38 * 1.1;
|
mech.jumpForce = 0.38 * 1.1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "fracture analysis",
|
||||||
|
description: "<strong>6x</strong> physical <strong class='color-d'>damage</strong> to unaware enemies<br><em>enemies aware of you have a health bar</em>",
|
||||||
|
have: false, //16
|
||||||
|
effect: () => { // good with high damage guns that strike from a distance: rail gun, drones, flechettes, spores, grenade, vacuum bomb
|
||||||
|
b.modIsCrit = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "kinetic bombardment",
|
||||||
|
description: "do extra <strong class='color-d'>damage</strong> from farther away<br><em>up to 50% increase at about 30 steps away</em>",
|
||||||
|
have: false, //17
|
||||||
|
effect: () => { // good with annihilation, melee builds
|
||||||
|
b.isModFarAwayDmg = true; //used in mob.damage()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "quasistatic equilibrium",
|
||||||
|
description: "do extra <strong class='color-d'>damage</strong> at low health<br><em>up to 50% increase when near death</em>",
|
||||||
|
have: false, //18
|
||||||
|
effect: () => { // good with annihilation, melee builds
|
||||||
|
b.isModLowHealthDmg = true; //used in mob.damage()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bayesian inference",
|
||||||
|
description: "<strong>20%</strong> chance for double <strong>power ups</strong> to drop",
|
||||||
|
have: false, //19
|
||||||
|
effect: () => { // good with long term planning
|
||||||
|
b.modMoreDrops = 0.20;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "monogamy",
|
||||||
|
description: "equipping your first gun reduces <strong class='color-d'>damage</strong> taken<br>scales by <strong>7%</strong> for each gun in your inventory",
|
||||||
|
have: false, //20
|
||||||
|
effect: () => { // good with long term planning
|
||||||
|
b.isModMonogamy = true
|
||||||
|
}
|
||||||
|
},
|
||||||
],
|
],
|
||||||
giveMod(i) {
|
giveMod(i) {
|
||||||
b.mods[i].effect(); //give specific mod
|
b.mods[i].effect(); //give specific mod
|
||||||
@@ -226,7 +273,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mech.fireCDcycle = mech.cycle + 30; //cooldown
|
mech.fireCDcycle = mech.cycle + 30; //cooldown
|
||||||
// game.makeTextLog("<div style='font-size:140%;'>NO AMMO</div><span class = 'box'>E</span> / <span class = 'box'>Q</span>", 200);
|
// game.makeTextLog("<div style='font-size:140%;'>NO AMMO</div><strong class = 'box'>E</strong> / <strong class = 'box'>Q</strong>", 200);
|
||||||
game.replaceTextLog = true;
|
game.replaceTextLog = true;
|
||||||
game.makeTextLog("<div style='font-size:140%;'>NO AMMO</div> <p style='font-size:90%;'><strong>Q</strong>, <strong>E</strong>, and <strong>mouse wheel</strong> change weapons</p>", 200);
|
game.makeTextLog("<div style='font-size:140%;'>NO AMMO</div> <p style='font-size:90%;'><strong>Q</strong>, <strong>E</strong>, and <strong>mouse wheel</strong> change weapons</p>", 200);
|
||||||
}
|
}
|
||||||
@@ -496,7 +543,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
guns: [{
|
guns: [{
|
||||||
name: "laser", //0
|
name: "laser", //0
|
||||||
description: "fire a <span style='color:#f00;'>beam</span> of coherent light<br>reflects off walls at 75% intensity<br>uses <span class='color-f'>energy</span> instead of ammunition",
|
description: "emit a beam of <strong class='color-d'>damaging</strong> coherent light<br>uses <strong class='color-f'>energy</strong> instead of ammunition",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
// ammoPack: 350,
|
// ammoPack: 350,
|
||||||
ammoPack: Infinity,
|
ammoPack: Infinity,
|
||||||
@@ -658,17 +705,18 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "rail gun", //1
|
name: "rail gun", //1
|
||||||
description: "<strong>hold left mouse</strong> to charge and release to fire<br>charging repels small enemies<br><em>crouching charges quicker and reduces recoil</em>",
|
description: "magnetically launch a dense rod<br><strong>hold left mouse</strong> to charge and <strong>repel</strong> enemies",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 12,
|
ammoPack: 12,
|
||||||
have: false,
|
have: false,
|
||||||
isStarterGun: false,
|
isStarterGun: false,
|
||||||
fire() {
|
fire() {
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
bullet[me] = Bodies.rectangle(9, -90, 0.01 * b.modBulletSize, 0.0017 * b.modBulletSize, {
|
bullet[me] = Bodies.rectangle(0, 0, 0.012 * b.modBulletSize, 0.0022 * b.modBulletSize, {
|
||||||
// density: 0.0015, //frictionAir: 0.01, //restitution: 0,
|
density: 0.002, //0.001 is normal
|
||||||
angle: 0,
|
//frictionAir: 0.01, //restitution: 0,
|
||||||
friction: 0.5,
|
// angle: 0,
|
||||||
|
// friction: 0.5,
|
||||||
frictionAir: 0,
|
frictionAir: 0,
|
||||||
dmg: 3 + b.modExtraDmg, //damage done in addition to the damage from momentum
|
dmg: 3 + b.modExtraDmg, //damage done in addition to the damage from momentum
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
@@ -698,7 +746,7 @@ const b = {
|
|||||||
y: mech.pos.y
|
y: mech.pos.y
|
||||||
})
|
})
|
||||||
Matter.Body.setAngle(this, mech.angle)
|
Matter.Body.setAngle(this, mech.angle)
|
||||||
const speed = 80
|
const speed = 85
|
||||||
Matter.Body.setVelocity(this, {
|
Matter.Body.setVelocity(this, {
|
||||||
x: mech.Vx / 2 + speed * this.charge * Math.cos(mech.angle),
|
x: mech.Vx / 2 + speed * this.charge * Math.cos(mech.angle),
|
||||||
y: mech.Vy / 2 + speed * this.charge * Math.sin(mech.angle)
|
y: mech.Vy / 2 + speed * this.charge * Math.sin(mech.angle)
|
||||||
@@ -714,6 +762,7 @@ const b = {
|
|||||||
for (let i = 0, len = body.length; i < len; ++i) {
|
for (let i = 0, len = body.length; i < len; ++i) {
|
||||||
const SUB = Matter.Vector.sub(body[i].position, mech.pos)
|
const SUB = Matter.Vector.sub(body[i].position, mech.pos)
|
||||||
const DISTANCE = Matter.Vector.magnitude(SUB)
|
const DISTANCE = Matter.Vector.magnitude(SUB)
|
||||||
|
|
||||||
if (DISTANCE < RANGE) {
|
if (DISTANCE < RANGE) {
|
||||||
const DEPTH = Math.max(RANGE - DISTANCE, 100)
|
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 FORCE = Matter.Vector.mult(Matter.Vector.normalise(SUB), 0.005 * Math.sqrt(DEPTH) * Math.sqrt(body[i].mass))
|
||||||
@@ -732,8 +781,6 @@ const b = {
|
|||||||
// mob[i].force.y += FORCE.y
|
// mob[i].force.y += FORCE.y
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
} else { // charging on mouse down
|
} else { // charging on mouse down
|
||||||
mech.fireCDcycle = Infinity //can't fire until mouse is released
|
mech.fireCDcycle = Infinity //can't fire until mouse is released
|
||||||
if (mech.crouch) {
|
if (mech.crouch) {
|
||||||
@@ -750,7 +797,9 @@ const b = {
|
|||||||
// if (DISTANCE < RANGE) {
|
// if (DISTANCE < RANGE) {
|
||||||
// Matter.Body.setVelocity(mob[i], Matter.Vector.rotate(mob[i].velocity, 0.1))
|
// Matter.Body.setVelocity(mob[i], Matter.Vector.rotate(mob[i].velocity, 0.1))
|
||||||
// }
|
// }
|
||||||
|
// const DRAIN = 0.0002 //&& mech.fieldMeter > DRAIN
|
||||||
if (DISTANCE < RANGE) {
|
if (DISTANCE < RANGE) {
|
||||||
|
// mech.fieldMeter -= DRAIN + mech.fieldRegen;
|
||||||
const DEPTH = RANGE - DISTANCE
|
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 = Matter.Vector.mult(Matter.Vector.normalise(SUB), 0.000000001 * DEPTH * DEPTH * DEPTH * Math.sqrt(mob[i].mass))
|
||||||
mob[i].force.x += FORCE.x
|
mob[i].force.x += FORCE.x
|
||||||
@@ -894,7 +943,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "wave beam", //3
|
name: "wave beam", //3
|
||||||
description: "fire a stream of oscillating particles<br><strong style='opacity: 0.4;'>propagates through solids</strong>",
|
description: "fire a stream of oscillating particles<br>bullets <strong>propagate</strong> through solids",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 85,
|
ammoPack: 85,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -947,7 +996,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "super balls", //4
|
name: "super balls", //4
|
||||||
description: "fire 3 very <strong>bouncy</strong> balls",
|
description: "fire balls that <strong>bounce</strong> with no momentum loss",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 11,
|
ammoPack: 11,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -975,7 +1024,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "shotgun", //5
|
name: "shotgun", //5
|
||||||
description: "fire a <strong>burst</strong> of bullets<br><em>crouch to reduce recoil</em>",
|
description: "fire a <strong>burst</strong> of short range bullets<br><em>crouch to reduce recoil</em>",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 8,
|
ammoPack: 8,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -1003,7 +1052,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "fléchettes", //6
|
name: "fléchettes", //6
|
||||||
description: "fire accurate high speed needles",
|
description: "fire a flight of needles<br><strong>accurate</strong> at long range",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 25,
|
ammoPack: 25,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -1038,7 +1087,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "missiles", //7
|
name: "missiles", //7
|
||||||
description: "fire a missile that accelerates towards nearby targets<br><span class='color-e'>explodes</span> when near target",
|
description: "fire missiles that accelerate towards enemies<br><strong class='color-e'>explodes</strong> when near target",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 8,
|
ammoPack: 8,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -1143,7 +1192,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "flak", //8
|
name: "flak", //8
|
||||||
description: "fire a cluster of short range projectiles<br><span class='color-e'>explode</span> on contact or after half a second",
|
description: "fire a cluster of short range projectiles<br><strong class='color-e'>explode</strong> on contact or after half a second",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 20,
|
ammoPack: 20,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -1186,7 +1235,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "grenades", //9
|
name: "grenades", //9
|
||||||
description: "fire a projectile that <span class='color-e'>explodes</span> on contact or after one second",
|
description: "lob a single bouncy projectile<br><strong class='color-e'>explodes</strong> on contact or after one second",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 9,
|
ammoPack: 9,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -1214,7 +1263,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "vacuum bomb", //10
|
name: "vacuum bomb", //10
|
||||||
description: "fire a huge <strong>bomb</strong> that sucks before it <span class='color-e'>explodes</span><br>click left mouse <strong>again</strong> to detonate",
|
description: "fire a bomb that <strong>sucks</strong> before <strong class='color-e'>exploding</strong><br>click left mouse again to <strong>detonate</strong>",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 5,
|
ammoPack: 5,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -1323,7 +1372,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "ferro frag", //11
|
name: "ferro frag", //11
|
||||||
description: "fire a <strong>grenade</strong> that ejects <strong class='color-m'>magnetized</strong> nails<br>nails are <strong class='color-m'>attracted</strong> to enemy targets",
|
description: "fire a <strong>grenade</strong> that ejects magnetized nails<br>nails are <strong>attracted</strong> to enemies",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 8,
|
ammoPack: 8,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -1348,38 +1397,42 @@ const b = {
|
|||||||
//target nearby mobs
|
//target nearby mobs
|
||||||
const targets = []
|
const targets = []
|
||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
const sub = Matter.Vector.sub(this.position, mob[i].position);
|
if (mob[i].dropPowerUp) {
|
||||||
const dist = Matter.Vector.magnitude(sub);
|
const sub = Matter.Vector.sub(this.position, mob[i].position);
|
||||||
if (dist < 1400 &&
|
const dist = Matter.Vector.magnitude(sub);
|
||||||
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
if (dist < 1400 &&
|
||||||
Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
|
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
|
||||||
targets.push(mob[i].position)
|
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))
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i = 0; i < 14; i++) {
|
for (let i = 0; i < 14; i++) {
|
||||||
const SPEED = 35 + 20 * Math.random()
|
const speed = 55 + 10 * Math.random()
|
||||||
if (targets.length > 0) { // aim near a random target
|
if (targets.length > 0) { // aim near a random target
|
||||||
const SPREAD = 100
|
const index = Math.floor(Math.random() * targets.length)
|
||||||
const INDEX = Math.floor(Math.random() * targets.length)
|
const SPREAD = 150 / targets.length
|
||||||
const WHERE = {
|
const WHERE = {
|
||||||
x: targets[INDEX].x + SPREAD * (Math.random() - 0.5),
|
x: targets[index].x + SPREAD * (Math.random() - 0.5),
|
||||||
y: targets[INDEX].y + 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, Matter.Vector.mult(Matter.Vector.normalise(Matter.Vector.sub(WHERE, this.position)), speed))
|
||||||
} else { // aim in random direction
|
} else { // aim in random direction
|
||||||
const ANGLE = 2 * Math.PI * Math.random()
|
const ANGLE = 2 * Math.PI * Math.random()
|
||||||
needle(this.position, {
|
needle(this.position, {
|
||||||
x: SPEED * Math.cos(ANGLE),
|
x: speed * Math.cos(ANGLE),
|
||||||
y: SPEED * Math.sin(ANGLE)
|
y: speed * Math.sin(ANGLE)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function needle(pos, velocity) {
|
function needle(pos, velocity) {
|
||||||
const me = bullet.length;
|
const me = bullet.length;
|
||||||
bullet[me] = Bodies.rectangle(pos.x, pos.y, 23 * b.modBulletSize, 2 * b.modBulletSize, b.fireAttributes(Math.atan2(velocity.y, velocity.x)));
|
bullet[me] = Bodies.rectangle(pos.x, pos.y, 25 * b.modBulletSize, 2 * b.modBulletSize, b.fireAttributes(Math.atan2(velocity.y, velocity.x)));
|
||||||
Matter.Body.setVelocity(bullet[me], velocity);
|
Matter.Body.setVelocity(bullet[me], velocity);
|
||||||
World.add(engine.world, bullet[me]); //add bullet to world
|
World.add(engine.world, bullet[me]); //add bullet to world
|
||||||
bullet[me].endCycle = game.cycle + 60 + Math.floor(15 * Math.random());
|
bullet[me].endCycle = game.cycle + 60 + 15 * Math.random();
|
||||||
// bullet[me].dmg = 1.1+b.modExtraDmg;
|
// bullet[me].dmg = 1.1+b.modExtraDmg;
|
||||||
bullet[me].do = function () {};
|
bullet[me].do = function () {};
|
||||||
}
|
}
|
||||||
@@ -1390,7 +1443,7 @@ const b = {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: "spores", //12
|
name: "spores", //12
|
||||||
description: "release an orb that discharges <span class='color-s'>spores</span> after 2 seconds<br>seeks out targets<br>passes through blocks",
|
description: "fire orbs that discharge <strong class='color-s'>spores</strong><br><strong class='color-s'>spores</strong> seek out enemies",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 5,
|
ammoPack: 5,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -1491,9 +1544,10 @@ const b = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: "drones", //13
|
name: "drones", //13
|
||||||
description: "release <strong>drones</strong> that seek out targets for 16 seconds<br>follows mouse if no targets are found",
|
description: "fire <strong>drones</strong> that seek out enemies<br>follows mouse if no targets are found",
|
||||||
ammo: 0,
|
ammo: 0,
|
||||||
ammoPack: 20,
|
ammoPack: 20,
|
||||||
have: false,
|
have: false,
|
||||||
@@ -1664,7 +1718,7 @@ const b = {
|
|||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// name: "kinetic slugs", //1
|
// name: "kinetic slugs", //1
|
||||||
// description: "fire a large <strong>rod</strong> that does excessive physical <span class='color-d'>damage</span><br><em>high recoil</em>",
|
// description: "fire a large <strong>rod</strong> that does excessive physical <strong class='color-d'>damage</strong><br><em>high recoil</em>",
|
||||||
// ammo: 0,
|
// ammo: 0,
|
||||||
// ammoPack: 5,
|
// ammoPack: 5,
|
||||||
// have: false,
|
// have: false,
|
||||||
@@ -1686,7 +1740,7 @@ const b = {
|
|||||||
// player.force.x -= KNOCK * Math.cos(dir)
|
// player.force.x -= KNOCK * Math.cos(dir)
|
||||||
// player.force.y -= KNOCK * Math.sin(dir) * 0.3 //reduce knock back in vertical direction to stop super jumps
|
// player.force.y -= KNOCK * Math.sin(dir) * 0.3 //reduce knock back in vertical direction to stop super jumps
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// name: "triboelectricty", //14
|
// name: "triboelectricty", //14
|
||||||
// description: "release <strong>particles</strong> that quickly seek out targets",
|
// description: "release <strong>particles</strong> that quickly seek out targets",
|
||||||
// ammo: 0,
|
// ammo: 0,
|
||||||
@@ -1754,7 +1808,7 @@ const b = {
|
|||||||
// {
|
// {
|
||||||
// //draw a halo, since there will only be 1-3 balls
|
// //draw a halo, since there will only be 1-3 balls
|
||||||
// name: "junk-bots", //14
|
// name: "junk-bots", //14
|
||||||
// description: "release unreliable <strong>drones</strong> that defend the space around the player<br><strong>collisions</strong> may cause <span class='color-d'>malfunction</span>",
|
// description: "release unreliable <strong>drones</strong> that defend the space around the player<br><strong>collisions</strong> may cause <strong class='color-d'>malfunction</strong>",
|
||||||
// ammo: 0,
|
// ammo: 0,
|
||||||
// ammoPack: 15,
|
// ammoPack: 15,
|
||||||
// have: false,
|
// have: false,
|
||||||
|
|||||||
@@ -177,9 +177,10 @@ function mobCollisionChecks(event) {
|
|||||||
}
|
}
|
||||||
//mob + bullet collisions
|
//mob + bullet collisions
|
||||||
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
|
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
|
||||||
mob[k].foundPlayer();
|
|
||||||
// const dmg = b.dmgScale * (obj.dmg + 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 * Matter.Vector.magnitude(Matter.Vector.sub(mob[k].velocity, obj.velocity)));
|
||||||
const dmg = b.dmgScale * (obj.dmg + b.modExtraDmg + 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)))
|
||||||
|
if (b.modIsCrit && !mob[k].seePlayer.recall) dmg *= 6
|
||||||
|
mob[k].foundPlayer();
|
||||||
mob[k].damage(dmg);
|
mob[k].damage(dmg);
|
||||||
obj.onDmg(); //some bullets do actions when they hits things, like despawn
|
obj.onDmg(); //some bullets do actions when they hits things, like despawn
|
||||||
game.drawList.push({
|
game.drawList.push({
|
||||||
|
|||||||
@@ -454,7 +454,9 @@ const game = {
|
|||||||
game.startGame();
|
game.startGame();
|
||||||
};
|
};
|
||||||
document.getElementById("controls").style.display = "inline";
|
document.getElementById("controls").style.display = "inline";
|
||||||
document.getElementById("settings").style.display = "inline";
|
document.getElementById("build-button").style.display = "inline"
|
||||||
|
isShowingBuilds = false
|
||||||
|
// document.getElementById("settings").style.display = "inline";
|
||||||
document.getElementById("splash").style.display = "inline";
|
document.getElementById("splash").style.display = "inline";
|
||||||
document.getElementById("dmg").style.display = "none";
|
document.getElementById("dmg").style.display = "none";
|
||||||
document.getElementById("health-bg").style.display = "none";
|
document.getElementById("health-bg").style.display = "none";
|
||||||
@@ -464,8 +466,10 @@ const game = {
|
|||||||
then: null,
|
then: null,
|
||||||
startGame() {
|
startGame() {
|
||||||
game.onTitlePage = false;
|
game.onTitlePage = false;
|
||||||
|
document.body.style.overflow = "hidden"
|
||||||
|
document.getElementById("build-grid").style.display = "none"
|
||||||
document.getElementById("controls").style.display = "none";
|
document.getElementById("controls").style.display = "none";
|
||||||
document.getElementById("settings").style.display = "none";
|
document.getElementById("build-button").style.display = "none";
|
||||||
document.getElementById("splash").onclick = null; //removes the onclick effect so the function only runs once
|
document.getElementById("splash").onclick = null; //removes the onclick effect so the function only runs once
|
||||||
document.getElementById("splash").style.display = "none"; //hides the element that spawned the function
|
document.getElementById("splash").style.display = "none"; //hides the element that spawned the function
|
||||||
document.getElementById("dmg").style.display = "inline";
|
document.getElementById("dmg").style.display = "inline";
|
||||||
|
|||||||
64
js/index.js
64
js/index.js
@@ -2,6 +2,15 @@
|
|||||||
/* TODO: *******************************************
|
/* TODO: *******************************************
|
||||||
*****************************************************
|
*****************************************************
|
||||||
|
|
||||||
|
add builds with combinations of gun, field and mobs
|
||||||
|
use the pull down menu
|
||||||
|
|
||||||
|
dynamically generate html about fields, guns and mods
|
||||||
|
|
||||||
|
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
|
gun: like drones, but fast moving and short lived
|
||||||
dies after doing damage
|
dies after doing damage
|
||||||
|
|
||||||
@@ -12,31 +21,16 @@ gun: Spirit Bomb (singularity)
|
|||||||
sucked in stuff increase size
|
sucked in stuff increase size
|
||||||
uses energy
|
uses energy
|
||||||
|
|
||||||
left and right click mouse icons for text displays
|
|
||||||
|
|
||||||
mod: auto pick up guns, heals, ammo
|
mod: auto pick up guns, heals, ammo
|
||||||
use the same rule for drones
|
use the same rule for drones
|
||||||
maybe give some other bonus too?
|
maybe give some other bonus too?
|
||||||
|
|
||||||
mod: + move speed and jump height
|
|
||||||
will leg animations look strange?
|
|
||||||
that's OK for a mod
|
|
||||||
this could just slow the mobs down instead?
|
|
||||||
how?
|
|
||||||
|
|
||||||
rework junk bot
|
rework junk bot
|
||||||
it's behavior is too unpredictable
|
it's behavior is too unpredictable
|
||||||
range is unclear
|
range is unclear
|
||||||
having the bullets last long after doing dmg isn't fun
|
having the bullets last long after doing dmg isn't fun
|
||||||
we want a fun gun that acts like a melee weapon
|
we want a fun gun that acts like a melee weapon
|
||||||
|
|
||||||
mouse can get suck as clicked if the user clicks off the window
|
|
||||||
can lead to gun lock up until player pressed mouse again
|
|
||||||
should I really need to fix this?
|
|
||||||
|
|
||||||
diegetic field meter
|
|
||||||
show as the player head filling with teal color
|
|
||||||
|
|
||||||
atmosphere levels
|
atmosphere levels
|
||||||
large rotating fan that the player has to move through
|
large rotating fan that the player has to move through
|
||||||
give the user a rest, between combat
|
give the user a rest, between combat
|
||||||
@@ -55,17 +49,10 @@ Boss levels
|
|||||||
|
|
||||||
add a key that player picks up and needs to set on the exit door to open it
|
add a key that player picks up and needs to set on the exit door to open it
|
||||||
|
|
||||||
add modular difficulty settings
|
|
||||||
take reduced dmg
|
|
||||||
slower mob look / CD
|
|
||||||
more drops
|
|
||||||
fewer mobs
|
|
||||||
make a new var to scale number of mobs and stop using levels cleared var
|
|
||||||
|
|
||||||
make power ups keep moving to player if the pickup field is turned off before they get picked up
|
make power ups keep moving to player if the pickup field is turned off before they get picked up
|
||||||
not sure how to do this without adding a constant check
|
not sure how to do this without adding a constant check
|
||||||
|
|
||||||
levels spawn by having the map aspects randomly fly into place
|
animate new level spawn by having the map aspects randomly fly into place
|
||||||
|
|
||||||
new map with repeating endlessness
|
new map with repeating endlessness
|
||||||
get ideas from Manifold Garden game
|
get ideas from Manifold Garden game
|
||||||
@@ -128,6 +115,37 @@ map: 0x000001 0x111111
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//build build grid display
|
||||||
|
let isShowingBuilds = false
|
||||||
|
document.getElementById("build-button").addEventListener("click", () => {
|
||||||
|
const el = document.getElementById("build-grid")
|
||||||
|
if (isShowingBuilds) {
|
||||||
|
el.style.display = "none"
|
||||||
|
isShowingBuilds = false
|
||||||
|
document.body.style.overflow = "hidden"
|
||||||
|
document.getElementById("controls").style.display = 'inline'
|
||||||
|
} else {
|
||||||
|
let text = ""
|
||||||
|
for (let i = 0, len = mech.fieldUpgrades.length; i < len; i++) {
|
||||||
|
text += `<div class="build-grid-module "><div class="circle-grid field"></div> <strong style='font-size:1.3em;'>${mech.fieldUpgrades[i].name}</strong><br> ${mech.fieldUpgrades[i].description}</div>`
|
||||||
|
}
|
||||||
|
for (let i = 0, len = b.guns.length; i < len; i++) {
|
||||||
|
text += `<div class="build-grid-module "><div class="circle-grid gun"></div> <strong style='font-size:1.3em;'>${b.guns[i].name}</strong><br> ${b.guns[i].description}</div>`
|
||||||
|
}
|
||||||
|
for (let i = 0, len = b.mods.length; i < len; i++) {
|
||||||
|
text += `<div class="build-grid-module "><div class="circle-grid mod"></div> <strong style='font-size:1.3em;'>${b.mods[i].name}</strong><br> ${b.mods[i].description}</div>`
|
||||||
|
}
|
||||||
|
el.innerHTML = text
|
||||||
|
el.style.display = "grid"
|
||||||
|
isShowingBuilds = true
|
||||||
|
document.body.style.overflowY = "scroll";
|
||||||
|
document.body.style.overflowX = "hidden";
|
||||||
|
document.getElementById("controls").style.display = 'none'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//set up canvas
|
//set up canvas
|
||||||
var canvas = document.getElementById("canvas");
|
var canvas = document.getElementById("canvas");
|
||||||
//using "const" causes problems in safari when an ID shares the same name.
|
//using "const" causes problems in safari when an ID shares the same name.
|
||||||
|
|||||||
76
js/level.js
76
js/level.js
@@ -14,9 +14,10 @@ const level = {
|
|||||||
start() {
|
start() {
|
||||||
if (level.levelsCleared === 0) {
|
if (level.levelsCleared === 0) {
|
||||||
// game.difficulty = 6; //for testing to simulate possible mobs spawns
|
// game.difficulty = 6; //for testing to simulate possible mobs spawns
|
||||||
// b.giveGuns(14)
|
// level.startBuildRun(6)
|
||||||
|
// b.giveGuns(11)
|
||||||
// mech.fieldUpgrades[2].effect();
|
// mech.fieldUpgrades[2].effect();
|
||||||
// b.giveMod(15)
|
// b.giveMod(20)
|
||||||
// spawn.pickList = ["ghoster", "ghoster"]
|
// spawn.pickList = ["ghoster", "ghoster"]
|
||||||
|
|
||||||
this.intro(); //starting level
|
this.intro(); //starting level
|
||||||
@@ -36,6 +37,77 @@ const level = {
|
|||||||
level.addToWorld(); //add bodies to game engine
|
level.addToWorld(); //add bodies to game engine
|
||||||
game.draw.setPaths();
|
game.draw.setPaths();
|
||||||
},
|
},
|
||||||
|
isBuildRun: false,
|
||||||
|
builds: [ // choose 5 total: guns, mods, and field
|
||||||
|
() => {
|
||||||
|
mech.fieldUpgrades[2].effect();
|
||||||
|
b.giveMod(6)
|
||||||
|
b.giveMod(8)
|
||||||
|
b.giveMod(9)
|
||||||
|
b.giveMod(15)
|
||||||
|
game.replaceTextLog = true;
|
||||||
|
game.makeTextLog("<h2>build: melee</h2>", 300);
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
b.giveGuns(13)
|
||||||
|
mech.fieldUpgrades[5].effect();
|
||||||
|
b.giveMod(8)
|
||||||
|
b.giveMod(3)
|
||||||
|
b.giveMod(11)
|
||||||
|
game.replaceTextLog = true;
|
||||||
|
game.makeTextLog("<h2>build: drones</h2>", 300);
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
b.giveGuns(8)
|
||||||
|
mech.fieldUpgrades[4].effect();
|
||||||
|
b.giveMod(4)
|
||||||
|
b.giveMod(5)
|
||||||
|
b.giveMod(16)
|
||||||
|
game.replaceTextLog = true;
|
||||||
|
game.makeTextLog("<h2>build: flak</h2>", 300);
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
b.giveMod(6)
|
||||||
|
b.giveMod(7)
|
||||||
|
b.giveMod(12)
|
||||||
|
b.giveMod(13)
|
||||||
|
b.giveMod(14)
|
||||||
|
game.replaceTextLog = true;
|
||||||
|
game.makeTextLog("<h2>build: block thrower</h2>", 300);
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
b.giveGuns(5)
|
||||||
|
mech.fieldUpgrades[6].effect();
|
||||||
|
b.giveMod(1)
|
||||||
|
b.giveMod(8)
|
||||||
|
b.giveMod(15)
|
||||||
|
game.replaceTextLog = true;
|
||||||
|
game.makeTextLog("<h2>build: stealth shotgun</h2>", 300);
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
b.giveGuns(2)
|
||||||
|
mech.fieldUpgrades[1].effect();
|
||||||
|
b.giveMod(8)
|
||||||
|
b.giveMod(9)
|
||||||
|
b.giveMod(11)
|
||||||
|
game.replaceTextLog = true;
|
||||||
|
game.makeTextLog("<h2>build: time out</h2>", 300);
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
b.giveGuns(0)
|
||||||
|
mech.fieldUpgrades[5].effect();
|
||||||
|
b.giveMod(7)
|
||||||
|
b.giveMod(5)
|
||||||
|
b.giveMod(18)
|
||||||
|
game.replaceTextLog = true;
|
||||||
|
game.makeTextLog("<h2>build: laser tag</h2>", 300);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
startBuildRun(build) {
|
||||||
|
level.builds[build]()
|
||||||
|
game.difficulty = 6;
|
||||||
|
level.isBuildRun = true
|
||||||
|
},
|
||||||
difficultyIncrease(num = 1) {
|
difficultyIncrease(num = 1) {
|
||||||
for (let i = 0; i < num; i++) {
|
for (let i = 0; i < num; i++) {
|
||||||
game.dmgScale += 0.2; //damage done by mobs increases each level
|
game.dmgScale += 0.2; //damage done by mobs increases each level
|
||||||
|
|||||||
@@ -898,6 +898,8 @@ const mobs = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
damage(dmg) {
|
damage(dmg) {
|
||||||
|
if (b.isModLowHealthDmg) dmg *= (3 / (2 + mech.health)) //up to 50% dmg at zero player health
|
||||||
|
if (b.isModFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(1000, Math.min(3500, this.distanceToPlayer())) - 1000) * 0.01 //up to 50% dmg at max range of 3500
|
||||||
this.health -= dmg / Math.sqrt(this.mass);
|
this.health -= dmg / Math.sqrt(this.mass);
|
||||||
//this.fill = this.color + this.health + ')';
|
//this.fill = this.color + this.health + ')';
|
||||||
if (this.health < 0.1) this.death();
|
if (this.health < 0.1) this.death();
|
||||||
@@ -913,7 +915,7 @@ const mobs = {
|
|||||||
},
|
},
|
||||||
onDeath() {
|
onDeath() {
|
||||||
// a placeholder for custom effects on mob death
|
// a placeholder for custom effects on mob death
|
||||||
//to use declare custom method in mob spawn
|
// to use declare custom method in mob spawn
|
||||||
},
|
},
|
||||||
leaveBody: true,
|
leaveBody: true,
|
||||||
dropPowerUp: true,
|
dropPowerUp: true,
|
||||||
|
|||||||
304
js/player.js
304
js/player.js
@@ -68,15 +68,6 @@ const mech = {
|
|||||||
FxNotHolding: 0.015,
|
FxNotHolding: 0.015,
|
||||||
Fx: 0.015, //run Force on ground //this is reset in b.setModDefaults()
|
Fx: 0.015, //run Force on ground //this is reset in b.setModDefaults()
|
||||||
FxAir: 0.015, //run Force in Air
|
FxAir: 0.015, //run Force in Air
|
||||||
definePlayerMass(mass = mech.defaultMass) {
|
|
||||||
Matter.Body.setMass(player, mass);
|
|
||||||
//reduce air and ground move forces
|
|
||||||
this.Fx = 0.075 / mass * b.modSquirrelFx
|
|
||||||
this.FxAir = 0.375 / mass / mass
|
|
||||||
//make player stand a bit lower when holding heavy masses
|
|
||||||
this.yOffWhen.stand = Math.max(this.yOffWhen.crouch, Math.min(49, 49 - (mass - 5) * 6))
|
|
||||||
if (this.onGround && !this.crouch) this.yOffGoal = this.yOffWhen.stand;
|
|
||||||
},
|
|
||||||
yOff: 70,
|
yOff: 70,
|
||||||
yOffGoal: 70,
|
yOffGoal: 70,
|
||||||
onGround: false, //checks if on ground or in air
|
onGround: false, //checks if on ground or in air
|
||||||
@@ -415,11 +406,6 @@ const mech = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
health: 0,
|
health: 0,
|
||||||
// regen() {
|
|
||||||
// if (this.health < 1 && mech.cycle % 15 === 0) {
|
|
||||||
// this.addHealth(0.01);
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
drawHealth() {
|
drawHealth() {
|
||||||
if (this.health < 1) {
|
if (this.health < 1) {
|
||||||
ctx.fillStyle = "rgba(100, 100, 100, 0.5)";
|
ctx.fillStyle = "rgba(100, 100, 100, 0.5)";
|
||||||
@@ -450,6 +436,12 @@ const mech = {
|
|||||||
},
|
},
|
||||||
defaultFPSCycle: 0, //tracks when to return to normal fps
|
defaultFPSCycle: 0, //tracks when to return to normal fps
|
||||||
damage(dmg) {
|
damage(dmg) {
|
||||||
|
if (b.isModMonogamy && b.inventory[0] === b.activeGun) {
|
||||||
|
for (let i = 0, len = b.inventory.length; i < len; i++) {
|
||||||
|
dmg *= 0.93
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(dmg, "after")
|
||||||
this.health -= dmg;
|
this.health -= dmg;
|
||||||
if (this.health < 0) {
|
if (this.health < 0) {
|
||||||
this.health = 0;
|
this.health = 0;
|
||||||
@@ -639,7 +631,6 @@ const mech = {
|
|||||||
throwChargeRate: 0,
|
throwChargeRate: 0,
|
||||||
throwChargeMax: 0,
|
throwChargeMax: 0,
|
||||||
fieldFireCD: 0,
|
fieldFireCD: 0,
|
||||||
fieldDamage: 0,
|
|
||||||
fieldShieldingScale: 0,
|
fieldShieldingScale: 0,
|
||||||
grabRange: 0,
|
grabRange: 0,
|
||||||
fieldArc: 0,
|
fieldArc: 0,
|
||||||
@@ -656,7 +647,6 @@ const mech = {
|
|||||||
player.collisionFilter.mask = 0x010011 //0x010011 is normal
|
player.collisionFilter.mask = 0x010011 //0x010011 is normal
|
||||||
this.holdingMassScale = 0.5;
|
this.holdingMassScale = 0.5;
|
||||||
this.fieldFireCD = 15;
|
this.fieldFireCD = 15;
|
||||||
this.fieldDamage = 0; // a value of 1.0 kills a small mob in 2-3 hits on level 1
|
|
||||||
this.fieldShieldingScale = 1; //scale energy loss after collision with mob
|
this.fieldShieldingScale = 1; //scale energy loss after collision with mob
|
||||||
this.grabRange = 175;
|
this.grabRange = 175;
|
||||||
this.fieldArc = 0.2; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
this.fieldArc = 0.2; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||||
@@ -701,6 +691,15 @@ const mech = {
|
|||||||
this.throwCharge = 0;
|
this.throwCharge = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
definePlayerMass(mass = mech.defaultMass) {
|
||||||
|
Matter.Body.setMass(player, mass);
|
||||||
|
//reduce air and ground move forces
|
||||||
|
this.Fx = 0.075 / mass * b.modSquirrelFx
|
||||||
|
this.FxAir = 0.375 / mass / mass
|
||||||
|
//make player stand a bit lower when holding heavy masses
|
||||||
|
this.yOffWhen.stand = Math.max(this.yOffWhen.crouch, Math.min(49, 49 - (mass - 5) * 6))
|
||||||
|
if (this.onGround && !this.crouch) this.yOffGoal = this.yOffWhen.stand;
|
||||||
|
},
|
||||||
drawHold(target, stroke = true) {
|
drawHold(target, stroke = true) {
|
||||||
const eye = 15;
|
const eye = 15;
|
||||||
const len = target.vertices.length - 1;
|
const len = target.vertices.length - 1;
|
||||||
@@ -869,55 +868,70 @@ const mech = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pushMobs() { // push all mobs in range and in direction looking
|
pushMass(who) {
|
||||||
|
const fieldBlockCost = Math.max(0.02, who.mass * 0.012) //0.012
|
||||||
|
if (this.fieldMeter > fieldBlockCost) {
|
||||||
|
this.fieldMeter -= fieldBlockCost * this.fieldShieldingScale;
|
||||||
|
if (this.fieldMeter < 0) this.fieldMeter = 0;
|
||||||
|
this.drawHold(who);
|
||||||
|
//knock backs
|
||||||
|
const angle = Math.atan2(player.position.y - who.position.y, player.position.x - who.position.x);
|
||||||
|
const mass = Math.min(Math.sqrt(who.mass), 4);
|
||||||
|
Matter.Body.setVelocity(who, {
|
||||||
|
x: player.velocity.x - (15 * Math.cos(angle)) / mass,
|
||||||
|
y: player.velocity.y - (15 * Math.sin(angle)) / mass
|
||||||
|
});
|
||||||
|
Matter.Body.setVelocity(player, {
|
||||||
|
x: player.velocity.x + 5 * Math.cos(angle) * mass,
|
||||||
|
y: player.velocity.y + 5 * Math.sin(angle) * mass
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pushMobsFacing() { // find mobs in range and in direction looking
|
||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
if (this.lookingAt(mob[i]) && Matter.Vector.magnitude(Matter.Vector.sub(mob[i].position, this.pos)) < this.grabRange && Matter.Query.ray(map, mob[i].position, this.pos).length === 0) {
|
if (
|
||||||
const fieldBlockCost = Math.max(0.02, mob[i].mass * 0.012) //0.012
|
Matter.Vector.magnitude(Matter.Vector.sub(mob[i].position, this.pos)) < this.grabRange &&
|
||||||
if (this.fieldMeter > fieldBlockCost) {
|
this.lookingAt(mob[i]) &&
|
||||||
this.fieldMeter -= fieldBlockCost * this.fieldShieldingScale;
|
Matter.Query.ray(map, mob[i].position, this.pos).length === 0
|
||||||
if (this.fieldMeter < 0) this.fieldMeter = 0;
|
) {
|
||||||
if (this.fieldDamage) mob[i].damage(b.dmgScale * this.fieldDamage);
|
mob[i].locatePlayer();
|
||||||
mob[i].locatePlayer();
|
mech.pushMass(mob[i]);
|
||||||
this.drawHold(mob[i]);
|
|
||||||
//mob and player knock back
|
|
||||||
const angle = Math.atan2(player.position.y - mob[i].position.y, player.position.x - mob[i].position.x);
|
|
||||||
const mass = Math.min(Math.sqrt(mob[i].mass), 4);
|
|
||||||
Matter.Body.setVelocity(mob[i], {
|
|
||||||
x: player.velocity.x - (15 * Math.cos(angle)) / mass,
|
|
||||||
y: player.velocity.y - (15 * Math.sin(angle)) / mass
|
|
||||||
});
|
|
||||||
Matter.Body.setVelocity(player, {
|
|
||||||
x: player.velocity.x + 5 * Math.cos(angle) * mass,
|
|
||||||
y: player.velocity.y + 5 * Math.sin(angle) * mass
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pushMobs360(range = this.grabRange * 0.75) { // push all mobs in range in any direction
|
pushMobs360(range = this.grabRange * 0.75) { // find mobs in range in any direction
|
||||||
for (let i = 0, len = mob.length; i < len; ++i) {
|
for (let i = 0, len = mob.length; i < len; ++i) {
|
||||||
if (Matter.Vector.magnitude(Matter.Vector.sub(mob[i].position, this.pos)) < range && Matter.Query.ray(map, mob[i].position, this.pos).length === 0) {
|
if (
|
||||||
const fieldBlockCost = Math.max(0.02, mob[i].mass * 0.012)
|
Matter.Vector.magnitude(Matter.Vector.sub(mob[i].position, this.pos)) < range &&
|
||||||
if (this.fieldMeter > fieldBlockCost) {
|
Matter.Query.ray(map, mob[i].position, this.pos).length === 0
|
||||||
this.fieldMeter -= fieldBlockCost * this.fieldShieldingScale;
|
) {
|
||||||
if (this.fieldMeter < 0) this.fieldMeter = 0
|
mob[i].locatePlayer();
|
||||||
|
mech.pushMass(mob[i]);
|
||||||
if (this.fieldDamage) mob[i].damage(b.dmgScale * this.fieldDamage);
|
}
|
||||||
mob[i].locatePlayer();
|
}
|
||||||
this.drawHold(mob[i]);
|
},
|
||||||
//mob and player knock back
|
pushBodyFacing() { // push all body in range and in direction looking
|
||||||
const angle = Math.atan2(player.position.y - mob[i].position.y, player.position.x - mob[i].position.x);
|
for (let i = 0, len = body.length; i < len; ++i) {
|
||||||
const mass = Math.min(Math.sqrt(mob[i].mass), 4);
|
if (
|
||||||
// console.log(mob[i].mass, Math.sqrt(mob[i].mass), mass)
|
body[i].speed > 12 && body[i].mass > 2 &&
|
||||||
Matter.Body.setVelocity(mob[i], {
|
Matter.Vector.magnitude(Matter.Vector.sub(body[i].position, this.pos)) < this.grabRange &&
|
||||||
x: player.velocity.x - (15 * Math.cos(angle)) / mass,
|
this.lookingAt(body[i]) &&
|
||||||
y: player.velocity.y - (15 * Math.sin(angle)) / mass
|
Matter.Query.ray(map, body[i].position, this.pos).length === 0
|
||||||
});
|
) {
|
||||||
Matter.Body.setVelocity(player, {
|
mech.pushMass(body[i]);
|
||||||
x: player.velocity.x + 5 * Math.cos(angle) * mass,
|
}
|
||||||
y: player.velocity.y + 5 * Math.sin(angle) * mass
|
}
|
||||||
});
|
},
|
||||||
}
|
pushBody360(range = this.grabRange * 0.75) { // push all body in range and in direction looking
|
||||||
|
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 &&
|
||||||
|
this.lookingAt(body[i]) &&
|
||||||
|
Matter.Query.ray(map, body[i].position, this.pos).length === 0 &&
|
||||||
|
body[i].collisionFilter.category === 0x010000
|
||||||
|
) {
|
||||||
|
mech.pushMass(body[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1017,12 +1031,12 @@ const mech = {
|
|||||||
},
|
},
|
||||||
fieldUpgrades: [{
|
fieldUpgrades: [{
|
||||||
name: "field emitter",
|
name: "field emitter",
|
||||||
description: "<strong class='color-f'>shields</strong> you from <span class='color-d'>damage</span><br>lets you <strong>pick up</strong> and throw objects",
|
description: "use <strong class='color-f'>energy</strong> to <strong>shield</strong> yourself from <strong class='color-d'>damage</strong><br>lets you <strong>pick up</strong> and <strong>throw</strong> objects",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
mech.fieldMode = 0;
|
mech.fieldMode = 0;
|
||||||
mech.fieldText();
|
mech.fieldText();
|
||||||
game.replaceTextLog = true; //allow text over write
|
game.replaceTextLog = true; //allow text over write
|
||||||
// game.makeTextLog("<strong style='font-size:30px;'></strong><br> <span class='faded'>(right click or space bar)</span><p></p>", 1200);
|
// game.makeTextLog("<strong style='font-size:30px;'></strong><br> <strong class='faded'>(right click or space bar)</strong><p></p>", 1200);
|
||||||
mech.setHoldDefaults();
|
mech.setHoldDefaults();
|
||||||
mech.hold = function () {
|
mech.hold = function () {
|
||||||
if (mech.isHolding) {
|
if (mech.isHolding) {
|
||||||
@@ -1032,7 +1046,8 @@ const mech = {
|
|||||||
} else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0.1)) { //not hold but field button is pressed
|
} else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0.1)) { //not hold but field button is pressed
|
||||||
mech.drawField();
|
mech.drawField();
|
||||||
mech.grabPowerUp();
|
mech.grabPowerUp();
|
||||||
mech.pushMobs();
|
mech.pushMobsFacing();
|
||||||
|
mech.pushBodyFacing();
|
||||||
mech.lookForPickUp();
|
mech.lookForPickUp();
|
||||||
} else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
|
} else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
|
||||||
mech.pickUp();
|
mech.pickUp();
|
||||||
@@ -1045,7 +1060,7 @@ const mech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "time dilation field",
|
name: "time dilation field",
|
||||||
description: "<strong style='letter-spacing: 3px;'>stop time</strong> while field is active<br> <em>can fire while field is active</em>",
|
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br><em>can fire bullets while field is active</em>",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
mech.fieldMode = 1;
|
mech.fieldMode = 1;
|
||||||
mech.fieldText();
|
mech.fieldText();
|
||||||
@@ -1119,14 +1134,14 @@ const mech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "plasma torch",
|
name: "plasma torch",
|
||||||
description: "field emits a beam of destructive <strong style='color:#d0d;'>ionized gas</strong><br><span style='color:#a00;'>decreased</span> <strong class='color-f'>shield</strong> range and efficiency",
|
description: "use <strong class='color-f'>energy</strong> to emit <strong class='color-d'>damaging</strong> beam<br><strong>decreased</strong> <strong>shield</strong> range and efficiency",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
mech.fieldMode = 2;
|
mech.fieldMode = 2;
|
||||||
mech.fieldText();
|
mech.fieldText();
|
||||||
mech.setHoldDefaults();
|
mech.setHoldDefaults();
|
||||||
// mech.fieldShieldingScale = 2;
|
// mech.fieldShieldingScale = 2;
|
||||||
// mech.grabRange = 125;
|
// mech.grabRange = 125;
|
||||||
mech.fieldArc = 0.05 //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
mech.fieldArc = 0.1 //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||||
mech.calculateFieldThreshold(); //run after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
mech.calculateFieldThreshold(); //run after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||||
mech.hold = function () {
|
mech.hold = function () {
|
||||||
if (mech.isHolding) {
|
if (mech.isHolding) {
|
||||||
@@ -1269,7 +1284,8 @@ const mech = {
|
|||||||
ctx.lineWidth = 2 * Math.random();
|
ctx.lineWidth = 2 * Math.random();
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
|
||||||
mech.pushMobs360(100);
|
mech.pushMobs360(110);
|
||||||
|
// mech.pushBody360(100); //disabled because doesn't work at short range
|
||||||
mech.grabPowerUp();
|
mech.grabPowerUp();
|
||||||
mech.lookForPickUp();
|
mech.lookForPickUp();
|
||||||
} else {
|
} else {
|
||||||
@@ -1286,7 +1302,7 @@ const mech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "negative mass field",
|
name: "negative mass field",
|
||||||
description: "field nullifies <strong style='letter-spacing: 15px;'>gravity</strong><br><em>can fire while field is active</em>",
|
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 10px;'>gravity</strong><br><em>can fire bullets while active</em>",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
mech.fieldMode = 3;
|
mech.fieldMode = 3;
|
||||||
mech.fieldText();
|
mech.fieldText();
|
||||||
@@ -1302,6 +1318,7 @@ const mech = {
|
|||||||
const DRAIN = 0.0004
|
const DRAIN = 0.0004
|
||||||
if (mech.fieldMeter > DRAIN) {
|
if (mech.fieldMeter > DRAIN) {
|
||||||
mech.pushMobs360(170);
|
mech.pushMobs360(170);
|
||||||
|
mech.pushBody360(180);
|
||||||
mech.grabPowerUp();
|
mech.grabPowerUp();
|
||||||
mech.lookForPickUp(170);
|
mech.lookForPickUp(170);
|
||||||
//look for nearby objects to make zero-g
|
//look for nearby objects to make zero-g
|
||||||
@@ -1373,7 +1390,7 @@ const mech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "standing wave harmonics",
|
name: "standing wave harmonics",
|
||||||
description: "you are surrounded by oscillating <strong class='color-f'>shields</strong><br> <span style='color:#a00;'>decreased</span> field regeneration",
|
description: "oscillating <strong>shields</strong> surround you <strong>constantly</strong><br> <strong>decreased</strong> <strong class='color-f'>energy</strong> regeneration",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
mech.fieldMode = 4;
|
mech.fieldMode = 4;
|
||||||
mech.fieldText();
|
mech.fieldText();
|
||||||
@@ -1409,6 +1426,7 @@ const mech = {
|
|||||||
ctx.arc(mech.pos.x, mech.pos.y, grabRange3, 0, 2 * Math.PI);
|
ctx.arc(mech.pos.x, mech.pos.y, grabRange3, 0, 2 * Math.PI);
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
mech.pushMobs360(netGrabRange);
|
mech.pushMobs360(netGrabRange);
|
||||||
|
mech.pushBody360(netGrabRange);
|
||||||
}
|
}
|
||||||
mech.drawFieldMeter()
|
mech.drawFieldMeter()
|
||||||
}
|
}
|
||||||
@@ -1416,16 +1434,16 @@ const mech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nano-scale manufacturing",
|
name: "nano-scale manufacturing",
|
||||||
description: "excess field <span class='color-f'>energy</span> used to build <strong class='color-b'>drones</strong><br> increased <span class='color-f'>energy</span> regeneration",
|
description: "excess <strong class='color-f'>energy</strong> used to build <strong>drones</strong><br><strong>3x</strong> <strong class='color-f'>energy</strong> regeneration",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
let gunIndex = 13 //Math.random() < 0.5 ? 13 : 14
|
let gunIndex = 13 //Math.random() < 0.5 ? 13 : 14
|
||||||
mech.fieldMode = 5;
|
mech.fieldMode = 5;
|
||||||
mech.fieldText();
|
mech.fieldText();
|
||||||
mech.setHoldDefaults();
|
mech.setHoldDefaults();
|
||||||
mech.fieldRegen *= 3.5;
|
mech.fieldRegen *= 3;
|
||||||
mech.hold = function () {
|
mech.hold = function () {
|
||||||
if (mech.fieldMeter === 1) {
|
if (mech.fieldMeter === 1) {
|
||||||
mech.fieldMeter -= 0.5;
|
mech.fieldMeter -= 0.43;
|
||||||
b.guns[gunIndex].fire() //spawn drone
|
b.guns[gunIndex].fire() //spawn drone
|
||||||
}
|
}
|
||||||
if (mech.isHolding) {
|
if (mech.isHolding) {
|
||||||
@@ -1433,7 +1451,8 @@ const mech = {
|
|||||||
mech.holding();
|
mech.holding();
|
||||||
mech.throw();
|
mech.throw();
|
||||||
} else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0.1)) { //not hold but field button is pressed
|
} else if ((keys[32] || game.mouseDownRight && mech.fieldMeter > 0.1)) { //not hold but field button is pressed
|
||||||
mech.pushMobs();
|
mech.pushMobsFacing();
|
||||||
|
mech.pushBodyFacing();
|
||||||
mech.drawField();
|
mech.drawField();
|
||||||
mech.grabPowerUp();
|
mech.grabPowerUp();
|
||||||
mech.lookForPickUp();
|
mech.lookForPickUp();
|
||||||
@@ -1448,7 +1467,7 @@ const mech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "phase decoherence field",
|
name: "phase decoherence field",
|
||||||
description: "<strong>intangible</strong> while field is active<br><em style='opacity: 0.6;'>can't see or be seen outside field</em>",
|
description: "use <strong class='color-f'>energy</strong> to to become <strong>intangible</strong><br><em style='opacity: 0.6;'>can't see or be seen outside field</em>",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
mech.fieldMode = 6;
|
mech.fieldMode = 6;
|
||||||
mech.fieldText();
|
mech.fieldText();
|
||||||
@@ -1493,142 +1512,5 @@ const mech = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// {
|
|
||||||
// name: "electrostatic field",
|
|
||||||
// description: "field does <strong class='color-d'>damage</strong> on contact<br> increased <span class='color-f'>field</span> regeneration",
|
|
||||||
// effect: () => {
|
|
||||||
// mech.fieldMode = 2;
|
|
||||||
// mech.fieldText();
|
|
||||||
// mech.setHoldDefaults();
|
|
||||||
// mech.grabRange = 225;
|
|
||||||
// mech.fieldShieldingScale = 2.5;
|
|
||||||
// mech.fieldRegen *= 2;
|
|
||||||
// mech.fieldDamage = 4; //passive field does extra damage
|
|
||||||
// // mech.fieldArc = 0.11
|
|
||||||
// // mech.calculateFieldThreshold(); //run after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
|
||||||
// mech.hold = function () {
|
|
||||||
// if (mech.isHolding) {
|
|
||||||
// mech.drawHold(mech.holdingTarget);
|
|
||||||
// mech.holding();
|
|
||||||
// mech.throw();
|
|
||||||
// } else if ((keys[32] || game.mouseDownRight) && mech.fieldMeter > 0.15) { //not hold but field button is pressed
|
|
||||||
// //draw electricity
|
|
||||||
// const Dx = Math.cos(mech.angle);
|
|
||||||
// const Dy = Math.sin(mech.angle);
|
|
||||||
// let x = mech.pos.x + 20 * Dx;
|
|
||||||
// let y = mech.pos.y + 20 * Dy;
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.moveTo(x, y);
|
|
||||||
// for (let i = 0; i < 8; i++) {
|
|
||||||
// x += 18 * (Dx + 2 * (Math.random() - 0.5))
|
|
||||||
// y += 18 * (Dy + 2 * (Math.random() - 0.5))
|
|
||||||
// ctx.lineTo(x, y);
|
|
||||||
// }
|
|
||||||
// ctx.lineWidth = 1 //0.5 + 2 * Math.random();
|
|
||||||
// ctx.strokeStyle = `rgba(100,20,50,${0.5+0.5*Math.random()})`;
|
|
||||||
// ctx.stroke();
|
|
||||||
|
|
||||||
// //draw field
|
|
||||||
// const range = 170;
|
|
||||||
// const arc = Math.PI * 0.11
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.arc(mech.pos.x, mech.pos.y, range, mech.angle - arc, mech.angle + arc, false);
|
|
||||||
// ctx.lineTo(mech.pos.x + 13 * Math.cos(mech.angle), mech.pos.y + 13 * Math.sin(mech.angle));
|
|
||||||
// if (mech.holdingTarget) {
|
|
||||||
// ctx.fillStyle = "rgba(255,50,150," + (0.01 + mech.fieldMeter * (0.1 + 0.1 * Math.random())) + ")";
|
|
||||||
// } else {
|
|
||||||
// ctx.fillStyle = "rgba(255,50,150," + (0.02 + mech.fieldMeter * (0.18 + 0.18 * Math.random())) + ")";
|
|
||||||
// }
|
|
||||||
// // ctx.fillStyle = "rgba(110,170,200," + (0.02 + mech.fieldMeter * (0.08 + 0.1 * Math.random())) + ")";
|
|
||||||
// // ctx.fillStyle = "rgba(110,170,200," + (0.06 + mech.fieldMeter * (0.1 + 0.18 * Math.random())) + ")";
|
|
||||||
// ctx.fill();
|
|
||||||
|
|
||||||
// //draw random lines in field for cool effect
|
|
||||||
// // eye = 15;
|
|
||||||
// // ctx.beginPath();
|
|
||||||
// // ctx.moveTo(mech.pos.x + eye * Math.cos(mech.angle), mech.pos.y + eye * Math.sin(mech.angle));
|
|
||||||
// // const offAngle = mech.angle + 2 * Math.PI * mech.fieldArc * (Math.random() - 0.5);
|
|
||||||
// // ctx.lineTo(mech.pos.x + range * Math.cos(offAngle), mech.pos.y + range * Math.sin(offAngle));
|
|
||||||
// // ctx.strokeStyle = "rgba(100,20,50,0.2)";
|
|
||||||
// // ctx.stroke();
|
|
||||||
|
|
||||||
// mech.grabPowerUp();
|
|
||||||
// mech.pushMobs();
|
|
||||||
// mech.lookForPickUp();
|
|
||||||
// } else if (mech.holdingTarget && mech.fireCDcycle < 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)
|
|
||||||
// }
|
|
||||||
// mech.drawFieldMeter()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
|
|
||||||
// () => {
|
|
||||||
// mech.fieldMode = 7;
|
|
||||||
// game.makeTextLog("<strong style='font-size:30px;'>Thermal Radiation Field</strong><br> <span class='faded'>(right click or space bar)</span> <p>field grows while active<br>damages all targets within range, <span style='color:#a00;'>including player</span><br> <span style='color:#a00;'>decreased</span> field shielding efficiency</p>", 1200);
|
|
||||||
// mech.setHoldDefaults();
|
|
||||||
// mech.fieldShieldingScale = 10;
|
|
||||||
// mech.rangeSmoothing = 0
|
|
||||||
// mech.hold = function () {
|
|
||||||
// if (mech.isHolding) {
|
|
||||||
// mech.drawHold(mech.holdingTarget);
|
|
||||||
// mech.holding();
|
|
||||||
// mech.throw();
|
|
||||||
// } else if ((keys[32] || game.mouseDownRight && mech.fieldCDcycle < mech.cycle)) { //not hold but field button is pressed
|
|
||||||
// mech.grabPowerUp();
|
|
||||||
// mech.lookForPickUp(Math.max(180, mech.grabRange));
|
|
||||||
// mech.pushMobs360(140);
|
|
||||||
|
|
||||||
// if (mech.health > 0.1) {
|
|
||||||
// const DRAIN = 0.0008
|
|
||||||
// if (mech.fieldMeter > DRAIN) {
|
|
||||||
// mech.fieldMeter -= DRAIN;
|
|
||||||
// mech.damage(0.00005 + 0.00000012 * mech.grabRange)
|
|
||||||
// //draw damage field
|
|
||||||
// mech.grabRange = mech.grabRange * 0.997 + (1350 + 150 * Math.cos(mech.cycle / 30)) * 0.003
|
|
||||||
// let gradient = ctx.createRadialGradient(this.pos.x, this.pos.y, 0, this.pos.x, this.pos.y, mech.grabRange);
|
|
||||||
// gradient.addColorStop(0, 'rgba(255,255,255,0.7)');
|
|
||||||
// gradient.addColorStop(1, 'rgba(255,0,50,' + (0.6 + 0.2 * Math.random()) + ')');
|
|
||||||
|
|
||||||
// const angleOff = 2 * Math.PI * Math.random()
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.arc(this.pos.x, this.pos.y, mech.grabRange + Math.sqrt(mech.grabRange) * 0.7 * (Math.random() - 0.5), angleOff, 1.8 * Math.PI + angleOff);
|
|
||||||
// ctx.fillStyle = gradient //rgba(255,0,0,0.2)
|
|
||||||
// ctx.fill();
|
|
||||||
|
|
||||||
// //damage and push away mobs in range
|
|
||||||
// for (let i = 0, len = mob.length; i < len; ++i) {
|
|
||||||
// if (mob[i].alive) {
|
|
||||||
// sub = Matter.Vector.sub(this.pos, mob[i].position);
|
|
||||||
// dist = Matter.Vector.magnitude(sub);
|
|
||||||
// if (dist < mech.grabRange) {
|
|
||||||
// mob[i].damage(0.01);
|
|
||||||
// mob[i].locatePlayer();
|
|
||||||
// mob[i].force = Matter.Vector.mult(Matter.Vector.normalise(sub), -0.0001 * mob[i].mass) //gently push mobs back
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// mech.fieldCDcycle = mech.cycle + 120;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// mech.grabRange = 180;
|
|
||||||
// mech.drawField();
|
|
||||||
// mech.grabPowerUp();
|
|
||||||
// mech.lookForPickUp();
|
|
||||||
// }
|
|
||||||
// } else if (mech.holdingTarget && mech.fireCDcycle < mech.cycle && mech.fieldMeter > 0.05) { //holding, but field button is released
|
|
||||||
// mech.grabRange = 0
|
|
||||||
// mech.pickUp();
|
|
||||||
// } else {
|
|
||||||
// mech.grabRange = 0
|
|
||||||
// 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)
|
|
||||||
// }
|
|
||||||
// mech.drawFieldMeter()
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -45,7 +45,8 @@ const powerUps = {
|
|||||||
if (!game.lastLogTime) game.makeTextLog("<span style='font-size:115%;'><span class='color-f'>+energy</span></span>", 300);
|
if (!game.lastLogTime) game.makeTextLog("<span style='font-size:115%;'><span class='color-f'>+energy</span></span>", 300);
|
||||||
} else {
|
} else {
|
||||||
//ammo given scales as mobs take more hits to kill
|
//ammo given scales as mobs take more hits to kill
|
||||||
const ammo = Math.ceil((target.ammoPack * (0.45 + 0.08 * Math.random())) / b.dmgScale);
|
let ammo = Math.ceil((target.ammoPack * (0.4 + 0.05 * Math.random())) / b.dmgScale);
|
||||||
|
if (level.isBuildRun) ammo *= 2
|
||||||
target.ammo += ammo;
|
target.ammo += ammo;
|
||||||
game.updateGunHUD();
|
game.updateGunHUD();
|
||||||
game.makeTextLog("<div class='circle gun'></div> <span style='font-size:110%;'>+" + ammo + " ammo for " + target.name + "</span>", 300);
|
game.makeTextLog("<div class='circle gun'></div> <span style='font-size:110%;'>+" + ammo + " ammo for " + target.name + "</span>", 300);
|
||||||
@@ -143,38 +144,49 @@ const powerUps = {
|
|||||||
spawnRandomPowerUp(x, y) { //mostly used after mob dies
|
spawnRandomPowerUp(x, y) { //mostly used after mob dies
|
||||||
if (Math.random() * Math.random() - 0.25 > Math.sqrt(mech.health) || Math.random() < 0.04) { //spawn heal chance is higher at low health
|
if (Math.random() * Math.random() - 0.25 > Math.sqrt(mech.health) || Math.random() < 0.04) { //spawn heal chance is higher at low health
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "heal");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.2) {
|
if (Math.random() < 0.2 && b.inventory.length > 0) {
|
||||||
if (b.inventory.length > 0) powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "ammo");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.004 * (5 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun to drop
|
if (Math.random() < 0.004 * (5 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun to drop
|
||||||
powerUps.spawn(x, y, "gun");
|
powerUps.spawn(x, y, "gun");
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "gun");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.004 * (8 - b.modCount)) {
|
if (Math.random() < 0.004 * (8 - b.modCount)) {
|
||||||
powerUps.spawn(x, y, "mod");
|
powerUps.spawn(x, y, "mod");
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "mod");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.005) {
|
if (Math.random() < 0.005) {
|
||||||
powerUps.spawn(x, y, "field");
|
powerUps.spawn(x, y, "field");
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "field");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades
|
spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades
|
||||||
if (mech.fieldMode === 0) {
|
if (mech.fieldMode === 0) {
|
||||||
powerUps.spawn(x, y, "field")
|
powerUps.spawn(x, y, "field")
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "field")
|
||||||
} else if (Math.random() < 0.042 * (b.mods.length - b.modCount)) {
|
} else if (Math.random() < 0.042 * (b.mods.length - b.modCount)) {
|
||||||
powerUps.spawn(x, y, "mod")
|
powerUps.spawn(x, y, "mod")
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "mod")
|
||||||
} else if (Math.random() < 0.3) {
|
} else if (Math.random() < 0.3) {
|
||||||
powerUps.spawn(x, y, "field");
|
powerUps.spawn(x, y, "field");
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "field");
|
||||||
} else if (Math.random() < 0.05 * (7 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun to drop
|
} else if (Math.random() < 0.05 * (7 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun to drop
|
||||||
powerUps.spawn(x, y, "gun")
|
powerUps.spawn(x, y, "gun")
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "gun")
|
||||||
} else if (mech.health < 0.6) {
|
} else if (mech.health < 0.6) {
|
||||||
powerUps.spawn(x, y, "heal");
|
powerUps.spawn(x, y, "heal");
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "heal");
|
||||||
} else {
|
} else {
|
||||||
powerUps.spawn(x, y, "ammo");
|
powerUps.spawn(x, y, "ammo");
|
||||||
|
if (Math.random() < b.modMoreDrops) powerUps.spawn(x, y, "ammo");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
chooseRandomPowerUp(x, y) { //100% chance to drop a random power up //used in spawn.debris
|
chooseRandomPowerUp(x, y) { //100% chance to drop a random power up //used in spawn.debris
|
||||||
@@ -195,31 +207,33 @@ const powerUps = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
spawn(x, y, target, moving = true, mode = null) {
|
spawn(x, y, target, moving = true, mode = null) {
|
||||||
let i = powerUp.length;
|
if (!level.isBuildRun || target === "heal" || target === "ammo") {
|
||||||
target = powerUps[target];
|
let i = powerUp.length;
|
||||||
size = target.size();
|
target = powerUps[target];
|
||||||
powerUp[i] = Matter.Bodies.polygon(x, y, 0, size, {
|
size = target.size();
|
||||||
density: 0.001,
|
powerUp[i] = Matter.Bodies.polygon(x, y, 0, size, {
|
||||||
frictionAir: 0.01,
|
density: 0.001,
|
||||||
restitution: 0.8,
|
frictionAir: 0.01,
|
||||||
inertia: Infinity, //prevents rotation
|
restitution: 0.8,
|
||||||
collisionFilter: {
|
inertia: Infinity, //prevents rotation
|
||||||
group: 0,
|
collisionFilter: {
|
||||||
category: 0x100000,
|
group: 0,
|
||||||
mask: 0x100001
|
category: 0x100000,
|
||||||
},
|
mask: 0x100001
|
||||||
color: target.color,
|
},
|
||||||
effect: target.effect,
|
color: target.color,
|
||||||
mode: mode,
|
effect: target.effect,
|
||||||
name: target.name,
|
mode: mode,
|
||||||
size: size
|
name: target.name,
|
||||||
});
|
size: size
|
||||||
if (moving) {
|
|
||||||
Matter.Body.setVelocity(powerUp[i], {
|
|
||||||
x: (Math.random() - 0.5) * 15,
|
|
||||||
y: Math.random() * -9 - 3
|
|
||||||
});
|
});
|
||||||
|
if (moving) {
|
||||||
|
Matter.Body.setVelocity(powerUp[i], {
|
||||||
|
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[i]); //add to world
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
113
style.css
113
style.css
@@ -1,7 +1,7 @@
|
|||||||
body {
|
body {
|
||||||
font-family: "Helvetica", "Arial", sans-serif;
|
font-family: "Helvetica", "Arial", sans-serif;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
/* overflow: hidden; */
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
/*cursor: crosshair;*/
|
/*cursor: crosshair;*/
|
||||||
@@ -35,10 +35,78 @@ table {
|
|||||||
/* background-color: #ddd; */
|
/* background-color: #ddd; */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
summary {
|
summary {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#build-button {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
right: 1px;
|
||||||
|
z-index: 12;
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#build-grid {
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0px;
|
||||||
|
border: 0px;
|
||||||
|
/* border-radius: 8px; */
|
||||||
|
background-color: #b6bfca;
|
||||||
|
|
||||||
|
display: none;
|
||||||
|
/* display: grid; */
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(292px, 1fr));
|
||||||
|
grid-auto-rows: minmax(auto, auto);
|
||||||
|
grid-gap: 15px;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
bottom: 0px;
|
||||||
|
/* left: 0px; */
|
||||||
|
z-index: 12;
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.build-grid-module {
|
||||||
|
/* box-shadow: 0px 1px 4px #234; */
|
||||||
|
padding: 7px;
|
||||||
|
/* margin: 4px; */
|
||||||
|
line-height: 150%;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #eee;
|
||||||
|
font-size: 0.65em;
|
||||||
|
/* display: flex; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.build-grid-module:hover {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gun-module {
|
||||||
|
background: #d5dde5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-module {
|
||||||
|
background: #bde;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mod-module {
|
||||||
|
background: #fdf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* #build {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
right: 1px;
|
||||||
|
z-index: 12;
|
||||||
|
font-size: 1.3em;
|
||||||
|
} */
|
||||||
|
|
||||||
#controls {
|
#controls {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
@@ -49,14 +117,6 @@ summary {
|
|||||||
/* border-radius: 5px; */
|
/* border-radius: 5px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
#settings {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0px;
|
|
||||||
right: 1px;
|
|
||||||
z-index: 12;
|
|
||||||
font-size: 1.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#details-div {
|
#details-div {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@@ -214,36 +274,28 @@ em {
|
|||||||
|
|
||||||
.color-f {
|
.color-f {
|
||||||
color: #0cf;
|
color: #0cf;
|
||||||
}
|
letter-spacing: 1px;
|
||||||
|
|
||||||
.color-b {
|
|
||||||
color: #024;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-d {
|
.color-d {
|
||||||
color: #f05;
|
color: #f03;
|
||||||
}
|
letter-spacing: 1px;
|
||||||
|
|
||||||
.color-l {
|
|
||||||
color: #f0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-h {
|
.color-h {
|
||||||
color: #0d9;
|
color: #0c8;
|
||||||
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-e {
|
.color-e {
|
||||||
color: #a10;
|
color: #e50;
|
||||||
}
|
letter-spacing: 1px;
|
||||||
|
|
||||||
.color-m {
|
|
||||||
color: #536;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-s {
|
.color-s {
|
||||||
color: #066;
|
color: #066;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.faded {
|
.faded {
|
||||||
@@ -256,6 +308,15 @@ em {
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
margin-bottom: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-grid {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: -4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.field {
|
.field {
|
||||||
@@ -268,12 +329,10 @@ em {
|
|||||||
|
|
||||||
.gun {
|
.gun {
|
||||||
background: #149;
|
background: #149;
|
||||||
margin-bottom: -2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.heal {
|
.heal {
|
||||||
background: #0d9;
|
background: #0d9;
|
||||||
margin-bottom: -2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
|
|||||||
Reference in New Issue
Block a user