Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm working on creating an inventory system for a game. The inventory system will use cells and 2D images to represent items, like Minecraft, Diablo, or WoW. I've hit a bit of a snag when trying to let the player place items in the bag (click and drag style).

So far, I've successfully created the inventory grid, which is really smoke and mirrors:

public class InventoryMenu {
boolean objectSelected = false;
Item selectedItem;

public final int COLUMNS = 5;
public final int ROWS = 7;

ArrayList<Item> inv = new ArrayList<Item>((ROWS + 1) * COLUMNS);
Sprite slot;

public void render(Graphics g) {

    for (int i = 0; i < 40; i++) {
        int col = i % COLUMNS;
        int row = ROWS - i / COLUMNS;


        slot.draw(g, (Camera.width - slot.getWidth() * COLUMNS) + slot.getWidth()* col, row * slot.getHeight());

        if (inv.get(i) != null) {
            inv.get(i).render(g);
        }
    }
    if (selectedItem != null) {
        selectedItem.render(g);
    }
}

Basically, I have an arraylist that can hold items, and it just draws the "slot" image 40 times and if there's an item in that "slot" it draws the item image too. Cool? Cool. The problem comes if I want to allow the player to select an item in their inventory and move it to a different slot. I have no problem letting them pick it up (I use a pretty primitive brute force, but with any reasonably sized inventory, it works):

private Item grabItem(Point2D mouse) {
    for (Item i : inv) {
        if (i != null) {
            if (i.getPhysicsShape().contains(mouse)) {
                Item pick = i;
                selectedItem = pick;
                objectSelected = true;
                i = null;
                return pick;
            }
        }
    }
    return null;
}

That bit of code lets a player pick up an item, but placing it fails - it rarely gets the right slot, except if its the bottom row (0-4):

setDown(){
    int slotLoc = calcSlot(InputHandler.mouseCoords);
    placeItem(slotLoc);
}

private void placeItem(int loc) {
    if(loc < 0 || loc > ROWS * (COLUMNS + 1))
        return;

    int col = loc % COLUMNS;
    int row = ROWS - loc / COLUMNS;
    selectedItem.pickUp((Camera.width - slot.getWidth() * COLUMNS) + slot.getWidth() * col, row * slot.getHeight());

    inv.set(loc, selectedItem);
    selectedItem = null;
    objectSelected = false;
}

private int calcSlot(Point2D mouse){
    int colPos = (int) (COLUMNS - (Camera.width - mouse.getX()) / slot.getWidth());
    int rowPos = (int) (ROWS+1 - (mouse.getY()) / slot.getHeight());


    if (colPos > COLUMNS || colPos < 0 || rowPos < 0 || rowPos > ROWS + 1) {
        dropItem();
        return -1;
    } else {
        return colPos + 4*rowPos;
    }

}

I'm fairly confident that the problem is in calcSlot, but I can't seem to find where. Any help would be greatly appreciated, I'm sure it's something silly.

Images!!

So, I can pick up an item with no problem, and it automatically places it in the last slot. So far, everything is gold.

Successfully placed in slot 39

I can then click that image and lift it out of the grid, and it follows my mouse (mouse is hidden by PrntScrn, but its at the top left corner of the image:

Dragging

When I try to place the item by clicking in the middle of slot 33, however, it derps and places it, inexplicably, in slot 27.

Derp

share|improve this question
    
Just write the logic of moving an item from slot to slot on paper and it will become crystal clear what you should do. Think of it as moving value (item) from field A to field B using field C (temp item slot). –  user1306322 Mar 23 '13 at 5:20
    
Thanks, but that's not my problem. Picking up the item (making it follow the mouse and then replacing it in the inventory) works just fine, its the placing it in the right slot on the grid (visual problem). –  BattleBarnes Mar 23 '13 at 5:22
    
Can you describe it in more detail? Maybe you have an image that illustrates the problem? –  user1306322 Mar 23 '13 at 5:24
    
Added pictures to the post. –  BattleBarnes Mar 23 '13 at 5:32

2 Answers 2

up vote 3 down vote accepted

I'll just give you the basic logic, not in Java, but I hope you can understand it.

Find the bottom left corner of the inventory (where the slot 0 is) and save that point in BLpoint. Then use variable dropPoint = (mouse.x - BLpoint.x ; BLpoint.y - mouse.y).

If dropPoint.x or .y is less than zero, you've missed the inventory slots.

The slot coordinates X = dropPoint.x / slotWidth, Y = dropPoint.y / slotHeight.

For items larger than 1×1 this might require some alteration. I would suggest you make your slot numbers start at top left corner of the inventory, it's going to be more simple for you to code.

nice metal dude btw

share|improve this answer
    
This makes a lot of sense, though I feel like it's almost exactly what I'm doing, just neater. I'm gonna play around with this, and see if it works better. Also, thanks! I like my metal dude. –  BattleBarnes Mar 23 '13 at 5:52
    
Actually, this only solves half my problem. See, the inventory is an ArrayList, not a 2D array, so I can't just put the item in [x][y], I have to turn x and y into a slot ID between 0-39. I had that as x + 4*y, but that doesn't seem to be playing well. Any ideas? –  BattleBarnes Mar 23 '13 at 5:57
1  
Final comment! Your solution is in fact the same as what I'm doing (but it is waaay neater) - my problem was in placing the item. The formula I ended up with is slot = 5*rowPos + colPos and now it works. Thanks all the same, you made me examine my code more closely. –  BattleBarnes Mar 23 '13 at 6:07
1  
Sometimes (actually more often than most programmers are willing to admit) it is better to put aside existing code and think again how you would solve a problem, like in this case. –  user1306322 Mar 23 '13 at 6:08
private int calcSlot(Point2D mouse){
    int colPos = (int) (COLUMNS - (Camera.width - mouse.getX()) / slot.getWidth());
    int rowPos = (int) (ROWS - ((mouse.getY())- slot.getHeight()) / slot.getHeight());


    if (colPos > COLUMNS || colPos < 0 || rowPos < 0 || rowPos > ROWS + 1) {
        dropItem();
        return -1;
    } else {
        return COLUMNS*rowPos + colPos;
    }

}
share|improve this answer
1  
You should add comments and some descriptive text to this answer. Answers that are just code are not very good. –  Byte56 Mar 23 '13 at 7:42

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.