Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Moving widgets between cards while interacting with deck

A topic by silva joão created Apr 10, 2024 Views: 304 Replies: 8
Viewing posts 1 to 4
(+1)

Hello, IJ and Decker community!

I'll go straight to the point. I'm building an adventure game on Decker and I want the deck to be able to do the following:

1) Have a card that stores every item the player can get. In this game, items are draggable canvases. I'd say I already know how to do this.

2) Have another card that keeps track of what items the player has.

3) Obviously have gameplay cards.


4) Once in gameplay cards, I want the deck to know, at any given moment, which items the player has. I figure this can be done with a simple if statement regarding which thingstracking's checkboxes are true.

5) This is where I start not knowing very well what to do. Once the deck knows which items the player has, I want the gameplay cards to display that item.

6) And maybe this is the trickiest bit: I want the next card (gameplay2, for example) to display the item in same the position it was when the player left the previous card.

I tried a few solutions already but I'm fairly certain I'm doing many things wrong, so I won't burden this post any further with my failed attempts. Instead, have a cool image:

Thanks in advance! Decker is great!

(+2)

I actually figured it out. There really is something to be said about writing down your problems.

Here is the full system at work:

Letter people are saying their opinions about letters you show them. If anyone is interested, I can share my process later.

Developer (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!

Developer(+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!

(+2)

dropping in to say I love the mind boggling effect meme lmaoooo 😭 good luck on the development!

(+2)

decker is the future!