All files / src characters.js

100% Statements 71/71
100% Branches 0/0
100% Functions 1/1
100% Lines 71/71

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 721x 1x 1x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x 300x  
import { Util } from './util.js';
 
/** A class containing methods for dealing with characters  */
export const Characters = {
  /**
   * This function determines the next move for a given NPC
   * @param {Object} state
   * @param {Character} state.npc the npc in question
   * @param {number} state.width the width of the whole map
   * @param {number} state.height the height of the whole map
   * @returns {Character} an updated version of the npc
   */
  moveNPC({ npc, width, height }) {
    let newNPC = npc;
 
    // Allow for spawn points
    if (npc.isNew) {
      if (npc.fallbackSpeed == null) {
        newNPC = { ...newNPC, speed: npc.width + 1, fallbackSpeed: npc.speed };
      } else if (!npc.hasCollision) {
        newNPC = { ...newNPC, speed: newNPC.fallbackSpeed, isNew: false };
      }
    }
 
    // If we're near to destination, set the next waypoint as our destination
    if (npc.destination && Util.dist(npc, npc.destination) <= npc.speed) {
      let { waypoints } = npc;
      waypoints = waypoints || [];
      newNPC = {
        ...newNPC,
        destination: waypoints[0],
        waypoints: waypoints.slice(1),
        exclude: null,
      };
    }
    if (newNPC.destination == null) { return newNPC; }
    const x = newNPC.x + Math.round(newNPC.width / 2);
    const y = newNPC.y + Math.round(newNPC.height / 2);
    const xdist = Math.abs(x - newNPC.destination.x);
    const xmove = Math.sign(-x + newNPC.destination.x) * Math.min(xdist, newNPC.speed);
    const ydist = Math.abs(y - newNPC.destination.y);
    const ymove = Math.sign(-y + newNPC.destination.y) * Math.min(ydist, newNPC.speed);
    if (xmove !== 0 || ymove !== 0) {
      let prefix = '';
      let { facing } = newNPC;
      if (ymove < 0) {
        prefix = 'up';
      } else if (ymove > 0) {
        prefix = 'down';
      }
 
      if (xmove < 0) {
        facing = `${prefix}left`;
      } else if (xmove > 0) {
        facing = `${prefix}right`;
      } else if (prefix) {
        facing = prefix;
      }
 
      newNPC = {
        ...newNPC,
        facing,
        x: Math.min(Math.max(newNPC.x + xmove, 0), width - 1),
        y: Math.min(Math.max(newNPC.y + ymove, 0), height - 1),
        hasCollision: false,
      };
    }
 
    return newNPC;
  },
};