Announcement

Collapse
No announcement yet.

Inventory Demo

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Inventory Demo

    Hey,

    I am using the Inventory Demo as reference for a UI I am making. But I am not understanding some stuff.

    I understand that you set the type in this code.

    Code:
    var itemData:Object = [
    	{type:"armor",asset:2},
    	{type:"weapon",asset:3},
    	{type:"spell",asset:4},
    	{type:"spell",asset:5},
    	{type:"wand",asset:6},
    	{type:"spell",asset:7,quantity:7},
    	{type:"spell",asset:8},
    	{type:"spell",asset:9,quantity:3}
    ];
    But in the demo there is an inventoryslot that ahs the value of "Shield" in the "DragEccepTypes" property. But this shieldtype is not in the previous code and I can't find it elsewhere in the code. Where is this shield type code?

    My other problem is that I want to prevent that a row of inventoryslots can switch of icons. I tried to set every inventoryslot with there own type. But then I can only move the first 2 inventoryslots to an other row of inventoryslots and the other one not. Here are 2 screens to make it clear.

    The goal is to have a row with nodes that I can move to the row above. But The row on the bottom may not interchange nodes.

    This first one works.


    The last one doesn't.


    All the inventoryItems on the top row have the * value.
    The bottom row have there own type.

    #2
    The 'shield' type does not exist, but was put as an acceptable drag type. You could easily add it, but the demo works without it.

    What is happening in that demo is that 8 items are arbitrarily created and stored in the 'itemData' object. Each item has a type (armor, weapon, spell, etc.) and each item has a unique asset number assigned to it (2, 3, ... 9). Some have a quantity. This is done in the 'demoComponents' movieclip timeline.

    If you then go into the 'panel' movie clip, you will see the 8 inventory slots. These slots are instances of 'InventorySlot'. You will find this class in the \Development\Flash\CLIK\gfx\controls\ directory. InventorySlot extends DragTarget (found in the same directory). And both make use of DragManager. DragManager is found in the \Development\Flash\CLIK\gfx\managers\ directory. You'll want to load up these class and be sure you understand what they do.

    Now, each slot has an instance name of: slotn (slot0, slot1, ... slot8)

    In the actions keyframe of this movie clip ('panel'), you can see that a for loop sets the data for each inventory slot arbitrarily based on the contents of the 'itemData' object that was created in the previous (parent) movie clip. This is a hack for the demo. In a live game, you'll want to populate your inventory in a more correct and dynamic way.

    Code:
    for (var i:Number = 0; i<8; i++) {
        this["slot"+i].data = _parent.itemData[i];
    }
    So, slot0 will hold the 0 element of _parent.itemData - which happens to be asset 2 (type: armor). And slot1 will hold the 1 element of _parent.itemData - which happens to be asset 3 (type: weapon). And so on. This is just an arbitrary way to populate the slots, but the key thing to notice here is the asset #.

    If you drill down into any one of the inventoryslot movie clips (slot0 for instance) , then drill down again into the 'icons' movie clip, you will see it has 9 frames. On each frame is an icon for an inventory item. Frame 2 has the armor. Frame 3 has a sword. These frames match up exactly with the 'asset' values. If you recall, asset 2 was type: armor. So, if you wanted to add a shield icon to frame 10, that would mean you would add asset 10 as type: shield to itemData, and of course you would need to change the for loop to test for i<9 instead of i<8. (0 to 9 = 10 total assets)

    Checking the dragAcceptTypes parameter in the component inspector for the inventoryslots (slot0, etc.) in this panel, we see they are all set to * - meaning anything can be dragged there.

    Go back out to the demoComponents movie clip and this time go into the paper doll inventory window. Checking the component inspector of these InventorySlots (on the paper doll), we see that the top slot allows only armor, and the side slots allow either a weapon and wand or a shield and wand. The bottom slots are instances of ItemSlot, not InventorySlot, and allow only spell or usable. I can change the dragAcceptTypes to * for one of the slots, and I can then drag anything to it.

    So - put shortly:

    The asset value = the frame # of the icons movie clip, where the image for that asset is stored. (armor, weapon, shield, etc.)
    The type value is used to specify whether an inventory slot will accept that asset. (specified by its dragAcceptTypes parameter)

    Unfortunately, I don't know what is wrong with your version, as I don't know what your code looks like, or what your Flash file setup is like, but the actual Scaleform Inventory Demo can be modified and works as expected.

    Comment


      #3
      Thank you very much for your fast reply. I appreciate this.

      It helped

      I hope you don't mind I ask some other questions.

      I want to make an instance of the icon when I drag one from an inventoryslot
      I tried this :

      Code:
      /*slot0_mc.dragBegin = function(){trace("This drag works!!")};
      But when I do this, the inventoryslot gets disabled.

      Would you mind helping me in the right direction pleas?

      Comment


        #4
        InventorySlot (the class) is a subclass of DragTarget. Inside DragTarget, the function configUI() adds dragBegin and dragEnd as event listeners to these slots. When the event dragBegin occurs, it fires off the function dragBegin() found in DragTarget.

        Now, I moved your trace statement inside this function at the bottom, and it worked properly. The trace statement occurs (multiple times however - couldn't tell you why), and the original inventory slot is not disabled. Here is the code from DragTarget as I modified the class. The last command is your trace statement:

        Code:
        private function dragBegin(event:Object):Void {
            if (!allowDrop(event.data)) { return; }
            trackAsMenu = _visible = true;
            gotoAndStop("up");
            gotoAndStop("dragUp");
            trace("This drag works!!");
        }
        However, you could also put the trace statement inside the onPress() function that lives in InventorySlot, and it will work just as well, and will only fire once.
        Code:
        private function onPress(controllerIdx:Number):Void {
            if (_data == null) { return; }
            Selection.setFocus(this, controllerIdx);
            icons._alpha = 20;
            dragOrigin = true;
            DragManager.instance.startDrag(this, "icons", data, this, icons).gotoAndStop(_data.asset);
            trace("This drag works!!");
            _data = null;
        }
        So, long story short - you're going to want to modify the class for your needs, rather than trying to do code in the Flash timeline. Otherwise, you're going to break things.

        Now - if you comment out the line _data = null in onPress(), you will in fact create an instance after dragging an object to a new slot, because this one line of code in onPress() tells the inventory slot you just dragged from to be made empty, once the function update() executes. Notice in update() it checks the value of _data. If it is null, then it sets that inventory slot (represented by _data) to frame 1, which is the empty icon slot.

        Code:
        //_data = null;
        But this is a hack that you don't want to use, as it creates an instance of the object in every inventory slot you drag from infinitely. So you're going to need to figure out how to make it work only in a specific instance - probably with an if statement of some kind.

        Take this example 'if' statement I just added to the onPress() function:
        Code:
        private function onPress(controllerIdx:Number):Void {
            if (_data == null) { return; }
            Selection.setFocus(this, controllerIdx);
            icons._alpha = 20;
            dragOrigin = true;
            DragManager.instance.startDrag(this, "icons", data, this, icons).gotoAndStop(_data.asset);
            if (_data.quantity == 1 || _data.quantity == null) {
                _data = null;
            }
            else {
                _data.quantity -= 1;
            }
        }
        This code checks to see if a dragged item has a quantity of 1 or null. If it does then it clears the data and does not allow an instance to be created. But if the quantity is higher than 1, when you drag the item to a new slot, it will leave behind an instance with a quantity of 1 less than before. The only problem with this code is that it does not give the correct quantity of the new instance that was dropped in another slot, but it illustrates the point I'm making.

        What I would do is create a new subclass of InventorySlot - something along the lines of MyInventorySlot. Or I would just modify InventorySlot. Then I would modify it to my hearts content. Any function I wanted to modify from DragTarget (such as dragBegin()) I would override by copying it into my subclass and modifying it there.

        Comment


          #5
          Matt Doyle, you are great!

          Thanks for the help.

          Comment


            #6
            No problem. Be sure to reread everything I wrote, as I've made considerable edits while investigating your scenario. Also bear in mind that my recommendations may not be the best way to do what you want. You may need to alter other functions instead. I'm just trying to show you how it could be done and how the whole thing is put together.

            Comment


              #7
              Wow, I just read through this, I'm very impressed with your replys Matt. Its nice to see this, I'm just starting to work on my invertory, and I'm going to be much better off after reading this.

              Comment


                #8
                A little side question. Does the swf file also also to be like 1024*512 or ... ?

                Comment


                  #9
                  Any size will work technically with SWFs, but using power of 2 on all images within the SWF is a must.

                  Comment


                    #10
                    I hope you don't mind I put all my questions in this topic.

                    I want to test my UI out in udk, but I am not sure how achieve the "Dead space" result.
                    In your tutorial you show how to use the swf on a bsp. But how can I achieve it like in dead space ?

                    Was this just projected on a plane or is there a specific method to do this?
                    And how did they set focus on the wpf so there is a mouseInput?

                    Already thanks for your help. I appreciate it.

                    Comment


                      #11
                      You're going to want to look at the 3D inventory tech demo file: GFxProjectedUI.uc for all the 3d rotation stuff - as well as the HUD wrapper class (UTGFxHudWrapper.uc) where the inventory screen is toggled on/off.

                      In our original tech demo, the player is put into 3rd person mode, and his head follows the inventory selection as you make selections, but it doesn't do that anymore.

                      I didn't built that tech demo, so I couldn't tell you exactly how that was done, but my best advice to you is to review those script files.

                      Comment


                        #12
                        Well, Matt, not to hijack this thread, but this was the straw that broke the camel's back.
                        I have officially made a bookmark folder called "Matt's Gems" because I had so many bookmarks of your responses to questions.

                        I hope you hear this all the time, but just in case you don't, you are doing an incredible job with support in these forums. I have worked with many 3rd party APIs in different game engines, and never have I seen support of this caliber. Thanks again, your responses in this thread could be made into a tutorial by themselves.

                        When I start working on the UI for my project again, I might just make a video explaining the Inventory demo based on your comments, if that's cool with you.

                        Comment


                          #13
                          Is there any reason for hiding the labels and actions layer in a flashfile? And when a file is hidden, is it still exported and read by the compiler?

                          Comment


                            #14
                            By hidden I assume you mean setting a layer to be a guide layer? If so, that layer is not compiled into the SWF file.

                            Comment


                              #15
                              No, just pressing on the dot under the eye so if there is content in the layer that it becomes unvisible. I was just checking the flashfiles and noticed some layers were hidden and one of those were an action and label layer. I was wondering of this had any special meaning?

                              Comment

                              Working...
                              X