Powtarzalność w kodzie

0

Siema robię sobie gierke typu clicker po przerwie z js. Mam taka zagwozdkę ponieważ po utworzeniu jakby takiego "core'a" aplikacji później nowe itemy muszę dodawać tak samo jak poprzednie tylko zmieniam cyferkę w górę żeby odpowiednią tablice wczytało. I np. tutaj to się tylko różni, że do innego elementu podpinam zdarzenie i cyfrą w górę w tablicy. Macie może jakiś pomysł żeby to ulepszyć , albo od innej strony ugryźć ? Na dole załączam kod.

// ITEMS
firstItem.addEventListener('click',()=>{
    if(gameMoney.money > items[0].price) {
        gameMoney.money -= items[0].price;
        items[0].amount++;
        items[0].price += 10;
        gameMoney.moneyPerClick++;
    } else {
        alert("Masz za malo pieniedzy");
    }
});

secondItem.addEventListener('click',()=>{
    if(gameMoney.money > items[1].price) {
        gameMoney.money -= items[1].price;
        items[1].amount++;
        items[1].price += 20;
        gameMoney.moneyPerClick += 2;
    } else {
        alert("Masz za malo pieniedzy");
    }
});

Albo to

setInterval(()=>{
    gainedMoney.textContent = gameMoney.money;
    moneyPerSecondInfo.textContent = gameMoney.moneyPerClick;
    itemPriceFirst.textContent = `Koszt: ${items[0].price}`;
    itemAmountFirst.textContent = `Ilosc: ${items[0].amount}`;
    itemPriceSecond.textContent = `Koszt: ${items[1].price}`;
    itemAmountSecond.textContent = `Ilosc: ${items[1].amount}`;
},1000);

https://jsfiddle.net/k0thby4d/1/

4

Stwórz funkcję przyjmującą parametry.

0
Dantheeq napisał(a):

Stwórz funkcję przyjmującą parametry.

Coś w ten sposób ?

const test = (arrayLength,amount,price,mpc) => {
    if(gameMoney.money > items[arrayLength].price) {
        gameMoney.money -= items[arrayLength].price;
        items[arrayLength].amount+=amount;
        items[arrayLength].price += price;
        gameMoney.moneyPerClick += mpc;
    } else {
        alert("Masz za malo pieniedzy");
    }
}
// ITEMS
firstItem.addEventListener('click',()=>{
    test(0,1,10,1);
});
1
const test = (item) => {
    if(gameMoney.money > item.price) {
        gameMoney.money -= item.price;
	item.amount += 1;
	item.price += item.pricePerUpdate
        gameMoney.moneyPerClick += item.mpc;
    } else {
        alert("Masz za malo pieniedzy");
    }
}

let items = [
	{"id": 1, "name": "Item first", price: 20, pricePerUpdate: 10},
	{"id": 2, "name": "Item first", price: 20, pricePerUpdate: 10},
]

function getItemById(ItemId){
	// return item
}

$(".item").addEventListener('click',()=>{  // korzystamy z klasy .item czyli każdy przyciski item 
	let itemId = $(this).data("id");
	let item = getItemById(itemId);
	test(item);
});

Coś w tym stylu bym dał, jest to tylko szkic

0

Coś w tym stylu bym dał, jest to tylko szkic

Ale to jest jQuery a ja w vanilla js chce to zrobić.

0

Przecież to tylko szkic, chodzi o koncepcje, w czystym js możesz to zrobić prawie identycznie

0

No ok tylko jest jakiś odpowiednik tego data() ?

1

https://stackoverflow.com/questions/15912246/access-data-attribute-without-jquery

Np. tak. Tylko, że nie wiem czy w najnowszym javascripcie nie ma jakiejś lepszej metody, no ale to w każdym razie zadziała.

A na przycisku ustawiasz to tak np.: <button class="item" data-id="123">Kup Maczugę</button>

0

Znalazłem, że jest coś takiego jak dataset i to pobiera. I jakoś to wyszło ale trochę zabawy było :D. Finalnie tak to wygląda :

const itemBtn = document.querySelectorAll('.item-btn');
let items = [{
        id: 1,
        name: "Create report",
        price: 10,
        amount: 0,
        mpc: 1
    },
    {
        id: 2,
        name: "Sell product",
        price: 150,
        amount: 0,
        mpc: 2
    }
];
const test = (item) => {
    if(gameMoney.money > items[item-1].price) {
        gameMoney.money -= items[item-1].price;
        items[item-1].amount += 1;
        items[item-1].price += 10
        gameMoney.moneyPerClick += items[item-1].mpc;
    } else {
        alert("Masz za malo pieniedzy");
    }
}
itemBtn.forEach(e =>{
    e.addEventListener('click',()=>{
        let itemId = e.dataset.id;
        test(itemId);
    })
})
0

Moim zdaniem jednak funkcja getItemById znacznie poprawi czytelność. Teraz odnosisz się do indeksu tablicy co powoduje gorszą czytelność i słabszą jakość. Np. nie możesz wykreślić środkowego itemu bo będziesz musiał przerabiać wszystkie ID. Przyciski tworzysz na podstawie tablicy items czy masz na sztywno w kodzie? Jeśli na sztywno to ciężko będzie potem coś modyfikować jeśli nie korzystasz z ID

