Diskuze: Nakupování virtuálních položek v JS online hrách
V předchozím kvízu, Online test znalostí JavaScript, jsme si ověřili nabyté zkušenosti z kurzu.


- A v cem je problem? co pise js konzola? Nebo, co se ti tam deje? Nezadal jsi podminky. takze, ikdyz si kod nekdo zkopiruje, tak nevi, co ma delat. Tududutu.
- Nechapu, proc si data neulozis treba to promenne db.
var db = {};
db.stavby = {
kamenolom: {pocet: 0, postaveni: {kameni:0, zelezo:0, drevo:0}, vyrabi: {kameni:10},
piskova_jama: {pocet: 1, postaveni: {kameni:0, zelezo:0, drevo:0}, vyrabi: {pisek:10}
};
Nechapu, proc to cele nemas obalene v class? Takovyto kod, kdyz copy-paste pridas k jinemu kodu, tak muze snadno prestat fungovat. Treba aspon takto:
var hra = {};
hra.db = {};
hra.fn = {};
hra.fn.nedostatekSurovin = function () {...}
Takhle mas pak vsechno v promenne hra. Takhle si zaberes spoustu promennych a
za chvilku budes premyslet nad tim, jak pojmenovat novou nebo, kam ji
zaradit.
Navic, kdyz si tam das logickou strukturu, tak muzes udelat funkci Next turn,
cyklus vsechny stavby, ziskej produkci, pridej ke stavbe. Jedna kratka funkce.
Takhle tam mas 1001 funkci a vlastne ani nevis, co delas.
3. A tuto cast absolutne nechapu.
$(function() {
$( "#drevorubec" ).click(zjistiDostupnostStavby()); // kdyz kliknes na id=drevorubec, tak se provede zjistiDostupnostStavby
stavba = "Drevorubec"; // a tohle je nesmysl
});
$(function() { // a tohle je uplny nesmysl, protoze by to melo prepsat predchozi kod.
$( "#ocelarna" ).click(zjistiDostupnostStavby());
stavba = "Ocelarna";
});
google = jquery click - pozijes google a najdes si priklady, treba ty v
dokumentaci, ze?
Kdyztak bych to napsal nejak takto:
$( "#drevorubec" ).click(function() {
// stavba = "Drevorubec"; // a ted je otazka, zda to stavba nema byt predtim
zjistiDostupnostStavby()
stavba = "Drevorubec";
// a nebo by to cele melo jit do haje a napsat to takto
// zjistiDostupnostStavby("Drevorubec") // function (stavba) {return db.stavby[stavba] == true;})
//
+20 Zkušeností
+2,50 Kč

// js jquery
$( "#drevorubec" ).click(function() {blabla});
// js
id = "drevorubec";
el = document.getElementById(id);
el.onclick = function() {blabla;}
// js verze 2
id = "drevorubec";
el = document.getElementById(id);
function xxx() {blabla;}
el.onclick = xxx; // do onclick prirazujes funkci
// js + html - mozna by bylo lepsi zapomenout na jquery a napsat to takto
<input type=button value=plus onclick="plus();">
<input type=button value=minus onclick="minus();">
<script>
function plus() {blabla;}
function minus() {blabla;}
</script>
šíma:6.4.2020 15:56
A tahle část:
var hra = {};
hra.db = {};
hra.fn = {};
hra.fn.nedostatekSurovin = function () {...}
.mám tam něco vyplnovat čitak, a ještě! když budu chtít nahradit při zakoupení obrázek jiným obrázkem, co tam mám udělat?
To byl jen priklad. Tam dal samozrejme musi byt js kod. Ja to pouzivam jeste trochu jinak:
var hra;
hra = {};
hra.vars = {}; // promene
hra.db = {}; // promene databazoveho typu, tabulky uzivatelu
hra.db.building_list= [
{
id: 0,
name: 'kamenolom',
postaveni: {kameni:0, zelezo:0, drevo:0},
vyrabi: {kameni:10}
},{
id: 1,
name: 'piskovna',
postaveni: {kameni:0, zelezo:0, drevo:0},
vyrabi: {pisek:10}
}
];
hra.db.user_list = [ // pole uzivatele
{
id: 0, // nulta polozka pole uzivatele
name: 'peter',
suroviny_list: {kameni:0, zelezo:0, drevo:0},
building_list: {building_id:0, count: 0}
}
];
hra.error = function (name, p)
{
var out = '';
case (name)
{
'nedostatek_surovin': out += 'Bohužel, na stavbu {0} nemáš dostatek surovin. Zkus to později.'.replace('{0}', p[0]);
}
$( "#notice_text" ).html(out);
}
function zjistiDostupnostStavby(user_id, building_id) {
var user , building , bool;
user = hra.db.user_list[user_id];
building = hra.db.building_list[building_id];
bool = true;
for (i in building.postaveni)
bool &= user.suroviny[i]>=building.postaveni[i]
if (bool==false) hra.error('nedostatek_surovin', building.name);
};
Je to jen od oka, nemusi to fungovat. Kazdopadne, podle tveho puvodniho kodu
je nejspis problem v tom, ze mas spatne vytvorene onclicky. Ale to jen hadam,
protoze jsi nedal zadny popis, co vlastne je treba v tom programu udelat, co je
treba sledovat a jaky na tom miste byl ocekavany vysledek. Rikam, ja bych nesel
cestou jquery, kdyz jquery neumis A nebo prave bych tim sel, je v mnohem jednodussi, ale vyhledavej si
priklady googlem, cti si dokumentaci. Problem ale nejspis je, ze neznas ani
zakladni js, tak se potom hur googluje, co vlastne chces po jquery
google = event click bind function to button
šíma:7.4.2020 9:26
A jak pak z těch polí vydoluju hodnoty? (mimochodem, nediv se, že to tolik
neumim, je mi teprve 13 )
x = [9, 8, 7];
x[0] = 9;
x[1] = 8;
x[2] = 7;
y = {a: 4, b: 5, c: 6}
y.a = 4;
y.b = 5;
y.c = 6;
y['a'] = 4;
y['b'] = 5;
y['c'] = 6;
Muzes to udelat jeste jinak.
function classSuroviny(a, b, c)
{ return {
kameni:a?a:0,
zelezo: b?b:0,
drevo: c?c:0
};}
function classBudova(id, name, a, b, c, pa, pb, pc)
{ return {
id: id,
name: name,
postaveni: new classSuroviny (a, b, c},
vyrabi: new classSuroviny (pa, pb, pc}
};}
list = [];
list[0] = new classBudova(0, 'kamenolon', 0, 0, 0, 10, 0, 0);
list[1] = new classBudova(1, 'piskovna', 0, 2, 0, 4, 0, 0);
list[2] = new classBudova(2, 'zelezne doly', 0, 10, 3, 0, 0, 3);
hra.db.building_list = list;
alert(list[2].name)
alert(list[2].id)
alert(list[2].postaveni.kameni)
alert(list[2].vyroba.kameni)
alert(list[2]['vyroba'].kameni)
alert(list[2]['vyroba']['kameni'])
Zkratka, podobne s praci v databazi. Tam se nejcasteji pouzivaji prikazy INSERT, UPDATE, DELETE, SELECT radek/radky z tabulky. Tabulkou je myslena tabulka jake umi treba excel.
-- V sql db bys udelal takoveto tabulky a ty podobne muzes udelat i v js. Ale muzes si to zjednodusit temi struktutovanymi poli
uzivatele: id_uzivatel, jmeno
1, peter (id=1, jmeno=peter)
2, lojza
budovy: id_budova, jmeno, popis
1, zelezny dul, V zeleznem dole se tezi zelezna ruda
2, piskovna, V piskovne se doluje pisek
suroviny: id_suroviny, surovina1, 2 ,3... typ=vystavba nebo produkce
1, 10, 0, 0, 0, 0, 3
2, 0, 10, 0, 1, 4, 2
budova_suroviny: id_budova, id_suroviny (vystavba), id_suroviny (produkce z budovy)
1, 1, 2 // budova id=1, suroviny id=1, suroviny id=2
uzivatel_postavene_budovy: id_uzivatel, id_budova
1, 1
1, 2
1, 3
Takze, bud to udelas takto, databazove, a pak budes mit ale prikazy, ktere ti ty tabulky propoji. a nebo pouzijes strukturovane pole
[] {}
Mozna par oprav. Rikal jsem ze to pisu z hlavy
// https://jsfiddle.net/gmveqaho/
function newSuroviny(row)
{ return {
kameni: row[0],
zelezo: row[1],
drevo: row[2]
};}
function newBudova(id, name, row_postaveni, row_vyrabi)
{ return {
id: id,
name: name,
postaveni: newSuroviny (row_postaveni),
vyrabi: newSuroviny (row_vyrabi)
};}
var list, item, hra, str;
hra = {};
hra.db = {};
list = [];
list[0] = newBudova(0, "kamenolon", [0, 0, 0], [10, 0, 0]);
list[1] = newBudova(1, "piskovna", [0, 2, 0], [4, 0, 0]);
list[2] = newBudova(2, "zelezne doly", [0, 10, 3], [0, 0, 3]);
hra.db.building_list = list;
str = "";
item = hra.db.building_list[2];
//alert(JSON.stringify(item));
str += "\n" + item.id;
str += "\n" + item.name;
str += "\n" + item.postaveni.kameni;
str += "\n" + item.vyrabi.kameni;
str += "\n" + item['vyrabi'].kameni;
str += "\n" + item['vyrabi']['kameni'];
//alert(str)
document.write('<pre>'+str+'</pre>');
To new by slo pouzit, ale musel bys to napsat jinak
function newSuroviny(row)
{ return {
kameni: row[0],
zelezo: row[1],
drevo: row[2]
};}
x = newSuroviny([1,2,3]) // spusti funkci a ta ti vrati returnem pole
---
function classSuroviny(row)
{
this.kameni = row[0];
this.zelezo = row[1];
this.drevo = row[2];
}
y = new classSuroviny([1,2,3]) // vytvor novy objekt podle konstrukce funkce
// to by melo udelat totez, jen se to pise trochu jinak
Navic jsem tam pridal pouziti pole pro suroviny, takhle bude snadnejsi menit pocet polozek. A zrusil kontrolu existence hodnoty. Budu pocitat s tim, ze u uzivatele tam vyplnis prislusny pocet nul, pripadne nejakou vychozi hodnotu.
šíma:28.5.2020 8:00
Múžu se tě ještě zeptat, co znamenají t hodnoty v hranatých závorkách?
list[0] = newBudova(0, "kamenolon", [0, 0, 0], [10, 0, 0]);
Posilas funkci cislovane pole.
a = 0
b = "kamenolom"
c = [0, 0, 0]
// nebo c = []; c[0] = 0; c[1] = 0; c[2] = 0;
d = [10, 0, 0]
list[0] = newBudova(a, b, c, d);
To potom pretransformuji na struturovane pole
function newSuroviny(row)
{ return {
kameni: row[0],
zelezo: row[1],
drevo: row[2]
};}
To je na tobe, jak si budes resit databazi udaju. Ja pro jednoduchost pro
zapis surovin pouzil pole
[0, 0, 0] ale klidne to zapis jako
{kameni: 0, zelezo: 0, drevo: 0}
Urcite jsem mel pro to dobry duvod, ale uz si nevzpomenu.
Mozna mi slo jen o zkraceni zapisu.
Mozna slo o to, ze kdyz se upises a napises vic cisel [0, 0, 0, 0], tak ta
funkce new suroviny to do databaze udaju prepise spravne.
function newSuroviny(row)
{ return {
kameni: row[0],
zelezo: row[1],
drevo: row[2]
};}
function newSuroviny(row)
{ return {
kameni: row[0] ? row[0] * 1 : 0,
zelezo: row[1] ? row[1] * 1 : 0,
drevo: row[2] ? row[2] * 1 : 0
};}
Ten zapis, funkce v podstate udela jen tohle (a pridam dalsi mozne upravy, zjednoduseni)
i = 0;
list[i] = newBudova(i++, "kamenolon", [0, 0, 10], [30, 0, 0]);
list[i] = newBudova(i++, "zelezny dul", [30, 5, 10], [0, 30, 0]);
i = 0;
list[i] = {id: i++, name: "kamenolom", postaveni: {kameni: 0, zelezo: 0, drevo: 10}, vyrabi: {kameni: 30, zelezo: 0, drevo: 0}};
list[i] = {id: i++, name: "zelezny dul", postaveni: {kameni: 30, zelezo: 5, drevo: 10}, vyrabi: {kameni: 0, zelezo: 30, drevo: 0}};
Id by melo odpovidat cislu, pod jakym to pridavas do toho list. Kdyz potom
funkci predas budovu, tak muze zpetne zjistit poradi v listu. To asi u budov
nevyuzijes, ale treba u seznamu hracu nebo neceho, co pridavas a odebiras, tam
bys to vyuzil. Kdyz tam pouziji i a i+=, tak to zjednodusi zapis, ze si nemusis
hlidat cislovani, ale automaticky se zvysuje.
Sam si vyber, ktery z tech zapisu je pro tebe prehlednejsi, pohodlnejsi na
upravy. Zas, kdyz pouzijes ten uplny, tak nemusis mit pomocne funkce. Program se
spusti o 100ms rychleji. Coz muze byt nekdy vyznamne.
šíma:30.5.2020 20:06
A ještě, co tam znamená ta poznámka JSON.stringify(item)?
Milan Turyna:30.5.2020 20:16
item = object
JSON.stringify(item) = string (json)
Prevede se ti to z objektu na json.
Kdybych chtěl zapsat informace o stavbě do proměnné str + název stavby, abych to mohl později v kódu vypsat na stránku, dalo by se to napsat nějak úsporněji než takto?
str_drevorubec = "";
item = hra.db.building_list[0];
//alert(JSON.stringify(item));
str_drevorubec += "\n" + item.id;
str_drevorubec += "\n" + item.name;
str_drevorubec += "\n" + item.postaveni.kameni;
str_drevorubec += "\n" + item.postaveni.zelezo;
str_drevorubec += "\n" + item.postaveni.drevo;
str_drevorubec += "\n" + item.postaveni.pisek;
str_drevorubec += "\n" + item.postaveni.ocel;
str_drevorubec += "\n" + item.postaveni.uhli;
str_drevorubec += "\n" + item.postaveni.sklo;
str_drevorubec += "\n" + item.vyrabi.kameni;
str_drevorubec += "\n" + item.vyrabi.zelezo;
str_drevorubec += "\n" + item.vyrabi.drevo;
str_drevorubec += "\n" + item.vyrabi.pisek;
str_drevorubec += "\n" + item.vyrabi.ocel;
str_drevorubec += "\n" + item.vyrabi.uhli;
str_drevorubec += "\n" + item.vyrabi.sklo;
str_drevorubec = JSON.stringify(item);
https://jsfiddle.net/g3Lok64f/
function myStringify(item)
{
var str, i;
str = '';
for (i in item)
{
if (typeof item[i] === 'object')
{
str += myStringify(item[i]);
continue;
}
str += "<br>" + i + " = " + item[i];
}
return str;
}
var x, item;
item = {id: 123, name: "kamenolom", postaveni: {kameni: 0, zelezo: 0, drevo: 10}, vyrabi: {kameni: 30, zelezo: 0, drevo: 0}};
document.write(myStringify(item))
id = 123
name = kamenolom
kameni = 0
zelezo = 0
drevo = 10
kameni = 30
zelezo = 0
drevo = 0
šíma:4.6.2020 16:07
Nechápu Proč jsou tam ty
proměnné takhle divně?
item = {id: 123, name: "kamenolom", postaveni: {kameni: 0, zelezo: 0, drevo: 10}, vyrabi: {kameni: 30, zelezo: 0, drevo: 0}};
document.write(myStringify(item))
"Proč jsou tam ty proměnné takhle divně?"
Nerozumim dotazu. Co znamena divne? Nebo, jak by to melo vypadat, aby se to
nejevilo divne?
Ruzne zapisy u poli v js (array, list).
// cislovane pole s cislovanymi indexy
a = [] // vytvor nove pole
a[0] = 123 // uprav existujici pole
a[1] = "kamenolom"
a[-3] = "jesterka" // to by mohlo projit
a = [123, "kamenolom", "jesterka"] // vytvor nove pole a napln ho hodnotami
alert(a[2]) // jesterka v pripade vytvoreni pole predchozim radkem bude mit index v poradi, 0=123, 1=kamenolom, takze 2=jesterka
// asociativni pole (objekt), s klici, textovymi indexy a myslim, ze cisla to bere taky
b = {} // vytvor nove pole
b.name = 123 // uprav existujici pole
b['name'] = 123;
b = { name: 123 } // vytvor nove pole a napln ho hodnotami
b = { 'name': 123 }
b = { 'name': "123" }
U pole mas vzdycky index (klic) a value. U cislovaneho pole jsou klice 0,1,2,3, u necislovaneho jakykoliv string. Ten string je mozne zapsat jako text nebo 'text' nebo "text". A soucasne je tam mozne pouzit promenou. Pokud je ale undefined, tak se pouzije jako string. String se da zapsat do jednoduchych nebo dvojitych apostrofu "aaa", 'bbb'.
c = {x: y}; // x je undefinex, y je undefined, vysledek dopadne takto:
c = {'x': undefined}
x = 'name';
y = 'kamenolom'
c = {x: y};
c = {'name': 'kamenolom'}
Jako value muzes pouzit jakoukoliv strukturu (cislo, string, pole, objekt, funkci)
d = {zobraz: alert}
d = {zobraz: window.alert}
d.zobraz(123) spusti funkci alert(123)
d.smaz = function (id) {document.getElementById(id).innerHTML = '';}
d.smaz('menu');
function e(id) {document.getElementById(id).innerHTML = '';}
e('menu');
... atd, takovych zapisu je spoustu a daji se najit googlem
U poli se daji provadet jeste tyto operace:
cislovane: pole.length, pouzivaji se cykly: for(i=0; i<pole.length; i++)
necislovane, pocet polozek zjistis jedine cyklem: for (i in pole)
Nevim, co ti napsat jineho, par prikladu, jak se s poli asi pracuje.
Nejake priklady zapisu poli jsem ti uvedl uz v prispevku ze 7. dubna 13:52.
Muzes pouzit strukturu, jakou mas v prvnim prispevku. V tom ti nikdo nebrani, ne? Jenom, az budes chtit data prenest do jineho programu, tak to budes muset do te funkce vypisovat promenou po promene, misto, aby jsi pouzil jednoduche cykly, kde nemusis dosazovat zadna jmena promenych, pokud nebudes chtit data preformatovat v neco spesl.
// tvuj kod vs muj
if (pocetDreva >= drevo) {
if (pocetZeleza >= zelezo) {
if (pocetSkla >= sklo) {
if (pocetKamene >= kamen) {
postavStavbu(stavba)}
else {nemasDostatekSurovin()};
}
else {nemasDostatekSurovin()};
}
else {nemasDostatekSurovin()};
}
else {nemasDostatekSurovin()};
// ----
bool = true;
for (i in building.postaveni)
bool &= user.suroviny[i]>=building.postaveni[i]
if (bool==false) hra.error('nedostatek_surovin', building.name);
};
Zadne kameni ani zelezo jsem tam nemusel zminovat, proste proveri vsechny
polozky v poli.
A kdyz se rozhodnes pridat surovinu, tak muj kod bude fungovat dale a tvuj kod
budes muset upravit o dalsi surovinu, podminky.
Jo, a jeste mozna za zminku stoji, ze tvuj kod by sel zapsat takto, coz by mozna zjednodusilo dalsi upravy, ale je o malo pomalejsi nez pomoci tech ifu. Cehoz si nejspis stejne nevsimnes, leda bys to meril. pomoci window.performance nebo new Date()
bool = true;
bool &= pocetDreva >= drevo; // bool = bool & pocetDreva >= drevo;
bool &= pocetZeleza >= zelezo;
bool &= pocetSkla >= sklo;
bool &= pocetKamene >= kamen;
if (bool==false) {nemasDostatekSurovin();}
Nebo by to slo zapsat takto a bylo by to mozna i rychlejsi nez tvuj kod, protoze se vyhodnocuji podinky postupne a pri prvnim false to skonci a dalsi uz neresi.
if (pocetDreva >= drevo && pocetZeleza >= zelezo && pocetSkla >= sklo && pocetKamene >= kamen) {...};
Zobrazeno 23 zpráv z 23.