Reputation: 89
I have a shop in a browser p5js game.
It's not important, but let's say the shop consists of:
shopContents = { "Sushi": 5, "Boba": 6, "Watermelon": 3 }
I have used a for loop to create a button for each of these items. Is there a way to hide each button in the shop at the press of a "back" button (with a mousePressed()
function or something)?
I know it's possible to hard-code it with sushiButton.hide()
, bobaButton.hide()
, and watermelonButton.hide()
, but I think it would be ridiculous if this was the only way to do it, especially if the shop has more than a handful of items.
Since the buttons are dynamically generated, and there could be many buttons in the end, is there a way to just hide all of the buttons?
Edit:
This is the Shop.js class:
class Shop {
constructor() {
this.contents = {
"Burger": 5,
"Sushi": 10,
"Hotpot": 20,
"Boba": 6,
"Burrito": 5
};
this.items = ["Burger", "Sushi", "Hotpot", "Boba", "Burrito"];
}
}
This is the function I have in sketch.js
which creates the buttons:
function openShop(){
if (shop.items.length >= 1){
for (let i = 0; i < shop.items.length; i++) {
createButton(shop.items[i], shop.items[i])
.position(625, width/2-i*25)
.mousePressed(intermediateFunc(shop.items[i]));
}
}
}
function intermediateFunc(item) {
console.log(item)
return function() {
getPrice(item);
}
}
function getPrice(item) {
console.log(shop.contents[item])
}
Upvotes: 0
Views: 743
Reputation: 13283
Store the buttons as an array in the Shop
class, then iterate over all of them and run the .hide()
method.
class Shop {
constructor() {
this.contents = {
"Burger": 5,
"Sushi": 10,
"Hotpot": 20,
"Boba": 6,
"Burrito": 5
};
this.items = ["Burger", "Sushi", "Hotpot", "Boba", "Burrito"];
this.buttons = [];
}
}
function openShop() {
if (shop.items.length >= 1){
for (let i = 0; i < shop.items.length; i++) {
if (this.buttons.length > 0) { // if buttons are already made, just show them
shop.buttons[i].show();
} else {
shop.buttons.push(createButton(shop.items[i], shop.items[i])
.position(625, width/2-i*25)
.mousePressed(intermediateFunc(shop.items[i]));
);
}
}
}
}
function closeShop() {
for (let i = 0; i < shop.buttons.length; i++) {
shop.buttons[i].show();
}
}
However, you might want to use this style instead, since you're already using ES6+ classes:
class Shop {
constructor() {
this.contents = {
"Burger": 5,
"Sushi": 10,
"Hotpot": 20,
"Boba": 6,
"Burrito": 5
};
this.items = Object.keys(this.contents); // This will always be the keys of this.contents, so do this to reduce hardcoded duplication
this.buttons = this.items.map((itemName, idx) => {
return createButton(itemName, itemName)
.position(625, width/2 - idx*25)
.mousePressed(intermediateFunc(itemName));
});
}
open() {
this.buttons.forEach((button) => button.show());
}
close() {
this.buttons.forEach((button) => button.hide());
}
}
And I would also recommend better utilizing the constructor to allow for many kinds of Shop
s to be created without the contents
hardcoded:
class Shop {
constructor(contents) {
this.contents = contents;
this.items = Object.keys(this.contents);
this.buttons = this.items.map((itemName, idx) => {
return createButton(itemName, itemName)
.position(625, width/2 - idx*25)
.mousePressed(intermediateFunc(itemName));
});
}
open() {
this.buttons.forEach((button) => button.show());
}
close() {
this.buttons.forEach((button) => button.hide());
}
}
// Instantiate like this:
const shop = new Shop({
"Burger": 5,
"Sushi": 10,
"Hotpot": 20,
"Boba": 6,
"Burrito": 5
});
// open shop
shop.open();
// close shop
shop.close();
Upvotes: 2