Rodičovské a odvozené aplikace
Rodičovské a odvozené aplikace
Tvorba aplikace
Podíváme se na Rodičovské a odvozené aplikace a jejich interakce na příkladu hry "Námořní bitva"
Pro interakci použijeme následující funkce:
Pošleme požadavek na server za účelem spuštění odvozené aplikace
launchAppWithValues: function(appName, paramObj, x, y, funcToPassParams)
appName
- název programu, který se má spustit ze seznamu aplikacíparamObj
- volitelný parametr, který bude předán jako argument funkci 'funcToPassParams'. Musí to být typ Object!x
,y
- souřadnice, kde bude aplikace spuštěnafuncToPassParams
- název funkce, která bude volána po inicializaci aplikace ve formátu řetězce
Funkce pro inicializaci proměnné na serveru
serverDataSetValue: function(nameOfValue, value, description, shouldRemoveValueFromServerWhenAppCloses = false)
nameOfValue
- název proměnné. Pokud proměnná již existuje, přiřadí jí novou hodnotuvalue
- hodnota, která má být přiřazena proměnné.description
- popis proměnnéshouldRemoveValueFromServerWhenAppCloses
- měla by být proměnná odstraněna ze serveru po ukončení aplikace
Pro kontrolu změny hodnoty proměnne na serveru
serverDataSubscribeToValue: function(nameOfValue, callback, unsubscribe = false)
nameOfValue
- název proměnnécallback
- funkce, která bude volána, když se proměnná změní a vezme její novou hodnotu jako argumentunsubscribe
- zapnout nebo vypnout sledování
Pokud potřebujeme přímo zavolat funkci z rodičovské aplikace
sendDataToParentApp: function(nameOfFunction, data)
nameOfFunction
- nazev funkce ve formátu řetězcedata
- hodnota předaná funkci
Rodičovská aplikace
{
"main_script": "Game.js",
"width": 100,
"height": 20,
"animation": true,
"title": "BattleShip",
"author": "Oleksandr Khokhych"
}
var Game = SAGE2_App.extend({
init: function (data) {
this.SAGE2Init("canvas", data);
this.ctx = this.element.getContext("2d");
this.resizeEvents = "continuous";
// inicializace proměnných pro předání podřízeným aplikacím
var num1 = new Object();
var num2 = new Object();
// přiřazení indexů
num1.val = 1;
num2.val = 2;
// spuštění první aplikace
this.launchAppWithValues("Board", num1, this.sage2_x, this.sage2_y + 40, "setNum");
// spuštění druhé aplikace
this.launchAppWithValues("Board", num2, this.sage2_x + 300, this.sage2_y + 40, "setNum");
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = "grey";
this.ctx.font = "16px serif";
// aktuální stav hry
this.statement = 0;
},
resize: function (date) {
this.refresh(date);
},
draw: function (date) {
this.ctx.fillStyle = "black";
this.ctx.fillRect(0, 0, this.element.width, this.element.height);
this.update(date);
},
// funkce volaná z nadřazené aplikace
nextstate: function (date) {
// měníme aktuální stav hry
this.statement = (this.statement === 4 ? 3 : this.statement + 1);
this.refresh(date);
},
update: function (date) {
this.ctx.fillStyle = "red";
// v závislosti na aktuálním stavu hry
switch (this.statement) {
case 0:
// přiřazení proměnné "FirstPlayerState" hodnotu "waiting"
this.serverDataSetValue("FirstPlayerState", "waiting", "First player statement variable", true);
// přiřazení proměnné "SecondPlayerState" hodnotu "waiting"
this.serverDataSetValue("SecondPlayerState", "waiting", "Second player statement variable", true);
this.ctx.fillText("Press R to start the game", 20, 20);
break;
case 1:
// přiřazení proměnné "FirstPlayerState" hodnotu "waiting"
this.serverDataSetValue("FirstPlayerState", "waiting", "First player statement variable", true);
// přiřazení proměnné "SecondPlayerState" hodnotu "preparation"
this.serverDataSetValue("SecondPlayerState", "preparation", "Second player statement variable", true);
this.ctx.fillText("Preparing Second Player", 20, 20);
break;
case 2:
// přiřazení proměnné "FirstPlayerState" hodnotu "preparation"
this.serverDataSetValue("FirstPlayerState", "preparation", "First player statement variable", true);
// přiřazení proměnné "SecondPlayerState" hodnotu "waiting"
this.serverDataSetValue("SecondPlayerState", "waiting", "Second player statement variable", true);
this.ctx.fillText("Preparing First Player", 20, 20);
break;
case 3:
// přiřazení proměnné "FirstPlayerState" hodnotu "waiting"
this.serverDataSetValue("FirstPlayerState", "waiting", "First player statement variable", true);
// přiřazení proměnné "SecondPlayerState" hodnotu "turn"
this.serverDataSetValue("SecondPlayerState", "turn", "Second player statement variable", true);
this.ctx.fillText("First Player Turn", 20, 20);
break;
case 4:
// přiřazení proměnné "FirstPlayerState" hodnotu "turn"
this.serverDataSetValue("FirstPlayerState", "turn", "First player statement variable", true);
// přiřazení proměnné "SecondPlayerState" hodnotu "waiting"
this.serverDataSetValue("SecondPlayerState", "waiting", "Second player statement variable", true);
this.ctx.fillText("Second Player Turn", 20, 20);
break;
}
}
});
Odvozená aplikace
{
"main_script": "Board.js",
"width": 300,
"height": 300,
"animation": true,
"title": "Board",
"author": "Oleksandr Khokhych"
}
var Board = SAGE2_App.extend({
init: function (data) {
this.SAGE2Init("canvas", data);
this.ctx = this.element.getContext("2d");
this.resizeEvents = "continuous";
//...
// aktuální stav herního pole
this.statement = "waiting";
},
// vymaže obrazovku
clean: function () {
//...
},
drawLine: function (x0, y0, x1, y1) {
//...
},
// označíme herní mřížku
drawgrid: function () {
//...
},
// kreslení pole pro umístění lodí
drawpreset: function () {
//...
},
// kreslení pole pro střelbu
drawmap: function () {
//...
},
draw: function (date) {
this.clean();
// v závislosti na aktuálním stavu
switch (this.statement) {
//pokud tah jiného hráče, na vlastní obrazovku nic nekreslíme
case "waiting":
break;
// jestli je řada na nás umístit lodě
case "preparation":
this.drawpreset();
break;
// jestli je řada na nás střílet
case "turn":
this.drawmap();
break;
}
},
resize: function (date) {
this.refresh(date);
},
// funkce zpětného volání ke změně stavu
setState: function (val) {
this.statement = val;
},
// funkce, která vezme svůj index a přihlásí se k aktualizaci odpovídající proměnné na serveru
setNum: function (num) {
if (num.val === 1) this.serverDataSubscribeToValue("FirstPlayerState", this.setState);
if (num.val === 2) this.serverDataSubscribeToValue("SecondPlayerState", this.setState);
},
contain: function (tmp, [y, x]) {
//...
},
// funkce k určení, zda byla loď zcela zničena
bfsfill: function (ty, tx) {
//...
},
event: function (eventType, position, user_id, data, date) {
// pokud bylo stisknuto levé tlačítko myši
if (eventType === "pointerPress" && (data.button === "left")) {
var x = parseInt(position.x / this.size);
var y = parseInt(position.y / this.size);
// pokud je fáze umístění lodi, změníme hodnotu buňky na opačnou
if (this.statement === "preparation") this.presetboard[y][x] = !this.presetboard[y][x];
// pokud je fáze palby na lodě
if (this.statement === "turn") {
// pokud je v této buňce nepřátelská loď
if (this.presetboard[y][x]) {
// označíme buňku
this.gameboard[y][x] = 2;
// zkontrolujeme, zda byla loď úplně zničena
this.bfsfill(y, x);
}
// pokud není
else {
// označíme buňku
this.gameboard[y][x] = 1;
// změníme stav nadřazené aplikace, čímž předáme tah dalšímu hráči
this.sendDataToParentApp("nextstate", date);
}
}
}
else if (eventType === "keyboard") {
if (data.character === "r") {
// změníme stav nadřazené aplikace, čímž předáme tah dalšímu hráči
this.sendDataToParentApp("nextstate", date);
}
}
}
});


Odkazy
Zdrojový kód: Game
Zdrojový kód: Board