Professional Documents
Culture Documents
Inventory Tutorial
Inventory Tutorial
In this tutorial we will make a drag and drop inventory like this.
class Inventory(Entity):
def __init__(self):
super().__init__()
if __name__ == '__main__':
app = Ursina()
inventory = Inventory()
app.run()
2 Adding graphics
However, if we run the code, we'll see that there's nothing visible.
Let's parent it to the ui and set the model to 'quad', an included model.
class Inventory(Entity):
def __init__(self):
super().__init__(
parent = camera.ui,
model = 'quad'
)
if __name__ == '__main__':
app = Ursina()
inventory = Inventory()
app.run()
If we look at it now, we see it's a white square in the middle of the screen.
Let's set it to a nicer shape. We also want (0,0) to be in the upper left corner
because it makes it easier to add items later. Let's also give it a texture and a color.
If we have both, the color value will tint the texture.
Now, this is nice and all, but wouldn't it be nice to show a grid as well?
There are multiple way to do that, but in this case, we'll simply make the texture repeat
by setting texture_scale to (5,6). That'll nicely fit the size of our inventory.
class Inventory(Entity):
def __init__(self):
super().__init__(
parent = camera.ui,
model = 'quad',
scale = (.5, .8),
origin = (-.5, .5),
position = (-.3,.4),
texture = 'white_cube',
texture_scale = (5,8),
color = color.dark_gray
)
if __name__ == '__main__':
app = Ursina()
inventory = Inventory()
app.run()
class Inventory(Entity):
def __init__(self):
super().__init__(
parent = camera.ui,
model = 'quad',
scale = (.5, .8),
origin = (-.5, .5),
position = (-.3,.4),
texture = 'white_cube',
texture_scale = (5,8),
color = color.dark_gray
)
if __name__ == '__main__':
app = Ursina()
inventory = Inventory()
item = Button(parent=inventory, color=color.red, position=(0,0))
item = Button(parent=inventory, color=color.green, position=(2,0))
app.run()
Well, that didn't go as planned. The items cover the entire inventory and
the second item is way off to the left.
Let's fix this by making another object to put the items under.
Scale the object to the size of an item.
They also don't fit the grid. Fix that by setting origin to the upper left
corner, (-.5,.5).
class Inventory(Entity):
def __init__(self):
super().__init__(
parent = camera.ui,
model = 'quad',
scale = (.5, .8),
origin = (-.5, .5),
position = (-.3,.4),
texture = 'white_cube',
texture_scale = (5,8),
color = color.dark_gray
)
if __name__ == '__main__':
app = Ursina()
inventory = Inventory()
item = Button(parent=inventory.item_parent, origin=(-.5,.5), color=color.red, position=(0,0))
item = Button(parent=inventory.item_parent, origin=(-.5,.5), color=color.green, position=(2,0))
app.run()
4 Adding items
We've added some items manually to make sure they get the right scale and position,
but we should make an append() function so it's easy to add items.
Let's start by making a function called 'append()' and make it spawn an item
when we send it a string. We'll also set the button's text to the string we
receive so we can differentiate them.
Let's give them a random color too, why not.
Lastly, let's call inventory.append('test item') a couple of times to make sure it works.
class Inventory(Entity):
def __init__(self):
super().__init__(
parent = camera.ui,
model = 'quad',
scale = (.5, .8),
origin = (-.5, .5),
position = (-.3,.4),
texture = 'white_cube',
texture_scale = (5,8),
color = color.dark_gray
)
if __name__ == '__main__':
app = Ursina()
inventory = Inventory()
inventory.append('test item')
inventory.append('test item')
app.run()
class Inventory(Entity):
def __init__(self):
super().__init__(
parent = camera.ui,
model = 'quad',
scale = (.5, .8),
origin = (-.5, .5),
position = (-.3,.4),
texture = 'white_cube',
texture_scale = (5,8),
color = color.dark_gray
)
def find_free_spot(self):
taken_spots = [(int(e.x), int(e.y)) for e in self.item_parent.children]
for y in range(8):
for x in range(5):
if not (x,-y) in taken_spots:
return (x,-y)
if __name__ == '__main__':
app = Ursina()
inventory = Inventory()
for i in range(7):
inventory.append('test item')
app.run()
Let's make an tuple with those and make the button choose a random item from the tuple
using random.choice(items)
if __name__ == '__main__':
app = Ursina()
inventory = Inventory()
def add_item():
inventory.append(random.choice(('bag', 'bow_arrow', 'gem', 'orb', 'sword')))
for i in range(7):
add_item()
add_item_button = Button(
scale = (.1,.1),
x = -.5,
color = color.lime.tint(-.25),
text = '+',
tooltip = Tooltip('Add random item'),
on_click = add_item
)
app.run()
Let's also remove the random color and instead show the item's name when we hover it with the mouse.
If a button has 'tooltip' set to something, it will show it when we hover the Button.
def drop():
icon.x = int(icon.x)
icon.y = int(icon.y)
icon.drop = drop
10 Swap items
Add a drag function to remember the start position as org_pos.
def drag():
icon.org_pos = (icon.x, icon.y)
def drop():
icon.x = int(icon.x)
icon.y = int(icon.y)
icon.drag = drag
icon.drop = drop
def drop():
icon.x = int(icon.x)
icon.y = int(icon.y)
icon.drop = drop
def drag():
icon.org_pos = (icon.x, icon.y)
icon.z -= .01 # ensure the dragged item overlaps the rest
def drop():
icon.x = int(icon.x)
icon.y = int(icon.y)
icon.z += .01
icon.drag = drag
icon.drop = drop