为什么我的自动RPG库存网格不起作用?

时间:2014-06-15 18:05:13

标签: c# xna xna-4.0

这是我的情况。我有四个类:Inventory.cs,InventoryTab.cs,ItemDatabase.cs,BaseItem.cs(以及一些从BaseItem派生的项目,如武器,消耗品等)

库存创建新的InventoryTabs(消耗品,武器,护甲),每个InventoryTab都有一个BaseItem列表。

然后调用

Inventory.AddItemByID(int ID, int Amount),它会检查ItemDatabase.cs的ID,并在游戏开始时将项目预先加载到列表中。

好的,现在你已经掌握了我的库存运行的基本信息,这里是我的问题:

在InventoryTab中:

int Column, Row; //Declared at the top of the class

for (int i = 0; i < ItemList.Count; i++)
{
    Column++;
    if (Column > gridSize.X)
    {
        Column = 0; Row++; //Row is not limited because my inventory will be unlimited in height
    }

    ItemList[i].gridLocation = new Point(column, row);
}

虽然我认为这样可行,但它会在顶部创建一个项目,然后快速跳到右侧,然后向下跳过一行,然后重复。如果我通过KeyboardState添加更多项目,它会闪烁大量项目,然后消失。

我确定它是因为它在一个循环中分配了gridLocation的值,但是我再也不知道如何以任何其他方式解决它。

我需要做的是只在ItemList中为每个BaseItem分配一次gridLocation。

编辑:

InventoryTab.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace InventoryEngine
{
    public class InventoryTab
    {
        public List<BaseItem> ItemList = new List<BaseItem>();

        int itemSize; //In Pixels
        Point gridSize = new Point(5, 4);
        int LocY, Column, Row;
        public float Scale;

        //Region Clipping
        Rectangle scissorRect;
        RasterizerState rState = new RasterizerState()
        {
            ScissorTestEnable = true
        };

        Vector2 gridOffset;

        Texture2D slot;
        SpriteFont sf;

        MouseState ms;

        public void LoadContent(ContentManager c, GraphicsDevice g)
        {
            ItemDatabase.LoadItemData(c);

            slot = c.Load<Texture2D>("inventory_slot");
            sf = c.Load<SpriteFont>("SpriteFont1");

            Scale = 4.0f;
            itemSize = 32 * (int)Scale;

            gridOffset = new Vector2(g.Viewport.Width / 2 - (itemSize * gridSize.X / 2), g.Viewport.Height / 2 - (itemSize * gridSize.Y / 2));
            LocY = g.Viewport.Height / 2;
        }

        public void Update(GameTime gt, GraphicsDevice g)
        {
            ms = Mouse.GetState();

            LocY += ms.ScrollWheelValue / 10;

            if (LocY >= g.Viewport.Height / 2 - 252)
                LocY = g.Viewport.Height / 2 - 252;

            for (int i = 0; i < ItemList.Count / 1; i++)
            {
                Column++;
                if (Column > gridSize.X)
                {
                    Column = 0; Row++;
                }

                ItemList[i].gridLocation = new Point(Column, Row);
            }

            foreach (BaseItem item in ItemList)
            {
                item.UpdateValues(gridSize, itemSize, gridOffset, LocY);
            }
        }

        public void DrawTab(SpriteBatch sb, GraphicsDevice g)
        {
            scissorRect = new Rectangle((int)gridOffset.X, g.Viewport.Height / 2 - 256, gridSize.X * itemSize, gridSize.Y * itemSize);

            sb.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, rState);
            //g.ScissorRectangle = scissorRect;

            foreach (BaseItem i in ItemList)
            {
                sb.Draw(slot, new Vector2(i.itemRect.X, i.itemRect.Y), new Rectangle(0, 0, 32, 32), Color.White, 0, Vector2.Zero, Scale, SpriteEffects.None, .95f);
                sb.Draw(i.Icon, new Vector2(i.itemRect.X, i.itemRect.Y), new Rectangle(0, 0, i.Icon.Width, i.Icon.Height), Color.White, 0, Vector2.Zero, Scale, SpriteEffects.None, .95f);
                //if (i.currentAmount > 1)
                    sb.DrawString(sf, "" + i.currentAmount, new Vector2(i.itemRect.X, i.itemRect.Y), Color.White, 0f, Vector2.Zero, Scale, SpriteEffects.None, .95f);
            }

            sb.End();
        }
    }
}

BaseItem.cs:

using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace InventoryEngine
{
    public class BaseItem
    {
        public Texture2D Icon;
        public string name;
        string description;
        public int id, currentAmount, maxAmount;

        public enum TabType { Consumable, Weapon, Armor, Ammo, Jewellery, Resources, Misc }
        public TabType tabType;

        public bool isSelected, isUsable;

        public Vector2 positionOffset;
        public Point gridLocation;
        public Rectangle itemRect;

        public BaseItem(Texture2D IconName, int ID, string Name, string Description, int MaxAmount, TabType TabType)
        {
            Icon = IconName;

            id = ID;

            name = Name;
            description = Description;

            maxAmount = MaxAmount;

            tabType = TabType;
        }

        public void UpdateValues(Point GridSize, int itemSize, Vector2 GridOffset, int OffsetY)
        {
            currentAmount = (int)MathHelper.Clamp(currentAmount, 0, maxAmount);

            itemRect = new Rectangle(gridLocation.X * itemSize + (int)GridOffset.X, gridLocation.Y * itemSize + OffsetY, itemSize, itemSize);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

使用@deathismyfriend,您可以在每个位置运行嵌套for循环:

int pos; //Declared at the top of the class

pos = 0;
for (int x = 0; x < gridsize.X; x++) // x represents column
{
    for (int y = 0; y < ItemList.Count / gridsize.X; y++) // y represents row
    {
        // In the above (ItemList.count / gridsize.X) = number of rows needed
        ItemList[pos].gridLocation = new Point(x, y);
        pos++;
    }
}

应该做你想要的。

莫纳