Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
(1 edit) (+1)

Aha, so you're trying to do something like the Shadowgate inventory system?

There are a few ways to approach this. One way would be to use card.copy[] and card.paste[] to duplicate several widgets from one card to another, and then card.remove[] to get rid of the originals.

We'd need this to happen whenever we change cards, from anywhere in the deck; the easiest way to make this happen is to override the "go[]" function in a deck-level script. We'll want to special-case navigating to the card we're already on, since this idiom is used for some kinds of animation.

It will also be convenient if we have an easy way of identifying the widgets on a card that are items. We could search the current card for any canvas that is draggable, but a naming convention might be less error-prone: I'll name each item-canvas with an "item_" prefix for this example. For card transitions to look correct, we need to add the copied widgets to the destination before the transition starts, and to remove the originals after the transition completes.

We might define a deck script something like:

on go dest trans delay do
 if !"card"~typeof dest dest:deck.cards[dest] end
 if dest~deck.card
  send go[dest]
 else
  s:deck.card
  i:extract value where value..name like "item_*" from s.widgets
  c:s.copy[i]
  dest.paste[c]
  send go[dest trans (30 unless delay)]
  each item in i s.remove[item] end
 end
end

In action:


This solution comes with some important caveats. For one thing, the deck-level definition won't apply to calls to go[] fired from within modules or contraptions. You will also probably want to override the default navigate[] event handler. This solution relies on the simplifying assumption that the first argument to go[] is a card name or card interface; if you want to be able to navigate by index or with special names like "Next" or "First" or open hyperlinks you'll need to do some more work.

Does that help?

(+1)

Nice, thank you so much!

I didn't know about Shadowgate, I loved the way it looks :) I barely knew about Hypercard when I came across Decker here on itch. It's great to see the original stuff.

I kept trying different approaches and arrived at the card.copy[]/paste[] solution by myself; but yours obviously is more elegant and will save me a lot of time.

I'll give this a go!!

(1 edit)

IJ, once again I'm in need of guidance. 

I have a question regarding the rect module. I'll ask here to avoid creating new posts:

is there a way to have to use rect.constrain to keep a draggable canvas outside of a container instead of inside? I wanted to create backgrounds with "pseudo-collision", for example, making it impossible to drag your character onto a table or keeping the character within odd-shaped spaces. 

In the following image, I drew an X over areas I want to keep the draggable character away from.


Thank you!

(+1)

Constraining an object within a concave shape while dragging is a rather difficult problem. You can easily construct examples that have no single "closest valid location"


In the general case I think this would probably require some kind of iterative solver.

If all you care about is the destination, you could use several calls to rect.overlaps[] to see if the player object overlaps any obstacles and "snap back" as demonstrated in the examples.

I see! 

Thank you for answering; the snap back workaround will do just fine!