如何创建多个相同的命名容器,可以包含(并保留)不同的项目/数量

时间:2018-09-10 07:35:19

标签: javascript

所以...我以下面的方式创建了许多“项目”,这些项目在很多方面对我来说都很有效。实际上,我的大部分代码都基于这种结构(截断列表):

const items = {
  Pearls: {
    worth: 100,
    color: "white",
    use: // do something
  },
  Oyster: {
    pearlsInside: 6,
    something: "whatever"
  }
};

然后我有一个这样的球员清单:

const player = {
    someVariable: "thingamabob",
    inventory: [
    ]
};

当玩家从地面上找到牡蛎或珍珠时,我将该物品(名称字符串)推入玩家的“库存阵列”中,然后在幕后让他们访问/使用“项目对象”。

轻松自如,工作出色,但有一个问题……如果玩家在地面上发现两只牡蛎,捡起一只牡蛎,然后从里面取出3颗珍珠,然后又放回地面,如果玩家后来捡到上两个牡蛎,它们将现在有3颗珍珠(以前未捡起的牡蛎应该仍然有6颗珍珠。)

这对Pearls物品来说不是问题,因为它本身不是“容器”,可以说,地面上可能有一百颗Pearls,玩家可以将它们取走,使用并放下它们没关系...这就是说珍珠是珍珠,珍珠是珍珠,这对我来说是畅通无阻的。

但是当我进入那只牡蛎时,我意识到我将需要多个具有相同名称/类型的物品,并且它们能够容纳不同数量的珍珠。

请记住,玩家UI在所有情况下都只会将牡蛎称为牡蛎-例如,地面或库存永远不会在游戏“ Oyster1,Oyster2,Oyster666”中显示-而是“ Oyster,Oyster,Oyster”或“ 3牡蛎”。只有进一步检查,才能发现内容不同。

那么...为了实现“相同命名的容器”,我必须搞砸我当前的项目结构有多严重?

如果有帮助,我想这个问题的答案可以帮助解决-您如何在一个房间中使用2个相同的“手电筒”,但是每个电池都具有不同程度的电池电量-或-“您找到了四个金马驹1911年代,珍珠母握在地上”(每个夹子上装有不同数量的弹药)-或-(也许)您如何多次出现被简单地称为“胸部”的宝箱在游戏中,它们都包含各种战利品。

在这一点上,我觉得我的思维障碍更大,再加上担心我目前的物品/库存结构/系统走得太远,现在必须进行重大改进。

5 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解您的问题,但这可能会有所帮助。

如果您使用的是ES6(因为您使用的是 const 我想是),则可以使用Symbols

  

符号是ECMAScript 2015中JavaScript的新功能。符号是唯一的   和不变的原始值,可用作对象的键   属性。在某些编程语言中,符号是   叫做原子。有关更多详细信息,请参见Symbol和Symbol对象。   JavaScript中的包装器。

答案 1 :(得分:0)

我建议您对世界上的所有事物都使用ID。您可以给他们一个类型,每种类型都有一个显示名称和其他元数据,但是可以唯一地标识对象的每个实例。

如果需要生成ID的帮助,请尝试搜索GUID / UUID in Javascript

答案 2 :(得分:0)

用数组而不是对象表示集合。然后,您可以在该数组中包含同一项目的倍数。如果然后为每个项目赋予相同的属性,则可以轻松进行比较。要区分项目,请使用ID。

this.activatedRoute.queryParams.subscribe(params => {
  let data = params;
  console.log(data.mockup_id);
});

答案 3 :(得分:0)

这是Oyster和Pearl原型以及如何实例化它们的示例。

// Some helper functions
function randomNum(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

function randomColor() {
  var colors = ['white', 'blue', 'purple', 'yellow'];
  return colors[randomNum(3)];
}

// The Pearl prototype
function Pearl(worth, color, usageCallback) {
  this.worth = worth;
  this.color = color;
  this.use = usageCallback;
}
// Replace the default toString() function just for fun
Pearl.prototype.toString = function() {
	return 'A ' + this.color + ' colored pearl worth ' + this.worth; 
}

// The Oyster prototype
function Oyster(pearlsInside, something) {
  this.pearls = [];
  for (var i = 0; i < pearlsInside; i++) {
  	this.pearls.push(new Pearl(randomNum(100), randomColor(), function() {}))
  }
  this.something = something;
}
// Replace the default toString() function just for fun
Oyster.prototype.toString = function() {
	var description = 'The oyster contains ' + this.pearls.length + ' pearls: ';
  this.pearls.forEach(function(pearl) {
  	description += pearl + ', ';
  });
  return description;
}

// Here we instantiate our new objects
var oyster1 = new Oyster(6, 'Whatever');
var oyster2 = new Oyster(3, 'Whatever');

// And then we can use them
var container = document.getElementById('pearls');
container.appendChild(document.createTextNode(oyster1 + ''));
container.appendChild(document.createElement('br'));
container.appendChild(document.createElement('br'));
container.appendChild(document.createTextNode(oyster2 + ''));

// (or log them as strings)
console.log(oyster1 + '');
console.log(oyster2 + '');
<div id="pearls"></div>

答案 4 :(得分:0)

我当时想得太深了。

没有GUID / UUID,没有符号,没有超级魔术。

为同名对象生成唯一ID就像使全局函数(比游戏世界中每个对象的唯一ID更具全局性)一样容易:

function generateId() { return idid += 1; }

然后创建一个新项目,如下所示:

function create(){ var item = new NewItem( {id: generateId(), name: "Widget", power: 6, energy: 0} ); }

然后按如下方式推送构造函数:

function NewItem(item) { this.item = item; }

然后,将这些新创建的项目中的每一个作为具有大量属性的对象推入“世界上所有项目”数组中,以根据需要进行引用。

除其他事项外,这允许100个“小部件”在游戏中浮动,每个小部件具有不同的ID,这意味着随着游戏的进行,一个小部件可以具有能量:0,而另一个“小部件”可以具有能量:69。 >

完成并完成。关于下一个巨大的问题。...待续...