RpyPlayerWeb/public_html/js/Views.js
2015-12-11 23:20:57 +02:00

640 lines
20 KiB
JavaScript

/* global TextUtils, PathResolver, ViewActivity, transitions, Transition, rpyscript, Variables */
function Views(parser) {
this.parser = parser;
parser.preScan();
this.windowTag = document.getElementById("window");
this.textAuthorTag = document.getElementById("textAuthor");
this.textContentTag = document.getElementById("textContent");
this.musicPlayerAudio = new Audio();
this.soundPlayerAudio = new Audio();
this.soundLoopPlayerAudio = new Audio();
this.ambiencePlayerAudio = new Audio();
this.musicQueue = new Array();
this.soundQueue = new Array();
this.backgroundName = "";
this.backgroundType = "";
this.characters = new Characters();
this.characters.makeNamesUnknown();
this.characters.makeNamesKnown();
this.places = new MapPlaces();
this.useSpriteTransitions = true;
this.spriteInContainer = {};
this.blockTap = false;
this.cancelNextStep = false;
this.nextCommandRunnable = function () {
Views.blockTap = false;
if (!Views.cancelNextStep) parser.next();
};
}
Views.prototype.init = function () {
$('#menu').hide();
$('#mainMenuButton').click(function () {
ViewActivity.getInstance().showMainMenu();
});
document.addEventListener('click', function (e) {
ViewActivity.getInstance().onTouch(e);
});
};
Views.prototype.NO_FADE = new FadeInfo();
Views.prototype.getInstance = function () {
return this;
};
Views.prototype.onTouch = function (e) {
if (this.blockTap) return;
if ($('#menu').is(":visible")) return;
if ($(e.target).is('li')) return;
if ($(e.target).is('#mainMenuButton')) return;
this.cancelNextStep = true;
this.parser.next();
};
Views.prototype.finish = function () {
this.text('{center}{html}<a style="color: white" href="/">Вернуться на главную</a>');
};
Views.prototype.windowShow = function (effect) {
if (this.windowTag.style.visibility !== "visible") {
this.windowTag.style.visibility = "visible";
}
if (!TextUtils.isEmpty(effect)) {
this.background(this.backgroundType, this.backgroundName, effect);
return true;
}
return false;
};
Views.prototype.windowHide = function (effect) {
if (this.windowTag.style.visibility !== "hidden") {
this.windowTag.style.visibility = "hidden";
}
if (!TextUtils.isEmpty(effect)) {
this.background(this.backgroundType, this.backgroundName, effect);
return true;
}
return false;
};
Views.prototype.windowSwitchVisibility = function () {
if (this.windowTag.style.visibility === "hidden") {
this.windowTag.style.visibility = "visible";
} else {
this.windowTag.style.visibility = "hidden";
}
};
Views.prototype.background = function (type, name, effect) {
if (TextUtils.isEmpty(name)) return;
this.backgroundType = type;
this.backgroundName = name;
this.text("");
this.spritesClear();
var background = '';
if (name.equalsIgnoreCase("black")) {
background = "black";
} else if (name.equalsIgnoreCase("white")) {
background = "white";
} else {
background = 'url("' + PathResolver.background(type, name) + '") no-repeat center center fixed';
}
var animationTime = 0;
$('#background1').css('background', $('#background2').css('background'));
$('#background1').show();
if (effect in transitions) {
var transition = transitions[effect];
if (transition["type"] === Transition.TYPE_FADE) {
animationTime = transition["inTime"] + transition["outTime"];
$('#background2').hide();
$('#background2').css('background', background);
$('#background2').css('backgroundSize', 'cover');
$('#background1').fadeOut(transition["outTime"], function () {
$('#background2').fadeIn(transition["inTime"], function () {
$('#background1').hide();
$(this).show();
});
});
this.pause(animationTime, false);
return;
}
}
$('#background1').hide();
$('#background2').css('background', background);
$('#background2').css('backgroundSize', 'cover');
$('#background2').show();
this.pause(animationTime, false);
};
Views.prototype.spritesClear = function () {
$('#container').empty();
this.spriteInContainer = {};
};
Views.prototype.sprite = function (whoid, params, position, alias, effect) {
var img = undefined;
var key = TextUtils.isEmpty(alias) ? whoid : alias;
if (key in this.spriteInContainer) {
img = this.spriteInContainer[key];
} else {
//if (this.useSpriteTransitions) img = new AnimatableImageView(this);
//else img = new ImageView(this);
img = $('<img>', {class: "sprite", style: "height: " + window.innerHeight + "px;" });
this.spriteInContainer[key] = img;
}
var path = PathResolver.sprite(whoid, params);
try {
//if (useSpriteTransitions) ((AnimatableImageView)img).setImageBitmap(bitmap, effect);
//else img.setImageBitmap(bitmap);
img.hide();
img.one("load", function() {
ViewActivity.getInstance().setSpritePosition($(this), position);
if (effect in transitions) {
var transition = transitions[effect];
if (transition["type"] === Transition.TYPE_FADE) {
$(this).hide().fadeIn(transition["inTime"]);
return;
}
}
$(this).show();
});
img.attr('src', path);
if (!$.contains($('#container'), img))
$('#container').append(img);
} catch (ioe) {
console.log("sprite: " + path, ioe);
//if (Logger.DEBUG) Logger.log("sprite: " + path, ioe);
}
};
Views.prototype.hideSprite = function (whoid, effect) {
if (!(whoid in this.spriteInContainer)) return;
this.hide(whoid, effect);
};
Views.prototype.hide = function (whoid, effect) {
var img = this.spriteInContainer[whoid];
if (img == null) return;
if (effect in transitions) {
var transition = transitions[effect];
if (transition["type"] === Transition.TYPE_FADE) {
img.fadeOut(transition["outTime"], function() {
$(this).remove();
});
} else {
img.remove();
}
} else {
img.remove();
}
delete this.spriteInContainer[whoid];
};
Views.prototype.setSpritePosition = function (img, position) {
var width = window.innerWidth;
var imgWidth = img.width();
if (TextUtils.isEmpty(position) || position.equals("center")) {
img.css("left", Math.floor(width / 2 - imgWidth / 2) + "px");
} else if (position.equals("left")) {
img.css("left", Math.floor(imgWidth / 6) + "px");
} else if (position.equals("cleft")) {
img.css("left", Math.floor(width / 2 - imgWidth + imgWidth / 8) + "px");
} else if (position.equals("right")) {
img.css("right", Math.floor(imgWidth / 6) + "px");
} else if (position.equals("cright")) {
img.css("right", Math.floor(width / 2 - imgWidth + imgWidth / 8) + "px");
} else if (position.equals("fleft")) {
img.css("left", Math.floor(-imgWidth / 4) + "px");
} else if (position.equals("fright")) {
img.css("right", Math.floor(-imgWidth / 4) + "px");
}
};
Views.prototype.pause = function (duration, hard) {
this.blockTap = hard;
this.cancelNextStep = false;
/* var now = new Date().getTime();
while(new Date().getTime() < now + sleepDuration){ ; } */
setTimeout(this.nextCommandRunnable, duration);
};
Views.prototype.text_1 = function (text) {
this.textAuthorTag.innerText = "";
if (TextUtils.isEmpty(text)) this.windowHide("");
else {
this.windowShow("");
this.formatString(this.textContentTag, text);
}
};
Views.prototype.text_2 = function (whoid, text) {
if (whoid.equalsIgnoreCase("th")) this.text("~ " + text + " ~");
else if (!this.characters.contains(whoid)) this.text(text);
else {
this.windowShow("");
var person = this.characters.get(whoid);
this.textAuthorTag.innerText = person.name;
this.textAuthorTag.style.color = toColor(person.color);
this.formatString(this.textContentTag, text);
}
};
Views.prototype.text = function (arg1, arg2) {
if (arguments.length === 1) this.text_1(String(arg1));
else this.text_2(String(arg1), String(arg2));
};
Views.prototype.formatString = function (tag, text) {
var edited = text.replaceAll("\\{w.*?\\}", "");
if (edited.contains("{center}")) {
edited = edited.replaceAll("\\{center\\}", "");
this.textContentTag.style.textAlign = "center";
} else {
this.textContentTag.style.textAlign = "left";
}
if (edited.contains("{html}")) {
edited = edited.replaceAll("\\{html\\}", "");
tag.innerHTML = edited;
return;
}
var codes = ["b","i","s","u","big","small"];
var html = false;
for (var i = 0; i < codes.length; i++) {
var ch = codes[i];
if (edited.contains("{"+ch+"}")) {
edited = edited.replaceAll("{"+ch+"}", "<"+ch+">");
edited = edited.replaceAll("{/"+ch+"}", "</"+ch+">");
html = true;
}
}
if (html) {
edited = edited.replace("\n", "<br/>");
tag.innerHTML = edited;
} else {
tag.innerText = edited;
}
};
Views.prototype.makeNamesKnown = function () {
this.characters.makeNamesKnown();
};
Views.prototype.makeNamesUnknown = function () {
this.characters.makeNamesUnknown();
};
Views.prototype.meet = function (whoid, name) {
this.characters.setName(whoid, name);
};
Views.prototype.disableAllZones = function () {
this.places.disableAllZones();
};
Views.prototype.disableCurrentZone = function () {
this.places.disableCurrentZone();
};
Views.prototype.resetZone = function (zone) {
this.places.resetZone(zone);
};
Views.prototype.setZone = function (name, label) {
this.places.setZone(name, label);
};
Views.prototype.showMap = function () {
$('#menuTitle').text('Карта');
var zoneKeys = new Array();
var zoneNames = new Array();
for (var key in this.places.zones) {
zoneKeys.push(key);
zoneNames.push( (key in this.places.names) ? this.places.names[key] : key );
}
$('#menuChoose').empty();
for(var i = 0; i < zoneKeys.length; i++) {
var li = $('<li>', {text: zoneNames[i]});
li.click(this.createMapPlaceClickFunction(i, zoneKeys, this.places.zones));
li.appendTo($('#menuChoose'));
}
$('#menu').show();
};
Views.prototype.createMapPlaceClickFunction = function (index, zoneKeys, zones) {
var views = this;
return function () {
$('#menu').hide();
var currentZone = zoneKeys[index];
views.parser.jumpLabel(zones[currentZone]);
views.parser.next();
};
};
Views.prototype.menu = function (menu) {
if (!TextUtils.isEmpty(menu.getTitle())) {
$('#menuTitle').text(menu.getTitle());
} else {
$('#menuTitle').text('Выберите: ');
}
$('#menuChoose').empty();
var items = menu.getItems();
for(var i = 0; i < items.length; i++) {
var li = $('<li>', {text: items[i].name});
li.click(this.createMenuItemClickFunction(i, menu));
li.appendTo($('#menuChoose'));
}
$('#menu').show();
};
Views.prototype.createMenuItemClickFunction = function (index, menu) {
var views = this;
return function () {
$('#menu').hide();
views.parser.setPosition(menu.getPosition(index));
};
};
Views.prototype.showMainMenu = function () {
$('#menuTitle').text('Меню');
var views = this;
$('#menuChoose').empty();
this.addMainMenuItem("Дальше", function() {
views.blockTap = false;
views.parser.next();
});
this.addMainMenuItem("Предыдущая сцена", function() {
views.parser.prevScene();
});
this.addMainMenuItem("Следующая сцена", function() {
views.parser.nextScene();
});
this.addMainMenuItem("Сохранить", function() {
$('#menu').hide();
views.saveState();
});
var saves = JSON.parse(localStorage.saves || null) || {};
saves[rpyscript] = saves[rpyscript] || [];
if (saves[rpyscript].length > 0) {
this.addMainMenuItem("Загрузить…", function() {
views.showLoadStateMenu();
});
this.addMainMenuItem("Удалить…", function() {
views.showRemoveStateMenu();
});
}
this.addMainMenuItem("Закрыть", function() {
$('#menu').hide();
});
$('#menu').show();
};
Views.prototype.addMainMenuItem = function(name, func) {
var li = $('<li>', {text: name});
li.click(func);
li.appendTo($('#menuChoose'));
};
Views.prototype.addMusicToQueue = function (name) {
if (!this.musicPlayerAudio.paused) {
// Если музыка играет, просто добавляем в очередь
this.musicQueue.push(name);
} else {
// Воспроизводим
this.music(name, this.NO_FADE);
}
};
Views.prototype.addSoundToQueue = function (name) {
if (!this.soundPlayerAudio.paused) {
this.soundQueue.push(name);
} else {
this.sound(name, this.NO_FADE);
}
};
Views.prototype.music = function (name, fade) {
try {
this.stopMusic(this.musicPlayerAudio.fade);
this.musicPlayerAudio.src = PathResolver.music(name);
this.musicPlayerAudio.fade = fade;
var views = this;
this.musicPlayerAudio.addEventListener('ended', function () {
if (views.musicQueue.length > 0) {
views.music(views.musicQueue.pop(), views.NO_FADE);
} else {
this.currentTime = 0;
this.play();
}
});
this.musicPlayerAudio.play();
if (fade.fadeIn) {
$(this.musicPlayerAudio).prop("volume", 0.0);
$(this.musicPlayerAudio).animate({volume: 1.0}, fade.duration * 1000);
} else {
$(this.musicPlayerAudio).prop("volume", 1.0);
}
} catch (e) {
console.log("music: " + name + " " + e);
}
};
Views.prototype.stopMusic = function (fade) {
if (this.musicPlayerAudio.paused) return;
if (fade.fadeOut) {
$(this.musicPlayerAudio).animate({volume: 0.0}, fade.duration * 1000, function() {
this.pause();
});
} else {
this.musicPlayerAudio.pause();
}
};
Views.prototype.sound = function (name, fade) {
try {
this.stopSound(this.soundPlayerAudio.fade);
this.soundPlayerAudio.src = PathResolver.sound(name);
this.soundPlayerAudio.fade = fade;
var views = this;
this.soundPlayerAudio.addEventListener('ended', function () {
if (views.soundQueue.length > 0) {
views.sound(views.soundQueue.pop(), views.NO_FADE);
}
});
this.soundPlayerAudio.play();
if (fade.fadeIn) {
$(this.soundPlayerAudio).prop("volume", 0.0);
$(this.soundPlayerAudio).animate({volume: 1.0}, fade.duration * 1000);
} else {
$(this.soundPlayerAudio).prop("volume", 1.0);
}
} catch (e) {
console.log("sound: " + name + " " + e);
}
};
Views.prototype.stopSound = function (fade) {
if (this.soundPlayerAudio.paused) return;
if (fade.fadeOut) {
$(this.soundPlayerAudio).animate({volume: 0.0}, fade.duration * 1000, function() {
this.pause();
});
} else {
this.soundPlayerAudio.pause();
}
};
Views.prototype.soundLoop = function (name, fade) {
try {
this.stopSoundLoop(this.soundLoopPlayerAudio.fade);
this.soundLoopPlayerAudio.src = PathResolver.sound(name);
this.soundLoopPlayerAudio.fade = fade;
this.soundLoopPlayerAudio.addEventListener('ended', function () {
this.currentTime = 0;
this.play();
});
this.soundLoopPlayerAudio.play();
if (fade.fadeIn) {
$(this.soundLoopPlayerAudio).prop("volume", 0.0);
$(this.soundLoopPlayerAudio).animate({volume: 1.0}, fade.duration * 1000);
} else {
$(this.soundLoopPlayerAudio).prop("volume", 1.0);
}
} catch (e) {
console.log("soundloop: " + name + " " + e);
}
};
Views.prototype.stopSoundLoop = function (fade) {
if (this.soundLoopPlayerAudio.paused) return;
if (fade.fadeOut) {
$(this.soundLoopPlayerAudio).animate({volume: 0.0}, fade.duration * 1000, function() {
this.pause();
});
} else {
this.soundLoopPlayerAudio.pause();
}
};
Views.prototype.ambience = function (name, fade) {
try {
this.stopAmbience(this.ambiencePlayerAudio.fade);
this.ambiencePlayerAudio.src = PathResolver.ambience(name);
this.ambiencePlayerAudio.fade = fade;
this.ambiencePlayerAudio.addEventListener('ended', function () {
this.currentTime = 0;
this.play();
});
this.ambiencePlayerAudio.play();
if (fade.fadeIn) {
$(this.ambiencePlayerAudio).prop("volume", 0.0);
$(this.ambiencePlayerAudio).animate({volume: 1.0}, fade.duration * 1000);
} else {
$(this.ambiencePlayerAudio).prop("volume", 1.0);
}
} catch (e) {
console.log("ambience: " + name + " " + e);
}
};
Views.prototype.stopAmbience = function (fade) {
if (this.ambiencePlayerAudio.paused) return;
if (fade.fadeOut) {
$(this.ambiencePlayerAudio).animate({volume: 0.0}, fade.duration * 1000, function() {
this.pause();
});
} else {
this.ambiencePlayerAudio.pause();
}
};
Views.prototype.saveState = function () {
var saves = JSON.parse(localStorage.saves || null) || {};
saves[rpyscript] = saves[rpyscript] || [];
saves[rpyscript].push(this.createSave());
localStorage.saves = JSON.stringify(saves);
};
Views.prototype.createSave = function () {
var save = new SaveInfo();
save.position = this.parser.lastPosition;
save.time = String(new Date());
save.variables = Variables.variables;
save.characterNames = this.characters.names;
save.backgroundType = this.backgroundType;
save.backgroundName = this.backgroundName;
return save;
};
Views.prototype.showLoadStateMenu = function () {
var saves = JSON.parse(localStorage.saves || null) || {};
var items = saves[rpyscript] || [];
$('#menuTitle').text('Загрузить');
$('#menuChoose').empty();
this.addMainMenuItem("Закрыть", function() {
$('#menu').hide();
});
for(var i = items.length - 1; i >= 0; i--) {
var li = $('<li>', {text: items[i].time});
li.click(this.createLoadStateClickFunction(i, items[i]));
li.appendTo($('#menuChoose'));
}
$('#menu').show();
};
Views.prototype.createLoadStateClickFunction = function (index, save) {
var views = this;
return function () {
Variables.variables = save.variables;
views.characters.names = save.characterNames;
if (!TextUtils.isEmpty(save.backgroundName)) {
views.background(save.backgroundType, save.backgroundName, "");
}
views.parser.setPosition(save.position);
$('#menu').hide();
};
};
Views.prototype.showRemoveStateMenu = function () {
var saves = JSON.parse(localStorage.saves || null) || {};
var items = saves[rpyscript] || [];
$('#menuTitle').text('Удалить');
$('#menuChoose').empty();
this.addMainMenuItem("Закрыть", function() {
$('#menu').hide();
});
for(var i = items.length - 1; i >= 0; i--) {
var li = $('<li>', {text: items[i].time});
li.click(this.createRemoveStateClickFunction(i));
li.appendTo($('#menuChoose'));
}
$('#menu').show();
};
Views.prototype.createRemoveStateClickFunction = function (index) {
var views = this;
return function () {
var saves = JSON.parse(localStorage.saves || null) || {};
saves[rpyscript].splice(index, 1);
localStorage.saves = JSON.stringify(saves);
views.showRemoveStateMenu();
};
};