0

Nie no przyciski mam na sztywno w html'u ale ta funkcja mi zwracała tylko id dlatego pomyślałem , że jest bezużyteczna. Teraz jak dodam sobie 3 element normalnie zadziała bo pobieram przecież wszystkie przyciski i z każdego po clicku id jego przesyła. Chyba , że coś innego masz na myśli.

3

Dodaj sobie item o id 3. Pograj sobie w gierkę. Stwierdź, że trzeba usunąć item 2. I teraz musisz zmienić ID itemu trzeciego. Przy dwóch itemach to nie problem. Gorzej jak masz tych itemów np. 20

No i funkcja powinna przyjmować item a nie jego ID

2

zmień:

let items = [{
        id: 1,
        name: "Create report",
        price: 10,
        amount: 0,
        mpc: 1
    },
    {
        id: 2,
        name: "Sell product",
        price: 150,
        amount: 0,
        mpc: 2
    }
];

na

let items = {
        '1': {
          name: "Create report",
          price: 10,
          amount: 0,
          mpc: 1
        },
       '2': {
        name: "Sell product",
        price: 150,
        amount: 0,
        mpc: 2
    }
};

i będziesz się mógł odwoływać do elementów po kluczu items[1], zamiast ich szukać lub polegać na indeksie odejmując 1.
Poza tym jak wyżej wspomniano, elastyczniej i ładniej by było przekazać item a nie jego id. Poza tym po co Ci w ogóle jakieś numerki tutaj? Kluczem może być nazwa elementu w clickerze, nie musisz nadawać tutaj żadnych sztucznych idków.

Ostatnia wskazówka - staraj się nie tworzyć funkcji w pętli:

itemBtn.forEach(e =>{
    e.addEventListener('click',()=>{
        let itemId = e.dataset.id;
        test(itemId);
    })
})

ten kod można zastąpić takim:

function itemClick() {
  let itemId = this.dataset.id;
  test(itemId);
}

itemBtn.forEach(e => e.addEventListener('click', itemClick));

Tutaj tworzysz funkcję raz i tylko ją przypinasz. W Twoim przypadku utworzone by było tyle funkcji ile masz przycisków, każda funkcja miałaby własny closure przetrzymujący zmienną "e". Ogólnie dużo więcej zużytej pamięci i czasu jeśli tych przycisków byłoby dużo. Może akurat w tym przypadku gdzie masz zaledwie parę przycisków nie ma to dużego znaczenia ale taka rada na przyszłość

0

Teraz to już mam mętlik w głowie i nie wiem co zrobić, z tego co zrozumiałem to teraz do tego muszę zrobić żeby do funkcji test() przechodził jeden z obiektów items żebym w funkcji test nie musiał robic np. items[item].price to tak naprawdę te data-id, które robiłem w html'u nie jest mi w ogóle potrzebne. Bo teraz to nie działa bo przekazuje jedno właśnie z tych id. i przez to w funkcji test jest np 1.price. Tylko nie wiem jak zrobić funkcję, która będzie mi zwracać jeden z tych obiektów własnie.

const itemBtn = document.querySelectorAll('.item-btn');
let items = {
    '1': {
      name: "Create report",
      price: 10,
      amount: 0,
      mpc: 1
    },
   '2': {
    name: "Sell product",
    price: 150,
    amount: 0,
    mpc: 2
}
};
const test = (item) => {
    if(gameMoney.money > item.price) {
        gameMoney.money -= item.price;
        item.amount += 1;
        item.price += 10
        gameMoney.moneyPerClick += item.mpc;
    } else {
        alert("Masz za malo pieniedzy");
    }
}

function itemClick() {
    let itemId = this.dataset.id;
    test(itemId);
}
itemBtn.forEach(e => e.addEventListener('click',itemClick))
1

Bo do funkcji test przekazujesz itemId zamist item. Musisz pobrać item z items czyli wywołać np. test(items[itemId])

To powinieneś wyłapać przy pierwszym debugowaniu... nawet za pomocą conole.log jakbyś wpisał np. w funkcji test console.log(item) to widziałbyś, że przekazujesz zły argument

0

I teraz console.log(item) przekazuje cały obiekt.

const getItem = (itemId) => {
    return items[itemId];
}
function itemClick() {
    let itemId = this.dataset.id;
    let item = getItem(itemId);
    console.log(item);
    test(item);
}
0
anonimowy napisał(a):

Bo do funkcji test przekazujesz itemId zamist item. Musisz pobrać item z items czyli wywołać np. test(items[itemId])

To powinieneś wyłapać przy pierwszym debugowaniu... nawet za pomocą conole.log jakbyś wpisał np. w funkcji test console.log(item) to widziałbyś, że przekazujesz zły argument

A to , że zły argument przekazuje to wiedziałem nawet napisałem. Tylko nie wiem wczoraj już mnie zmęczenie dopadło i z tą funkcją nie mogłem wykombinować :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1