Parachutes

This commit is contained in:
zenoamaro committed 2019-07-03 01:04:15 +02:00
1 parent 5a5232d6f0
commit 03c3d3ec42
3 files changed
+48 -12

No files matched your search

+6 -2
View File
@@ -30,8 +30,8 @@ export const PLAYER_STARTING_WEAPONS = [
{type: 'babyRoller', ammo:5}, {type: 'babyRoller', ammo:5},
{type: 'roller', ammo:3}, {type: 'roller', ammo:3},
{type: 'superRoller', ammo:1}, {type: 'superRoller', ammo:1},
{type: 'mirv', ammo:5}, {type: 'mirv', ammo:3},
{type: 'xmirv', ammo:3}, {type: 'xmirv', ammo:1},
{type: 'leapfrog', ammo:3}, {type: 'leapfrog', ammo:3},
{type: 'superLeapfrog', ammo:1}, {type: 'superLeapfrog', ammo:1},
{type: 'smallDirt', ammo:5}, {type: 'smallDirt', ammo:5},
@@ -81,6 +81,10 @@ export const DEATH_SPECS = [
{type: 'dirtCone', r: 400}, {type: 'dirtCone', r: 400},
]; ];
export const PLAYER_STARTING_TOOLS = [
{type: 'parachute', ammo: 1},
];
export const MAX_WIND = 25; export const MAX_WIND = 25;
export const DEFAULT_KEYPRESS_DELAY = 150; export const DEFAULT_KEYPRESS_DELAY = 150;
+10
View File
@@ -93,6 +93,16 @@ export function drawCircle(ctx, x, y, r, color) {
} }
} }
export function drawSemiCircle(ctx, x, y, r, color) {
x = Math.round(x);
y = Math.round(y);
r = Math.round(r);
for (let cy = -r; cy <= 0; cy++) {
const w = Math.round(Math.sqrt(r*r - cy*cy));
drawRect(ctx, x-w, y+cy, w*2, 1, color);
}
}
/** @param align {CanvasTextAlign} */ /** @param align {CanvasTextAlign} */
/** @param baseline {CanvasTextBaseline} */ /** @param baseline {CanvasTextBaseline} */
export function drawText(ctx, text, x, y, color, align='left', baseline='top') { export function drawText(ctx, text, x, y, color, align='left', baseline='top') {
+32 -10
View File
@@ -1,6 +1,6 @@
import {AI_TYPES} from './ai.js'; import {AI_TYPES} from './ai.js';
import {DEATH_SPECS, EXPLOSION_SHAKE_REDUCTION_FACTOR, H, MAX_EXPLOSION_SHAKE_FACTOR, MAX_WIND, PARTICLE_AMOUNT, PARTICLE_FADE_AMOUNT, PARTICLE_MAX_POWER_FACTOR, PARTICLE_MIN_LIFETIME, PARTICLE_MIN_POWER_FACTOR, PARTICLE_POWER_REDUCTION_FACTOR, PARTICLE_TIME_FACTOR, PARTICLE_WIND_REDUCTION_FACTOR, PLAYER_ANGLE_FAST_INCREMENT, PLAYER_ANGLE_INCREMENT, PLAYER_ANGLE_TICK_SOUND_INTERVAL, PLAYER_COLORS, PLAYER_ENERGY_POWER_MULTIPLIER, PLAYER_EXPLOSION_PARTICLE_POWER, PLAYER_FALL_DAMAGE_FACTOR, PLAYER_FALL_DAMAGE_HEIGHT, PLAYER_INITIAL_POWER, PLAYER_MAX_ENERGY, PLAYER_POWER_FAST_INCREMENT, PLAYER_POWER_INCREMENT, PLAYER_POWER_TICK_SOUND_INTERVAL, PLAYER_STARTING_WEAPONS, PLAYER_TANK_BOUNDING_RADIUS, PLAYER_TANK_Y_FOOTPRINT, TRAJECTORY_FADE_SPEED, TRAJECTORY_FLOAT_SPEED, W, WEAPON_TYPES, Z} from './constants.js'; import {DEATH_SPECS, EXPLOSION_SHAKE_REDUCTION_FACTOR, H, MAX_EXPLOSION_SHAKE_FACTOR, MAX_WIND, PARTICLE_AMOUNT, PARTICLE_FADE_AMOUNT, PARTICLE_MAX_POWER_FACTOR, PARTICLE_MIN_LIFETIME, PARTICLE_MIN_POWER_FACTOR, PARTICLE_POWER_REDUCTION_FACTOR, PARTICLE_TIME_FACTOR, PARTICLE_WIND_REDUCTION_FACTOR, PLAYER_ANGLE_FAST_INCREMENT, PLAYER_ANGLE_INCREMENT, PLAYER_ANGLE_TICK_SOUND_INTERVAL, PLAYER_COLORS, PLAYER_ENERGY_POWER_MULTIPLIER, PLAYER_EXPLOSION_PARTICLE_POWER, PLAYER_FALL_DAMAGE_FACTOR, PLAYER_FALL_DAMAGE_HEIGHT, PLAYER_INITIAL_POWER, PLAYER_MAX_ENERGY, PLAYER_POWER_FAST_INCREMENT, PLAYER_POWER_INCREMENT, PLAYER_POWER_TICK_SOUND_INTERVAL, PLAYER_STARTING_TOOLS, PLAYER_STARTING_WEAPONS, PLAYER_TANK_BOUNDING_RADIUS, PLAYER_TANK_Y_FOOTPRINT, TRAJECTORY_FADE_SPEED, TRAJECTORY_FLOAT_SPEED, W, WEAPON_TYPES, Z} from './constants.js';
import {createCanvas, drawLine, drawRect, drawText, loop, plot} from './gfx.js'; import {createCanvas, drawLine, drawRect, drawSemiCircle, drawText, loop, plot} from './gfx.js';
import {afterKeyDelay, key} from './input.js'; import {afterKeyDelay, key} from './input.js';
import {clamp, deg2rad, distance, parable, random, randomInt, vec, wrap} from './math.js'; import {clamp, deg2rad, distance, parable, random, randomInt, vec, wrap} from './math.js';
import {PROJECTILE_TYPES} from './projectiles.js'; import {PROJECTILE_TYPES} from './projectiles.js';
@@ -49,7 +49,8 @@ for (let [color, borderColor] of PLAYER_COLORS) {
x, y, a, x, y, a,
c: color, cb: borderColor, c: color, cb: borderColor,
p: PLAYER_INITIAL_POWER, p: PLAYER_INITIAL_POWER,
weapons: PLAYER_STARTING_WEAPONS.map(x => ({...x})), // FIXME tools: PLAYER_STARTING_TOOLS.map(x => ({...x})), // FIXME: Ghetto clone
weapons: PLAYER_STARTING_WEAPONS.map(x => ({...x})), // FIXME: Ghetto clone
currentWeapon: 0, currentWeapon: 0,
energy: PLAYER_MAX_ENERGY, energy: PLAYER_MAX_ENERGY,
ai: i !== 0 ? sample(Object.keys(AI_TYPES)) : undefined, ai: i !== 0 ? sample(Object.keys(AI_TYPES)) : undefined,
@@ -197,8 +198,17 @@ function update() {
stable = false; stable = false;
player.y++; player.y++;
if (player.fallHeight++ >= PLAYER_FALL_DAMAGE_HEIGHT) { if (player.fallHeight++ >= PLAYER_FALL_DAMAGE_HEIGHT) {
if (player.energy > 0 && player.parachute) continue;
const parachute = player.tools.find(x => x.type === 'parachute');
if (player.energy > 0 && parachute && parachute.ammo > 0) {
player.parachute = parachute;
parachute.ammo--;
continue;
}
player.energy -= PLAYER_FALL_DAMAGE_FACTOR; player.energy -= PLAYER_FALL_DAMAGE_FACTOR;
} }
} else {
player.parachute = null;
} }
} }
if (stable) state = 'destroy-players'; if (stable) state = 'destroy-players';
@@ -227,15 +237,12 @@ function update() {
return state = 'player-win'; return state = 'player-win';
} }
const player = players[currentPlayer]; for (let player of players) {
player.weapons = player.weapons.filter(x => x.ammo > 0);
const weaponType = player.weapons[player.currentWeapon]; player.tools = player.tools.filter(x => x.ammo > 0);
if (weaponType.ammo <= 0) {
player.weapons = player.weapons.filter(x => x !== weaponType);
}
player.currentWeapon = wrap(0, player.currentWeapon, player.weapons.length-1); player.currentWeapon = wrap(0, player.currentWeapon, player.weapons.length-1);
player.fallHeight = 0; player.fallHeight = 0;
}
for (let p=0; p<players.length; p++) { for (let p=0; p<players.length; p++) {
const i = wrap(0, currentPlayer+p+1, players.length-1); const i = wrap(0, currentPlayer+p+1, players.length-1);
@@ -337,10 +344,24 @@ function drawPlayers() {
for (let player of players) { for (let player of players) {
const {x, y, a, c, cb, energy, dead} = player; const {x, y, a, c, cb, energy, dead} = player;
if (dead) continue; if (dead) continue;
// Parachute
if (player.parachute) {
drawSemiCircle(foreground, x, y-15, 10, 'white');
drawLine(foreground, x-10, y-15, x-2, y, 'white');
drawLine(foreground, x-5, y-15, x-1, y, 'white');
drawLine(foreground, x, y-15, x, y, 'white');
drawLine(foreground, x+5, y-15, x+1, y, 'white');
drawLine(foreground, x+10, y-15, x+2, y, 'white');
}
// Cannon
const [px, py] = vec(x, y-3, a+180, 3); const [px, py] = vec(x, y-3, a+180, 3);
drawLine(foreground, x-1, y-3, px-1, py, cb); drawLine(foreground, x-1, y-3, px-1, py, cb);
drawLine(foreground, x+1, y-3, px+1, py, cb); drawLine(foreground, x+1, y-3, px+1, py, cb);
drawLine(foreground, x, y-4, px, py-1, cb); drawLine(foreground, x, y-4, px, py-1, cb);
// Tank
drawRect(foreground, x-4, y-3, 8, 1, cb); drawRect(foreground, x-4, y-3, 8, 1, cb);
drawRect(foreground, x-5, y-2, 10, 2, cb); drawRect(foreground, x-5, y-2, 10, 2, cb);
drawRect(foreground, x-4, y-0, 8, 1, cb); drawRect(foreground, x-4, y-0, 8, 1, cb);
@@ -349,6 +370,7 @@ function drawPlayers() {
drawRect(foreground, x-4, y-2, 8, 2, c); drawRect(foreground, x-4, y-2, 8, 2, c);
drawRect(foreground, x-3, y-0, 6, 1, c); drawRect(foreground, x-3, y-0, 6, 1, c);
// Damage
const damage = clamp(0, 1 - energy/PLAYER_MAX_ENERGY, 1); const damage = clamp(0, 1 - energy/PLAYER_MAX_ENERGY, 1);
foreground.globalAlpha = damage * 0.7; foreground.globalAlpha = damage * 0.7;
drawRect(foreground, x-4, y-2, 8, 2, cb); drawRect(foreground, x-4, y-2, 8, 2, cb);