Skip to main content

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

Is there ANY way to resize an internal canvas(es) on a contraption resize?

If you make your prototype “resizable” (when you’re editing a prototype, from the “Prototype” menu make sure the last item “Resizable” is ticked), then you should be able to resize the contraption when you add it to a card. If you also tick “Show Margins” in the Prototype menu, you’ll also get four little handles you can use to mark the left, right, top and bottom margins of the prototype: any part of a widget that is between the edge of the prototype and the margins will stay at that fixed distance from the edge, any part of a widget that is in the middle will be proportionally resized as the contraption is resized.

%%WGT0{"w":[{"name":"prototype11","type":"contraption","size":[98,91],"pos":[86,66],"def":"prototype1","widgets":{"canvas1":{"size":[81,41]}}}],"d":{"prototype1":{"name":"prototype1","size":[100,100],"resizable":1,"margin":[0,25,0,0],"widgets":{"canvas1":{"type":"canvas","size":[83,46],"pos":[8,9]}}}}}

If you paste the above widget definition into a card, you’ll get a contraption with a canvas in the top half of it. The top edge of the canvas is between the top edge of the prototype and the top margin, so it stays at a fixed distance from the top of the contraption as it is resized. The bottom edge of the canvas is between the top and bottom margins, so it moves proportionally as the contraption is resized.

If you are trying to write code to reposition widgets in a deck, that should work, but it may be overidden by the “built in” resizing behaviour described above? I’m not sure, I haven’t tried it.

But, then that raises another question, I am uncertain where to initialize long term state on a card or contraption.

The best place to put long-term state on a card or contraption is in a widget. Widgets don’t have to be in the centre “white” part of a prototype, you can stash them in the dark-grey border area - but make sure they’re locked so the user can’t accidentally interact with them. For most data types (numbers, strings, lists, dicts, tables) you can just use a regular field, and read and write its .data property. If you want to store a bunch of images (such as sprites), the best way is to use a rich-text field; you can paste the images in, and access them from code by reading the .images property.

Also, is there a working example of get_ and set_ for prototypes?

If you edit a prototype and choose “Script…” from the Prototype menu, you can enter a handler like this:

on get_foo do
 "here's a foo"
end

Then, let’s say you make a contraption from this prototype, called mycontraption. If you say mycontraption.foo, that will evaluate to the string "here's a foo". Here’s a pasteable example of that in action:

%%WGT0{"w":[{"name":"mycontraption","type":"contraption","size":[100,100],"pos":[86,66],"def":"prototype1","widgets":{}},{"name":"button1","type":"button","size":[84,20],"pos":[93,40],"script":"on click do\n alert[mycontraption.foo]\nend","text":"Gimme a foo"}],"d":{"prototype1":{"name":"prototype1","size":[100,100],"margin":[0,0,0,0],"script":"on get_foo do\n \"here's a foo\"\nend","widgets":{}}}}

Setting works the same way: define on set_foo val do ... end and it will be called when code does mycontraption.foo:somevalue.

If you want to be able to get and set values interactively, rather than just through code, you can also use “attributes”, but that’s an optional, additional layer on top of get_foo and set_foo that you don’t have to worry about otherwise.

(1 edit)

Thanks, I’ll try these.

As for the resizing widgets and what you’ve said, my gut is that it might be being overridden by the internal resizing logic, I’m not sure really.

What I have experienced is that I have them offscreen, since they are acting as compositing buffers. The “resize event” works fine, as it is triggered by some code that is being run in an animated widget - ONLY when it’s in the prototype view. As soon as an instance of the prototype becomes a contraption instance, all of that code stops working. The canvases will not resize anymore.

Also, thanks for the confirmation on the state. I kind of figured it was like Pd (Pure Data) and it would go in a widget, like how Pd does it.

(+1)

If you can provide an example contraption that exhibits the behaviour you describe, that would help. If you can set it up in a new deck, you can select the contraption, do Edit → Copy Widgets, and then paste the result into a reply here. That’s what I did to create the examples in my reply - if you copy a contraption, Decker even includes its prototype.

(+1)

Thanks for the offer, but I’ve decided on another route.

I’m doing what I wanted through modules, deck.add, etc. That does work for me and it’s clearer to me what’s happening.

It’s more work for me to avoid the prototype/contraption interface, but that’s how it goes.

(+2)

I figured out what the problem was. I didn’t realize you needed to call card.update[] when changing subordinate widget sizes.

Actually, no - that wasn’t it.

Anyways, I’ll have the contraption done soon, but I think I am running into a corner case where it doesn’t like resizing when a canvas is beyond the boundaries or something. The clipping gets to be incorrect and things start wrapping even though I explicitly set the sizes of the canvas and clip.

(1 edit)

I figured it out. I don’t know if it’s a bug or a limitation, but it’s easy to reproduce:

A prototype/contraption background image will not resize itself. It is fixed, no matter what. For instance, if I make a prototype at (200,200) and then resize it, the image is fixed. It also causes strange compositing errors near the edge of the contraption if I am actively drawing into it.

To get around it, I will have to use another canvas as the background image, rather than the contraption’s image - because they should be resizing themselves, obeying the margins. The prototype’s/contraption’s card does not, and is permanently fixed size.

Also, maybe I am abusing the use of the prototype/contraption base image and it is not supposed to be drawn into during interaction.

(+1)

Ah, yeah. The “margins” of a prototype also divide up the prototype background into a 3x3 grid. When a contraption is resized: the top-left tile of the prototype is drawn at the top-left corner of the contraption; the top-centre tile of the prototype is tiled horizontally across the top of the contraption; the top-right tile of the prototype is drawn at the top-right corner of the contraption, and so forth.

The default introduction/tutorial deck you get when you launch Decker has a page on “contraptions”, and one of the examples is a “resizable decorative border” contraption that demonstrates the behaviour nicely.

If you want to draw the background with code, you’ll need a canvas widget if only because the Image protocol you get from card.image doesn’t provide a lot of drawing primitives. You can use a “hidden” canvas widget, draw the background you want, then do card.image:canvas.copy[0,0 canvas.lsize] to paste it onto the contraption background, or (much easier) just make the canvas widget cover the area of your prototype, and Decker’s default resize behaviour (with the margins and such) will make sure it stays in place as the contraption is resized.

(2 edits) (+1)

That’s exactly what I do, except the problem is the base image of the prototype/contraption will be fixed. If I resize the contraption, and the image started at (200,200) after instantiation, it remains at (200,200). It cannot be changed. I’ve tried on view or a subordinate widget that tries to resize it - it stays fixed.

Then, when I composite the subordinate canvases into it, and the contraption is resized, the image will wrap. The image will not resize itself and I can’t force it to resize.

The only way I have gotten around this is by maximizing the card on the prototype page so it starts with a very large image buffer, and then shrink it on view, when it’s actually instantiated. Except, that has problems, too.

So, I figure the only real fix is to not draw on the prototype’s/contraption’s base image, but on a canvas, and show the canvas.

Yep - it works now. It’s either a bug or limitation.

  • If the final target of the composite is the prototype/contraption card image, there are compositing errors and it (the image attached to the prototype/contraption card) will never resize.
  • If I use a “visible” canvas as the target, it does resize and all compositing errors go away.