How do I combine items using an array?

0 favourites
From the Asset Store
With this template you will learn how to use the GooglePlay Games native plugin
  • Hi oosyrag,

    Thank you so much for this, it's extremely helpful and I think I'll be able to use this for the project. I'm still experimenting with it and have a couple of questions:

    Which json file is the item list one, as they both contain item lists?

    If there were duplicate items on screen, how could I ensure only one of each item has drag and drop enabled?

    Is there a (fairly) simple way of tweaking this so that item order doesn't matter, as it sounds useful but beyond my abilities to code at the moment?

  • items.json contains the item definitions, with "id", "dispName", "animName", "aniFrame", and "desc" keys for each item. recipes.json contains recipe definitions, with ingredients (an array of item ids), and result keys for each recipe. They're different in form and function, which is why I used two files. It works the same if they're all together like they were in the original example.

    On start of layout, the two files are loaded and placed into the "items" and "recipes" paths respectively, resulting in the exact same result as when it was just one file with items and recipes together. I've included that original file into the updated example (same link), if that way is preferable.

    What do you mean only one has drag and drop enabled? If there were two of the same thing, how should which one be draggable be determined?

    There are a few ways to ensure item (or recipe rather) order doesn't matter. The first way would be to not have conflicts to begin with. So don't have an A+B, B+C, or A+C recipe if A+B+C is a recipe.

    Another way would be to use a different trigger to check recipes, like a button the user has to push (after adding items to a pot or something), so that it's not triggered immediately upon dropping. But even then order still kind of matters, you would probably just want check the bigger recipes first before the smaller ones.

    You could also explicitly define a "priority" value in the recipe json, and check the recipes in order of their priority. But this is not much different than just leaving it as is - the priority is simply the order in which they appear in the recipe list.

    One option would be to just not worry about it, and let the player figure it out. If you had A+B=C and A+B+C=D, they would have to add A+C before B or B+C before A to get D.

  • Hi oosyrag,

    Many thanks for clarifying things. For the drag and drop, I was trying to make it so that only the first instance of an item could be dragged into (for example) a pot, and any identical items in the inventory would temporarily have drag and drop disabled until after a recipe was successfully created.

  • Example updated, see events 12-14. I didn't add a re-enabling event, but that depends on what triggers you want to turn dragdrop back on, like on craft complete, or if the item was dropped again without overlapping the pot. It would pretty much be pick all items and enable dragdrop. Or you can filter by item.id again, like when disabling - I saved the item id to a variable, and used that to pick which items I wanted drag and drop disabled.

  • Hi oosyrag,

    Maybe I'm doing something wrong but I can't find the link to the updated example. The previous link downloads the original example, which only has 10 events.

  • dropbox.com/s/j2oyalr4sc6b5ny/dragdropcraftingexample.c3p

    Sorry! Didn't realize I had two copies in my dropbox. Try this one.

  • Hi oosyrag,

    Many thanks for the link, it's been a big help.

    I've run into a problem with a variation of this setup where I collect items on another layout before combining them. I'm trying to store individual items' ID instance variables and current animations in an "inventory" array,

    but on moving to the combining layout, it either displays the correct animations or IDs, but not both. I expect I'm not using the right "push back" actions on the item collect layout (see below):

    I might not be using the correct "set to" actions on the combining layout either:

    I've tried "push back Item.AnimationName&Item.ID" but this sets all the items' IDs to "NaN".

  • Here's a visualization of what happens during an array pushing, see if it helps. When you push, you only push on the x axis, the other axis gets filled by whatever you pushed.

    docs.google.com/spreadsheets/d/1muTLyfKFaxD5WykJ2YoKYfg_lRQeuuABC5HwNi2t670/edit

    NaN means "Not a Number", which is what you get when you try to combine a string (animation name) with a number (ID), and try to put it into a number variable.

    I'm not sure about what's wrong with setting your items from the array, but maybe try again when your array is how you want it.

  • Thanks oosyrag. I eventually got it to work using push to front for the sprite animations and set value to (0,1) for the ID. I'd also forgotten to add ",1" after the CurX for the ID.

    One last thing. When I spawn items randomly on the item layout, is there a way to generate the correct ID instance variable for each item? So far all generated items have an ID of 0.

  • How are you spawning items randomly? When you spawn the item, you can look up what it is supposed to be from the json (or a dictionary or array list). Alternatively, you can just set the ID randomly first, then set the animation based on it's id instead (looking it up in the json again).

  • Hi oosyrag,

    This is the setup I'm currently using. The json file contains the id, animation name and description details for each item. Maybe I'm using "Get" wrong, as spawned items always have "0" for ID and the default animation. I tried setting a random ID but this only worked for the first item; the others IDs constantly cycle through 0-9 and the animation was still the default one.

  • Try this -

    The example has also been updated again (I hope!)

    Here I'm setting the item ID directly after creating the object (based on the number of entries in ".items" in the json file). Then, I loop through each ".items" in JSON to see which one matches the ID of the object I just created. If it matches, then set it to the animation to the ".animName" that is located in the same JSON entry that matches the ID.

    One alternate way you can work with JSON is that if the order of your objects in JSON is fixed, such that the index of the array matches the id of the object (Item ID 2 is at array index 2 of the ".items" array), you can look it up directly with a absolute path instead of a relative path. The path would be "items.2.animName". It's a string, so you can stick an expression in there with &.

    Item: Set animation to JSON.Get("items."&Item.ID&".animName") (play from beginning)
    

    If I were to do it this way in this case I would get rid of the "ID" key in the json completely, the index/position of the object becomes it's ID.

    Edit: I think a lot of your roadblocks are coming from the JSON object. It's a little less user friendly to work with than an array or dictionary. One of the biggest advantages of JSON it is that it can make it easy for end users mod your game if you keep data in an easily readable JSON file (or collaborators who are not familiar with construct/code in an open source project, for example). If you're the only one who is going to be working with it, it might make more sense to just use an array or dictionary directly. On the other hand, this kind of crafting system project is an excellent application of JSON, and a good way to learn how to use it.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Hi oosyrag,

    Thanks again for the link, I've finally got everything working.

    I'm in two minds about whether to stick with json as although it's been a good (though tiring) learning experience, I doubt anyone else will be working on this project other than me so arrays would be the better choice as I have a small amount of experience with them compared to json, which I'm completely new to, but have been struggling to work out what events to change in order to get the same setup working with arrays.

    Having said that, I think I've got enough to work with for now so switching to arrays isn't essential.

  • Just out of curiosity, would it be possible to make the above setup in Construct 2?

    I don't have much experience with it other than a few small test projects and installing a JSON plugin, but found I couldn't replicate the "floor(random(0,JSON.ArraySize(".items")))" action - I kept getting an "ArraySize is not a expression or instance variable in JSON" message.

  • Construct 2 didn't have a json plugin. I don't know about third party add ons and what they can do, I'm guessing they just didn't include the arraysize expression. Or it might be called something else, would need to check the documentation of the plugin.

    You can get a similar value and store it in a variable by using a "for each" at the path of the array, and add one to the variable in the for each event.

    If you're doing this in c2, I'd say just use an array, the array.asjson expression and load from json action. It's a little more cumbersome because you can't edit the project file directly in the editor in c2 either, but it should still work. I'll put together another example in c2 when I get a chance, it would double as an example for how to do this with arrays.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)