diff --git a/src/constants.js b/src/constants.js index 9076d93..300bff8 100644 --- a/src/constants.js +++ b/src/constants.js @@ -74,7 +74,8 @@ export const PLAYER_INITIAL_POWER = 300; export const PLAYER_FALL_DAMAGE_HEIGHT = 50; export const PLAYER_FALL_DAMAGE_FACTOR = 3; export const PLAYER_EXPLOSION_PARTICLE_POWER = 500; -export const PLAYER_TANK_BOUNDING_RADIUS = 3; +export const PLAYER_TANK_BOUNDING_RADIUS = 4; +export const PLAYER_TANK_Y_FOOTPRINT = -2; export const PLAYER_ANGLE_INCREMENT = 1; export const PLAYER_ANGLE_FAST_INCREMENT = 3; export const PLAYER_POWER_INCREMENT = 1; diff --git a/src/main.js b/src/main.js index 8d6fc8e..56e8a9d 100644 --- a/src/main.js +++ b/src/main.js @@ -1,13 +1,13 @@ -import {H, PROJECTILE_MAX_SOUND_FREQUENCY, MAX_WIND, PROJECTILE_MIN_SOUND_FREQUENCY, PLAYER_COLORS, PLAYER_INITIAL_POWER, PROJECTILE_POWER_REDUCTION_FACTOR, W, Z, PROJECTILE_ITERATIONS_PER_FRAME, PROJECTILE_ITERATION_PROGRESS, PLAYER_MAX_ENERGY, PLAYER_ENERGY_POWER_MULTIPLIER, PLAYER_FALL_DAMAGE_FACTOR, PLAYER_FALL_DAMAGE_HEIGHT, PARTICLE_AMOUNT, PROJECTILE_WIND_REDUCTION_FACTOR, PARTICLE_POWER_REDUCTION_FACTOR, PARTICLE_WIND_REDUCTION_FACTOR, PARTICLE_MIN_POWER_FACTOR, PARTICLE_MAX_POWER_FACTOR, PARTICLE_MIN_LIFETIME, PARTICLE_TIME_FACTOR, PLAYER_EXPLOSION_PARTICLE_POWER, EXPLOSION_SHAKE_REDUCTION_FACTOR, MAX_EXPLOSION_SHAKE_FACTOR, TRAJECTORY_FADE_SPEED, PARTICLE_FADE_AMOUNT, TRAJECTORY_FLOAT_SPEED, PLAYER_TANK_BOUNDING_RADIUS, PLAYER_STARTING_WEAPONS, WEAPON_TYPES, DEATH_SPECS, PLAYER_ANGLE_INCREMENT, PLAYER_POWER_FAST_INCREMENT, PLAYER_POWER_INCREMENT, PLAYER_ANGLE_TICK_SOUND_INTERVAL, PLAYER_POWER_TICK_SOUND_INTERVAL, PLAYER_ANGLE_FAST_INCREMENT} from './constants.js'; -import {createCanvas, drawLine, drawRect, drawText, loop, plot, drawLineVirtual} from './gfx.js'; -import {key, afterKeyDelay} from './input.js'; -import {clamp, deg2rad, parable, randomInt, vec, wrap, random, within} from './math.js'; -import {createSky} from './sky.js'; -import {audio, createOsc, playTickSound, createAudioLoop} from './sound.js'; -import {collapseTerrain, createTerrain, isTerrain, landHeight, closestLand, clipTerrain} from './terrain.js'; -import {EXPLOSION_TYPES} from './weapons.js'; -import {sample} from './utils.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, PROJECTILE_ITERATIONS_PER_FRAME, PROJECTILE_ITERATION_PROGRESS, PROJECTILE_MAX_SOUND_FREQUENCY, PROJECTILE_MIN_SOUND_FREQUENCY, PROJECTILE_POWER_REDUCTION_FACTOR, PROJECTILE_WIND_REDUCTION_FACTOR, TRAJECTORY_FADE_SPEED, TRAJECTORY_FLOAT_SPEED, W, WEAPON_TYPES, Z} from './constants.js'; +import {createCanvas, drawLine, drawLineVirtual, drawRect, drawText, loop, plot} from './gfx.js'; +import {afterKeyDelay, key} from './input.js'; +import {clamp, deg2rad, distance, parable, random, randomInt, vec, wrap} from './math.js'; +import {createSky} from './sky.js'; +import {audio, createOsc, playTickSound} from './sound.js'; +import {clipTerrain, closestLand, collapseTerrain, createTerrain, isTerrain, landHeight} from './terrain.js'; +import {sample} from './utils.js'; +import {EXPLOSION_TYPES} from './weapons.js'; let state = 'start-game'; @@ -341,7 +341,11 @@ function updateParticles() { function isTank(x, y) { for (let player of players) { if (player.dead) continue; - if (within(x, y, player.x, player.y, PLAYER_TANK_BOUNDING_RADIUS)) { + + if ( + distance(x, y, player.x, player.y+PLAYER_TANK_Y_FOOTPRINT) <= + PLAYER_TANK_BOUNDING_RADIUS + ) { return true; } } diff --git a/src/math.js b/src/math.js index f479c94..89195de 100644 --- a/src/math.js +++ b/src/math.js @@ -5,8 +5,7 @@ export function index2coords(width, i) { } export function coords2index(width, x, y) { - x = Math.round(x); - y = Math.round(y); + x = Math.round(x); y = Math.round(y); width = Math.round(width); return y * width + x; } @@ -35,8 +34,15 @@ export function cycle(x, d) { return Math.floor(x / d); } -export function within(x, y, tx, ty, r) { - return Math.abs(x-tx) < r && Math.abs(y-ty) < r; +export function diagonal(a, b) { + return Math.sqrt(a**2 + b**2); +} + +export function distance(x1, y1, x2, y2) { + return diagonal( + Math.abs(x2-x1), + Math.abs(y2-y1), + ); } export function parable(t, x, y, a, v, w=0, g=9.8) { diff --git a/src/weapons.js b/src/weapons.js index cd6f22f..16a2243 100644 --- a/src/weapons.js +++ b/src/weapons.js @@ -1,8 +1,8 @@ +import {PLAYER_TANK_BOUNDING_RADIUS, PLAYER_TANK_Y_FOOTPRINT} from './constants.js'; import {drawCircle, plot} from './gfx.js'; +import {clamp, cycle, distance, randomInt} from './math.js'; +import {audio, createOsc} from './sound.js'; import {clipTerrain} from './terrain.js'; -import {within, cycle, random, randomInt} from './math.js'; -import {createOsc, audio} from './sound.js'; -import {PLAYER_TANK_BOUNDING_RADIUS} from './constants.js'; export function drawExplosion(ctx, x, y, r) { const color = 255 - (16 * (r % 16)); @@ -49,13 +49,11 @@ export const EXPLOSION_TYPES = { clipTerrain(terrain, (ctx) => drawExplosion(ctx, x, y, cr)); }, damage(explosion, player) { - if (within(explosion.x, explosion.y, player.x, player.y, explosion.r)) { - return 100; - } else if ( - within(explosion.x, explosion.y, player.x-PLAYER_TANK_BOUNDING_RADIUS, player.y, explosion.r) || - within(explosion.x, explosion.y, player.x+PLAYER_TANK_BOUNDING_RADIUS, player.y, explosion.r) - ) { - return 50; + const {x, y, r} = explosion; + const dist = distance(x, y, player.x, player.y+PLAYER_TANK_Y_FOOTPRINT); + const tolerance = clamp(0, dist - r, Infinity); + if (tolerance <= PLAYER_TANK_BOUNDING_RADIUS) { + return Math.round(100 * (1 - tolerance / (PLAYER_TANK_BOUNDING_RADIUS+1))); } } },