Don't worry, it's not much!
So you'd like to check if there is at least
one item in the
container_trash, and if at least one item is
droppable?
That's not too complicated!
That said, for the record, if
container_trash contains 0 items (that is, if
container_trash.items is an empty list), then the
for item in container_trash.items loop will itself be empty: if there are no items in
container_trash.items, then the loop will do nothing anyway.
In other words, no
imagebutton will be displayed on the screen if there are no items to display in the first place.
Therefore, your condition is in part naturally fulfilled by the loop: it's just lacking the verification that at least one item is
droppable.
To display only droppable items, you would have a few possibilities:
1) With the showif statement
The easiest way is to use
the showif statement inside the loop, to check if each item is droppable.
The
showif statement simply takes a condition to verify. It would be used this way:
Code: Select all
screen container_trash:
for item in container_trash.items:
showif item.droppable: #If the item is droppable, display the imagebutton
imagebutton:
# …
2)With a list comprehension
Alternatively, you could use
a list comprehension to enforce the droppable condition
on the list over which the loop iterates.
Instead of having the loop iterate over all items and check if
each item is droppable, we would have the loop iterate
only over the droppable items from the very beginning.
The list comprehension to use would be:
[item for item in container_trash.items if item.droppable]
This is basically a new list, but which contains only droppable items.
Then instead of having the loop iterate over
container_trash.items (all items), we would have the loop iterate over this list comprehension:
Code: Select all
screen container_trash:
for item in [item for item in container_trash.items if item.droppable]:
imagebutton:
# …
In this way, we do not use
showif at all: all the items in the loop are already droppable, they are filtered by the list comprehension.
3)Avoiding the loop if there isn't at least 1 droppable item
One last possibility is to avoid the loop entirely is there isn't at least 1 droppable item.
We would do so with a list comprehension again, but by storing it in a variable.
First, we use
the default statement to define a screen variable: that variable must contain only droppable items.
The list comprehension we have already used allows us to do just that:
[item for item in container_trash.items if item.droppable] is a list which contains only droppable items.
If there are no droppable items, or no items at all, that list will be empty.
Let's store it in a screen variable called
onlyDroppableItems:
Code: Select all
screen container_trash:
default onlyDroppableItems = [item for item in container_trash.items if item.droppable]
Since
onlyDroppableItems contains only droppable items, we can use it as a condition to display the loop only if the list is not empty.
At the same time, we can have the loop iterate over this same list!
Code: Select all
screen container_trash:
default onlyDroppableItems = [item for item in container_trash.items if item.droppable]
if onlyDroppableItems: #If it's not empty, then there's at least one droppable item
for item in onlyDroppableItems:
imagebutton:
# …
The index clause
One last thing! Whichever solution you end up using, consider adding an
index clause to the
for loop!
This is not a thing you normally see in Python code, it's exclusive to Ren'Py (and you need to have Ren'Py
version 7.0 or higher to use it).
Basically, the
index clause takes an expression that should be
unique to each item found in the list. It can be useful to prevent weird side effects if you have animations or changes in the screen (I
think you might need it since items can be dropped, but I'm not fully certain).
There are more details in the Ren'Py documentation on
the for statement:
If given, the index clause should consist of an expression that returns a hashable and comparable value that is unique for each row in the list. Ren'Py uses this value to make sure that transforms and other state wind up associated with the correct iteration. If you're seeing weird behavior when elements are added to or removed from a list you're iterating over, you might want to use an index clause.
In your case, the
name of the item (
item.name) is clearly the value to use in the
index clause.
It would be used like this:
for item index item.name in onlyDroppableItems
Of course, you would need to adapt the part with the iterable (
onlyDroppableItems) depending on which of 3 the solutions you chose to use!
If that last thing sounds too weird, don't worry about it.
But if you notice weird side effects in your screen someday (for instance an item turning into another item after dropping one), then consider adding this
index clause, it might fix your problem!