Skip to content

Item Pickup

Jeremyzihanwu edited this page Oct 18, 2026 · 2 revisions

Overview

Item pickup transfers ground items into the player's existing inventory. Consumables add stock for later use, Gold increases the currency balance, and charms are stored and equipped immediately.

ItemPickupComponent detects nearby ground items and handles pickup requests. Each item's pickUp(Entity player) implementation determines the inventory change; the component then removes the collected entity from the world.

Usage

  1. Move close enough to overlap a ground item's pickup hitbox.
  2. When Press E — Pick up [item name] appears, press E to collect it.
  3. Press I to inspect the inventory. Consumables can be equipped or unequipped through the book.
  4. During gameplay, press Tab to select a consumable slot and Q to use its item.

Overlapping an item makes it available for pickup; contact alone does not collect it. Each E request collects one ground entity, which may represent several units of a stackable item.

E also starts NPC interaction. The input handler sends interact first and requests itemPickup only if an NPC interaction has not started. An already active NPC interaction suppresses the pickup request. While the inventory book is open, Q and E change book pages instead of using or collecting items.

Pickup behaviour

Item category Result of picking up a ground item
Consumable Add the full stack quantity to inventory without applying its effect. A newly owned type is assigned to the first empty consumable slot when one is available.
Currency Add the stack quantity to the player's Gold balance and emit a Gold-pickup notification.
Charm Add the individual charm to inventory and equip it immediately, applying its bonus.

When several items overlap the player, pickup uses the order in which their overlap was recorded. It does not calculate which item is closest. The pickup prompt refers to the same first tracked item.

ItemPickupComponent

PlayerFactory attaches ItemPickupComponent to the player alongside HitboxComponent, InventoryComponent and the input component.

Usage

Code can request normal pickup through the player's event handler:

player.getEvents().trigger("itemPickup");

The component exposes String getPickupPrompt(). It returns the prompt for the first tracked item, or null when no prompt is available. The shared interaction prompt gives NPC prompts priority over item prompts, followed by exit prompts.

How it works internally

  1. Listen for collisionStart, collisionEnd and itemPickup on the player.
  2. On collision start, check that the player's fixture is its own hitbox, the other fixture includes PhysicsLayer.ITEM, and the other entity has an ItemComponent.
  3. Add that entity to a LinkedHashSet. Leaving the hitbox removes it from the set.
  4. On a pickup request, resolve the first tracked entity and obtain its Item from ItemComponent.
  5. Call the item's pickup method, remove it from the tracked set and dispose of the ground entity:
Item item = itemComponent.getItem();
item.pickUp(entity);
nearbyItems.remove(itemEntity);
itemEntity.dispose();

Here, entity is the player that owns the component. Pickup range comes from hitbox overlap; this component has no separate distance setting. If the set is empty, the request does nothing.

Events

The following events use the player entity's event handler:

Event Parameters Role
collisionStart Fixture me, Fixture other Track an eligible ground item entering the player's hitbox.
collisionEnd Fixture me, Fixture other Remove a ground item leaving the player's hitbox.
itemPickup None Request collection of one tracked ground entity.
consumableInventoryChanged String itemId, Integer count Notify observers of the updated consumable count.
goldChanged Integer total Notify observers when the Gold balance changes.
goldPickedUp Integer amount Report the amount acquired through the Gold-pickup path.
charmAdded Charm charm Notify observers when a charm is added to inventory.

Inventory notifications describe the mutation already performed. Their listeners should update displays or feedback without adding the same reward again.

Ground item creation

Item provides the shared pickUp(Entity player) and drop(Entity player) contracts, along with the stable ID, category, texture and quantity. ConsumableItem, CurrencyItem and Charm implement their own pickup behaviour.

ItemComponent holds an item instance. Its constructors accept an Item, a catalog ID, or an ItemDropSpec. getItem(), getItemId() and getQuantity() expose the stored item data; the component itself does not detect collisions or collect anything.

ItemFactory provides:

public static Entity createItem(Item item, Vector2 position)

The factory attaches physics, an ITEM-layer hitbox, ItemComponent and ItemDropAnimationComponent. The item texture must already be loaded through ResourceService. The returned entity is not registered automatically; the caller registers it with the entity service to place it in the active world.

Enemy reward creation uses ItemCatalog.createItems to keep consumables and currency as quantity-bearing stacks while expanding non-stackable charms into separate item instances.

Inventory integration

Consumables and slots

ConsumableItem.pickUp calls InventoryComponent.addConsumable(getId(), quantity). Inventory stores quantities by item ID and maintains four consumable-slot assignments.

  • Picking up a newly owned type fills the first empty slot when available. If all four slots are occupied, the stock is still added and can be equipped through the inventory book later.
  • Picking up more of an already owned type increases its count. It does not assign another slot or automatically re-equip a type that was manually unequipped.
  • Unequipping clears the slot assignment without removing stock. Using the final copy clears that type's slot.

The four Consumable Slots display equipped item types and their quantities along the bottom of the screen. Pickup changes inventory data, and the display reads that shared state. Use Inventory UI (Team Five) for equipment controls and slot assignment through the book.

Item use is handled separately by ConsumableSelectionComponent and ConsumableEffectComponent. See Consumables for selection, use requests and effects.

Gold

CurrencyItem.pickUp calls InventoryComponent.addGoldFromPickup(quantity). This updates the balance through addGold and reports the positive pickup amount through goldPickedUp.

goldChanged carries the new total balance; goldPickedUp carries the amount just collected. Other balance changes, such as spending Gold, do not become pickup notifications.

Charms

Charm.pickUp checks whether that exact instance is already owned, then calls addCharm(this) and setEquipped(player, true). Separate copies of the same charm type remain independent inventory items.

setEquipped(Entity player, boolean equipped) applies or removes the bonus only when the equipment state changes. Unequipping retains ownership. The charm's drop method unequips it and removes it from inventory; it does not create a new ground entity.

Ground pickup and purchasing have different equipment behaviour. The Merchant stores newly purchased charms unequipped and adds purchased consumables without automatically filling an empty slot.

Magnet collection

MagnetEffect provides automatic collection for currency and consumables, excluding charms. It scans registered ground items and pulls eligible items towards the player. Collection calls the same Item.pickUp(player) method, so it uses the same inventory and slot rules as normal pickup.

The default Magnet Potion lasts 10 seconds, attracts items within 4 world units, and moves them at 6 world units per second. It collects an item within 0.4 world units, or when the current movement step would reach it.

Magnet collection does not require E or player-hitbox overlap. It schedules the collected ground entity for disposal after the update loop; normal E pickup disposes of the entity immediately.

Testing

The pickup implementation and its integration with inventory and input include the following test classes:

  • CharmPickupComponentTest
  • EnemyLootPickupIntegrationTest
  • ItemComponentTest
  • ItemPickupUseIntegrationTest
  • InventoryComponentTest
  • KeyboardPlayerInputComponentTest
  • InteractionPromptTest
  • ItemFactoryTest
  • ConsumableItemTest
  • MagnetUseIntegrationTest

Source and related documentation

Table of Contents

Home

Test Plan

Team 2

Features

Components
Player
Items and Inventory
Enemies
Interactable NPCs
Cutscenes and Dialogue
Music
Bosses
Rooms
Weapons
Abilities & Spells
Game Screens and Areas
Dungeons

Game Engine

Getting Started

Entities and Components

Service Locator

Loading Resources

Logging

Unit Testing

Debug Terminal

Input Handling

UI

Animations

Audio

AI

Physics

Terrain

Concurrency & Threading

Settings

Troubleshooting

MacOS Setup Guide

Clone this wiki locally