Skip to content

Interaction with non‐tile entities

pchsa edited this page Sep 15, 2023 · 22 revisions

The InteractionDetector is a component designed to handle interaction detection between entities within a specified range in the game. It is to used in the game to detect entities near the player character, such as NPCs. The entities in range can then be filtered based on the players held item and click position. It inherits from HitBoxComponent.

(UPDATE 15/09: This will be refactored in a future sprint to reduce coupling, getSuitableEntities() will be removed so component makes sense to use for non-player entities)

Functionality

The InteractionDetector component provides the following functionality:

  • InteractionDetector (constructor) - takes in a float for detection range, to be added as a component to entity.
  • getEntitiesInRange - returns all entities within range.
  • getEntitiesTowardsDirection - Since most entity animations have 4 directions, provides method to filter entities range towards direction
  • getEntitiesTowardsPosition - Converts position to direction in relation to entity and returns entities towards direction.
  • getNearest - takes a list of entities and returns nearest to current entity.
  • getSuitableEntities - takes an ItemType (or null) and position, and returns a filtered list on entities depending on input.

Usage

The code below outlines how to enable player to feed animals on click based on the held item.

Add desired ItemType to getSuitableEntities() function in InteractionDetector, e.g.

case FOOD -> {
  entities.removeIf(entity -> entity.getComponent(TamableComponent.class) == null);
  entities.removeIf(entity -> entity.getComponent(TamableComponent.class).isTamed()); 
  return getNearest(entities);
}

Add ItemType to ItemActions, e.g.

case FOOD -> {
  if (interactionCollider == null) {
    return false;
  }
  resultStatus = feed(interactionCollider.getSuitableEntities(ItemType.FOOD, mouseWorldPos));
  return resultStatus;
}

Handle returned entities from getSuitableEntities in ItemActions, e.g.

private boolean feed(List<Entity> feedableEntities) {
   if (feedableEntities.size() != 1) {
    return false;
   }

  feedableEntities.get(0).getEvents().trigger("feed");
  return true;
}

The above code now allows the player to feed animals. Clicking in a certain direction will allow the player feed the nearest feedable entity at that direction, given that the player is holding a ItemType.FOOD and that the feedable entity is within range.

A sequence diagram for feeding entities on click is shown below.

Reasoning behind Implementation

The implementation of the InteractionDetector component was driven by several key factors:

  • Game Requirements: The game needed a system to detect and interact with nearby non-tile entities, such as NPCs.
  • Consistent Gameplay: The existing psuedo-click controls for non-tile entities were emulated, ensuring a uniform player experience.
  • Directional Alignment: Controls were limited to four directions, aligning with the player character's animations for a cohesive visual experience.
  • Efficiency: Previous implentation idea was to loop over all entities in GameArea. This InteractionDetector employs hitbox detection, and gets entities within range instead of all entities, making it more efficient as the game scales.
Clone this wiki locally