First demo
This commit is contained in:
commit
c7539bc0d5
5
nbproject/project.properties
Normal file
5
nbproject/project.properties
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
file.reference.RpyPlayer-public_html=public_html
|
||||||
|
file.reference.RpyPlayer-test=test
|
||||||
|
files.encoding=UTF-8
|
||||||
|
site.root.folder=${file.reference.RpyPlayer-public_html}
|
||||||
|
test.folder=${file.reference.RpyPlayer-test}
|
9
nbproject/project.xml
Normal file
9
nbproject/project.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||||
|
<type>org.netbeans.modules.web.clientproject</type>
|
||||||
|
<configuration>
|
||||||
|
<data xmlns="http://www.netbeans.org/ns/clientside-project/1">
|
||||||
|
<name>RpyPlayer</name>
|
||||||
|
</data>
|
||||||
|
</configuration>
|
||||||
|
</project>
|
32
public_html/index.html
Normal file
32
public_html/index.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Everlasting Summer</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script src="resources/js/jquery-1.11.3.min.js"></script>
|
||||||
|
<script src="resources/js/Utils.js"></script>
|
||||||
|
<script src="resources/js/Transitions.js"></script>
|
||||||
|
<script src="resources/js/Characters.js"></script>
|
||||||
|
<script src="resources/js/TokenType.js"></script>
|
||||||
|
<script src="resources/js/Token.js"></script>
|
||||||
|
<script src="resources/js/Lexer.js"></script>
|
||||||
|
<script src="resources/js/Parser.js"></script>
|
||||||
|
<script src="resources/js/Views.js"></script>
|
||||||
|
<script src="resources/js/Main.js"></script>
|
||||||
|
<link rel="stylesheet" href="resources/css/style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- <div>Everlasting Summer</div>-->
|
||||||
|
<!--<div id="backgroundBottom">-->
|
||||||
|
<div id="background">
|
||||||
|
<div id="container"></div>
|
||||||
|
<div id="window">
|
||||||
|
<div id="textAuthor"></div>
|
||||||
|
<div id="textContent"></div>
|
||||||
|
</div>
|
||||||
|
<p id="result"></p>
|
||||||
|
</div>
|
||||||
|
<!--</div>-->
|
||||||
|
</body>
|
||||||
|
</html>
|
54
public_html/resources/css/style.css
Normal file
54
public_html/resources/css/style.css
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body, div, span, p {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#background {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: black;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
background-attachment: fixed;
|
||||||
|
-webkit-background-size: cover;
|
||||||
|
-moz-background-size: cover;
|
||||||
|
-o-background-size: cover;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
#window {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 20%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#textAuthor {
|
||||||
|
margin: 5px 0 10px 20px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#textContent {
|
||||||
|
color: #DEC88C;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sprite {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
101
public_html/resources/js/Characters.js
Normal file
101
public_html/resources/js/Characters.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
function NameInfo(name, color) {
|
||||||
|
this.name = name;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Characters() {
|
||||||
|
this.names = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Characters.prototype.DEFAULT_COLOR = 0xFFC0C0C0;
|
||||||
|
|
||||||
|
Characters.prototype.contains = function (shortName) {
|
||||||
|
return shortName in this.names;
|
||||||
|
};
|
||||||
|
|
||||||
|
Characters.prototype.get = function (shortName) {
|
||||||
|
return this.names[shortName];
|
||||||
|
};
|
||||||
|
|
||||||
|
Characters.prototype.setName_2 = function (shortName, fullName) {
|
||||||
|
if (shortName in this.names) {
|
||||||
|
var info = this.names[shortName];
|
||||||
|
info.name = fullName;
|
||||||
|
} else {
|
||||||
|
this.names[shortName] = new NameInfo(fullName, this.DEFAULT_COLOR);
|
||||||
|
}
|
||||||
|
return shortName in this.names;
|
||||||
|
};
|
||||||
|
|
||||||
|
Characters.prototype.setName_3 = function (shortName, fullName, color) {
|
||||||
|
if (shortName in this.names) {
|
||||||
|
var info = this.names[shortName];
|
||||||
|
info.name = fullName;
|
||||||
|
info.color = color;
|
||||||
|
} else {
|
||||||
|
this.names[shortName] = new NameInfo(fullName, color);
|
||||||
|
}
|
||||||
|
return shortName in this.names;
|
||||||
|
};
|
||||||
|
Characters.prototype.setName = function (arg1, arg2, arg3) {
|
||||||
|
if (arguments.length === 2) return this.setName_2(arg1, arg2);
|
||||||
|
else return this.setName_2(arg1, arg2, arg3);
|
||||||
|
};
|
||||||
|
|
||||||
|
Characters.prototype.makeNamesUnknown = function () {
|
||||||
|
// https://github.com/yakui-lover/eroge-dopil/blob/master/media.rpy#L365
|
||||||
|
this.names["me"] = new NameInfo("Семён", 0xFFE1DD7D);
|
||||||
|
this.names["un"] = new NameInfo("Пионерка", 0xFFB956FF);
|
||||||
|
this.names["dv"] = new NameInfo("Пионерка", 0xFFFFAA00);
|
||||||
|
this.names["sl"] = new NameInfo("Пионерка", 0xFFFFD200);
|
||||||
|
this.names["us"] = new NameInfo("Пионерка", 0xFFFF3200);
|
||||||
|
this.names["mt"] = new NameInfo("Вожатая", 0xFF00EA32);
|
||||||
|
this.names["cs"] = new NameInfo("Медсестра", 0xFFA5A5FF);
|
||||||
|
this.names["mz"] = new NameInfo("Пионерка", 0xFF4A86FF);
|
||||||
|
this.names["mi"] = new NameInfo("Пионерка", 0xFF00DEFF);
|
||||||
|
this.names["uv"] = new NameInfo("Странная девочка", 0xFF4EFF00);
|
||||||
|
this.names["lk"] = new NameInfo("Луркмор-кун", 0xFFFF8080);
|
||||||
|
this.names["sh"] = new NameInfo("Пионер", 0xFFFFF226);
|
||||||
|
this.names["el"] = new NameInfo("Пионер", 0xFFFFFF00);
|
||||||
|
this.names["pi"] = new NameInfo("Пионер", 0xFFE60101);
|
||||||
|
|
||||||
|
this.names["dy"] = new NameInfo("Голос из динамика", 0xFFC0C0C0);
|
||||||
|
this.names["voice"] = new NameInfo("Голос", 0xFFE1DD7D);
|
||||||
|
this.names["voices"] = new NameInfo("Голоса", 0xFFC0C0C0);
|
||||||
|
this.names["message"] = new NameInfo("Сообщение", 0xFFC0C0C0);
|
||||||
|
this.names["all"] = new NameInfo("Пионеры", 0xFFED4444);
|
||||||
|
this.names["kids"] = new NameInfo("Малышня", 0xFFEB7883);
|
||||||
|
this.names["dreamgirl"] = new NameInfo("...", 0xFFC0C0C0);
|
||||||
|
this.names["bush"] = new NameInfo("Голос", 0xFFC0C0C0);
|
||||||
|
this.names["FIXME_voice"] = new NameInfo("Голос", 0xFFC0C0C0);
|
||||||
|
this.names["odn"] = new NameInfo("Одногруппник", 0xFFC0C0C0);
|
||||||
|
this.names["mt_voice"] = new NameInfo("Голос", 0xFF00EA32);
|
||||||
|
};
|
||||||
|
|
||||||
|
Characters.prototype.makeNamesKnown = function () {
|
||||||
|
this.setName("me", "Семён");
|
||||||
|
this.setName("un", "Лена");
|
||||||
|
this.setName("dv", "Алиса");
|
||||||
|
this.setName("sl", "Славя");
|
||||||
|
this.setName("us", "Ульяна");
|
||||||
|
this.setName("mt", "Ольга Дмитриевна");
|
||||||
|
this.setName("cs", "Виола");
|
||||||
|
this.setName("mz", "Женя");
|
||||||
|
this.setName("mi", "Мику");
|
||||||
|
this.setName("uv", "Юля");
|
||||||
|
this.setName("lk", "Луркмор-кун");
|
||||||
|
this.setName("sh", "Шурик");
|
||||||
|
this.setName("el", "Электроник");
|
||||||
|
this.setName("pi", "Пионер");
|
||||||
|
this.setName("dy", "Голос из динамика");
|
||||||
|
this.setName("voice", "Голос");
|
||||||
|
this.setName("voices", "Голоса");
|
||||||
|
this.setName("message", "Сообщение");
|
||||||
|
this.setName("all", "Пионеры");
|
||||||
|
this.setName("kids", "Малышня");
|
||||||
|
this.setName("dreamgirl", "...");
|
||||||
|
this.setName("bush", "Голос");
|
||||||
|
this.setName("FIXME_voice", "Голос");
|
||||||
|
this.setName("odn", "Одногруппник");
|
||||||
|
this.setName("mt_voice", "Голос");
|
||||||
|
};
|
228
public_html/resources/js/Lexer.js
Normal file
228
public_html/resources/js/Lexer.js
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/* global TokenType */
|
||||||
|
|
||||||
|
function Lexer(input) {
|
||||||
|
this.input = input;
|
||||||
|
this.tokens = [];
|
||||||
|
this.length = input.length;
|
||||||
|
this.pos = 0;
|
||||||
|
this.buffer = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Lexer.prototype.OPERATOR_CHARS = "=+-<>()[]!$:";
|
||||||
|
Lexer.prototype.OPERATOR_TYPES = [
|
||||||
|
TokenType.EQ,
|
||||||
|
TokenType.PLUS, TokenType.MINUS,
|
||||||
|
TokenType.LT, TokenType.GT,
|
||||||
|
TokenType.LPAREN, TokenType.RPAREN, TokenType.LBRACKET, TokenType.RBRACKET,
|
||||||
|
TokenType.EXCL, TokenType.COMMAND, TokenType.COLON
|
||||||
|
];
|
||||||
|
|
||||||
|
Lexer.prototype.KEYWORDS = {
|
||||||
|
"play" : TokenType.PLAY,
|
||||||
|
"queue" : TokenType.QUEUE,
|
||||||
|
"stop" : TokenType.STOP,
|
||||||
|
"music" : TokenType.MUSIC,
|
||||||
|
"ambience" : TokenType.AMBIENCE,
|
||||||
|
"sound" : TokenType.SOUND,
|
||||||
|
"sound_loop" : TokenType.SOUNDLOOP,
|
||||||
|
"fadein" : TokenType.FADEIN,
|
||||||
|
"fadeout" : TokenType.FADEOUT,
|
||||||
|
|
||||||
|
"scene" : TokenType.SCENE,
|
||||||
|
"anim" : TokenType.ANIM,
|
||||||
|
"bg" : TokenType.BG,
|
||||||
|
"cg" : TokenType.CG,
|
||||||
|
"at" : TokenType.AT,
|
||||||
|
"as" : TokenType.AS,
|
||||||
|
"define" : TokenType.DEFINE,
|
||||||
|
"window" : TokenType.WINDOW,
|
||||||
|
"hide" : TokenType.HIDE,
|
||||||
|
"show" : TokenType.SHOW,
|
||||||
|
"with" : TokenType.WITH,
|
||||||
|
|
||||||
|
"return" : TokenType.RETURN,
|
||||||
|
"menu" : TokenType.MENU,
|
||||||
|
"endmenu" : TokenType.ENDMENU,
|
||||||
|
"jump" : TokenType.JUMP,
|
||||||
|
"label" : TokenType.LABEL,
|
||||||
|
|
||||||
|
"if" : TokenType.IF,
|
||||||
|
"else" : TokenType.ELSE,
|
||||||
|
"endif" : TokenType.ENDIF,
|
||||||
|
"or" : TokenType.OR,
|
||||||
|
"and" : TokenType.AND,
|
||||||
|
"not" : TokenType.NOT,
|
||||||
|
|
||||||
|
"renpy.pause" : TokenType.RENPY_PAUSE,
|
||||||
|
"renpy.say" : TokenType.RENPY_SAY,
|
||||||
|
"persistent.sprite_time" : TokenType.PERSISTENT_SPRITE_TIME,
|
||||||
|
"prolog_time" : TokenType.PROLOG_TIME,
|
||||||
|
"day_time" : TokenType.DAY_TIME,
|
||||||
|
"sunset_time" : TokenType.SUNSET_TIME,
|
||||||
|
"night_time" : TokenType.NIGHT_TIME,
|
||||||
|
"make_names_known" : TokenType.MAKE_NAMES_KNOWN,
|
||||||
|
"make_names_unknown" : TokenType.MAKE_NAMES_UNKNOWN,
|
||||||
|
"set_name" : TokenType.SET_NAME,
|
||||||
|
"meet" : TokenType.SET_NAME,
|
||||||
|
"disable_all_zones" : TokenType.DISABLE_ALL_ZONES,
|
||||||
|
"disable_current_zone" : TokenType.DISABLE_CURRENT_ZONE,
|
||||||
|
"reset_zone" : TokenType.RESET_ZONE,
|
||||||
|
"set_zone" : TokenType.SET_ZONE,
|
||||||
|
"show_map" : TokenType.SHOW_MAP
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.getTokens = function () { return this.tokens; };
|
||||||
|
|
||||||
|
Lexer.prototype.process = function () {
|
||||||
|
this.pos = 0;
|
||||||
|
while (this.pos < this.length) {
|
||||||
|
this.tokenize();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.tokenize = function () {
|
||||||
|
this.skipWhitespaces();
|
||||||
|
var ch = this.peek(0);
|
||||||
|
if (ch.match(/[a-z]/i)) {
|
||||||
|
// Слово (ключевое слово или команда)
|
||||||
|
this.tokenizeWord();
|
||||||
|
} else if (ch.match(/[0-9]/i)) {
|
||||||
|
// Число
|
||||||
|
this.tokenizeNumber();
|
||||||
|
} else if (ch === '"' || ch === '\'') {
|
||||||
|
// Текст в "кавычках" или 'одинарных'
|
||||||
|
this.tokenizeText(ch);
|
||||||
|
} else if (ch === '#') {
|
||||||
|
this.tokenizeComment();
|
||||||
|
} else {
|
||||||
|
// Операторы и спецсимволы
|
||||||
|
this.tokenizeOperator();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.tokenizeWord = function () {
|
||||||
|
var ch = this.peek(0);
|
||||||
|
// Строка в юникоде u"текст" или u'текст'
|
||||||
|
if (ch === 'u') {
|
||||||
|
var textStartChar = this.peek(1);
|
||||||
|
if (textStartChar === '"' || textStartChar === '\'') {
|
||||||
|
this.next(); // u
|
||||||
|
this.tokenizeText(textStartChar);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clearBuffer();
|
||||||
|
while (ch.match(/[a-z0-9_\.]/i)) {
|
||||||
|
this.buffer += (ch);
|
||||||
|
ch = this.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
var word = this.buffer;
|
||||||
|
var key = word.toLowerCase();
|
||||||
|
if (key in this.KEYWORDS) {
|
||||||
|
this.addToken(this.KEYWORDS[key]);
|
||||||
|
} else {
|
||||||
|
this.addToken(TokenType.WORD, word);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.tokenizeNumber = function () {
|
||||||
|
var ch = this.peek(0);
|
||||||
|
this.clearBuffer();
|
||||||
|
var decimal = false;
|
||||||
|
while (true) {
|
||||||
|
// Целое или вещественное число.
|
||||||
|
if (ch === '.') {
|
||||||
|
// Пропускаем десятичные точки, если они уже были в числе.
|
||||||
|
if (!decimal) this.buffer += (ch);
|
||||||
|
decimal = true;
|
||||||
|
ch = this.next();
|
||||||
|
continue;
|
||||||
|
} else if (!ch.match(/[0-9]/i)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.buffer += (ch);
|
||||||
|
ch = this.next();
|
||||||
|
}
|
||||||
|
this.addToken(TokenType.NUMBER, this.buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.tokenizeOperator = function () {
|
||||||
|
var ch = this.peek(0);
|
||||||
|
var index = this.OPERATOR_CHARS.indexOf(ch);
|
||||||
|
if (index !== -1) {
|
||||||
|
this.addToken(this.OPERATOR_TYPES[index]);
|
||||||
|
}
|
||||||
|
this.next();
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.tokenizeText = function (textStartChar) {
|
||||||
|
this.clearBuffer();
|
||||||
|
var ch = this.next(); // пропускаем открывающую кавычку
|
||||||
|
while (true) {
|
||||||
|
if (ch === textStartChar) break;
|
||||||
|
if (ch === '\0') break; // не закрыта кавычка, но мы добавим то, что есть
|
||||||
|
if (ch === '\\') {
|
||||||
|
ch = this.next();
|
||||||
|
switch (ch) {
|
||||||
|
case 'n': ch = next(); this.buffer += ('\n'); continue;
|
||||||
|
case 't': ch = next(); this.buffer += ('\t'); continue;
|
||||||
|
default:
|
||||||
|
if (ch === textStartChar) {
|
||||||
|
ch = this.next();
|
||||||
|
this.buffer += ('"');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.buffer += ('\\');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.buffer += (ch);
|
||||||
|
ch = this.next();
|
||||||
|
}
|
||||||
|
this.next(); // пропускаем закрывающую кавычку
|
||||||
|
this.addToken(TokenType.TEXT, this.buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.tokenizeComment = function () {
|
||||||
|
var ch = this.peek(0);
|
||||||
|
while ("\n\r\0".indexOf(ch) === -1) {
|
||||||
|
ch = this.next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.skipWhitespaces = function () {
|
||||||
|
var ch = this.peek(0);
|
||||||
|
while (ch !== '\0' && ch.match(/\s/)) {
|
||||||
|
ch = this.next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.addToken_1 = function (type) {
|
||||||
|
this.addToken_2(type, "");
|
||||||
|
};
|
||||||
|
Lexer.prototype.addToken_2 = function (type, text) {
|
||||||
|
this.tokens.push(new Token(text, type));
|
||||||
|
};
|
||||||
|
Lexer.prototype.addToken = function (arg1, arg2) {
|
||||||
|
if (arguments.length === 1) this.addToken_1(arg1);
|
||||||
|
else this.addToken_2(arg1, arg2);
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.clearBuffer = function () {
|
||||||
|
this.buffer = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.next = function () {
|
||||||
|
this.pos++;
|
||||||
|
if (this.pos >= this.length) return '\0';
|
||||||
|
return this.input.charAt(this.pos);
|
||||||
|
};
|
||||||
|
|
||||||
|
Lexer.prototype.peek = function (relativePosition) {
|
||||||
|
var tempPos = this.pos + relativePosition;
|
||||||
|
if (tempPos >= this.length) return '\0';
|
||||||
|
return this.input.charAt(tempPos);
|
||||||
|
};
|
28
public_html/resources/js/Main.js
Normal file
28
public_html/resources/js/Main.js
Normal file
File diff suppressed because one or more lines are too long
397
public_html/resources/js/Parser.js
Normal file
397
public_html/resources/js/Parser.js
Normal file
@ -0,0 +1,397 @@
|
|||||||
|
/* global TokenType, ViewActivity, TextUtils */
|
||||||
|
|
||||||
|
function Parser(tokens) {
|
||||||
|
this.tokens = tokens;
|
||||||
|
this.tokensCount = tokens.length;
|
||||||
|
this.position = 0;
|
||||||
|
this.lastPosition = 0;
|
||||||
|
this.labels = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser.prototype.EOF = new Token("", TokenType.EOF);
|
||||||
|
|
||||||
|
Parser.prototype.getInstance = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.next = function () {
|
||||||
|
this.lastPosition = this.position;
|
||||||
|
|
||||||
|
var terminal = false;
|
||||||
|
var counter = 0;
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
terminal = this.statement();
|
||||||
|
} catch (re) {
|
||||||
|
console.log("Parser.next() " + re);
|
||||||
|
if (this.tokens.length === 0) return;
|
||||||
|
}
|
||||||
|
// антизацикливание
|
||||||
|
counter++;
|
||||||
|
if (counter >= 1000) {
|
||||||
|
this.position++;
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
} while (!terminal);
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.findFrom = function(from, which, step) {
|
||||||
|
var pos = from;
|
||||||
|
while (true) {
|
||||||
|
pos += step;
|
||||||
|
if (pos < 0 || pos >= this.tokensCount) break;
|
||||||
|
|
||||||
|
var token = this.tokens[pos];
|
||||||
|
if (which === token.getType()) return pos;
|
||||||
|
}
|
||||||
|
// Возвращаем текущее значение во избежание лишних проверок.
|
||||||
|
return from;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.statement = function() {
|
||||||
|
var token = this.get(0);
|
||||||
|
if (this.match(token, TokenType.COMMAND)) return this.command();
|
||||||
|
if (this.match(token, TokenType.SCENE)) return this.scene();
|
||||||
|
if (this.match(token, TokenType.PLAY)) return this.play();
|
||||||
|
// if (this.match(token, TokenType.QUEUE)) return this.queue();
|
||||||
|
// if (this.match(token, TokenType.STOP)) return this.stop();
|
||||||
|
if (this.match(token, TokenType.SHOW)) return this.show();
|
||||||
|
if (this.match(token, TokenType.HIDE)) return this.hide();
|
||||||
|
|
||||||
|
// if (this.match(token, TokenType.JUMP)) return this.jump();
|
||||||
|
// if (this.match(token, TokenType.IF)) return this.ifStatement();
|
||||||
|
|
||||||
|
/*if (this.lookMatch(1, TokenType.COLON)) {
|
||||||
|
// menu:
|
||||||
|
if (this.match(token, TokenType.MENU)) return this.menu();
|
||||||
|
|
||||||
|
// Остаток от меню выбора. Пропускаем до появления ENDMENU.
|
||||||
|
if (this.match(token, TokenType.TEXT)) {
|
||||||
|
if (this.hasEndMenu) this.position += this.skipMenu();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Остаток от условного выражения. Пропускаем до появления ENDIF.
|
||||||
|
if (this.match(token, TokenType.ELSE)) {
|
||||||
|
if (this.hasEndIf) this.position += this.skipIf();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Текст с именем автора реплики.
|
||||||
|
if (this.lookMatch(1, TokenType.TEXT) && this.match(token, TokenType.WORD)) {
|
||||||
|
var whoid = token.getText();
|
||||||
|
ViewActivity.getInstance().text(whoid, this.consume(TokenType.TEXT).getText());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обычный текст.
|
||||||
|
if (this.match(token, TokenType.TEXT)) {
|
||||||
|
ViewActivity.getInstance().text(token.getText());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.match(token, TokenType.EOF)) {
|
||||||
|
//ViewActivity.getInstance().finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.match(token, TokenType.WINDOW)) {
|
||||||
|
if (this.match(TokenType.SHOW))
|
||||||
|
return ViewActivity.getInstance().windowShow(this.matchWithEffect());
|
||||||
|
else if (this.match(TokenType.HIDE))
|
||||||
|
return ViewActivity.getInstance().windowHide(this.matchWithEffect());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(this.matchWithEffect())) return false;
|
||||||
|
|
||||||
|
this.position++;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.command = function() {
|
||||||
|
var token = this.get(0);
|
||||||
|
|
||||||
|
if (this.match(token, TokenType.RENPY_PAUSE)) {
|
||||||
|
this.consume(TokenType.LPAREN);
|
||||||
|
var pause = this.consumeDouble();
|
||||||
|
var hard = false;
|
||||||
|
if (!this.lookMatch(0, TokenType.RPAREN)) {
|
||||||
|
this.consume(TokenType.WORD); // hard
|
||||||
|
this.consume(TokenType.EQ);
|
||||||
|
hard = this.consumeBoolean();
|
||||||
|
}
|
||||||
|
this.consume(TokenType.RPAREN);
|
||||||
|
ViewActivity.getInstance().pause(Math.floor(1000 * pause), hard);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.match(token, TokenType.RENPY_SAY)) {
|
||||||
|
this.consume(TokenType.LPAREN);
|
||||||
|
var whoid = this.consume(TokenType.WORD).getText();
|
||||||
|
// TODO: this.consume(TokenType.COMMA)
|
||||||
|
var text = this.consume(TokenType.TEXT).getText();
|
||||||
|
// TODO: this.consume(TokenType.COMMA)
|
||||||
|
this.consume(TokenType.WORD); // interact
|
||||||
|
this.consume(TokenType.EQ);
|
||||||
|
var interact = this.consumeBoolean();
|
||||||
|
this.consume(TokenType.RPAREN);
|
||||||
|
ViewActivity.getInstance().text(whoid, text);
|
||||||
|
return interact;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.match(token, TokenType.PERSISTENT_SPRITE_TIME)) {
|
||||||
|
this.consume(TokenType.EQ);
|
||||||
|
this.consume(TokenType.TEXT);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.match(token, TokenType.PROLOG_TIME) ||
|
||||||
|
this.match(token, TokenType.DAY_TIME) ||
|
||||||
|
this.match(token, TokenType.SUNSET_TIME) ||
|
||||||
|
this.match(token, TokenType.NIGHT_TIME)) {
|
||||||
|
this.consume(TokenType.LPAREN);
|
||||||
|
this.consume(TokenType.RPAREN);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.match(token, TokenType.MAKE_NAMES_KNOWN) ||
|
||||||
|
this.match(token, TokenType.MAKE_NAMES_UNKNOWN)) {
|
||||||
|
this.consume(TokenType.LPAREN);
|
||||||
|
this.consume(TokenType.RPAREN);
|
||||||
|
if (token.getType() === TokenType.MAKE_NAMES_KNOWN) {
|
||||||
|
ViewActivity.getInstance().makeNamesKnown();
|
||||||
|
} else ViewActivity.getInstance().makeNamesUnknown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.match(token, TokenType.SET_NAME)) {
|
||||||
|
this.consume(TokenType.LPAREN);
|
||||||
|
var whoid = this.consume(TokenType.TEXT).getText();
|
||||||
|
// TODO: this.consume(TokenType.COMMA)
|
||||||
|
var name = this.consume(TokenType.TEXT).getText();
|
||||||
|
this.consume(TokenType.RPAREN);
|
||||||
|
ViewActivity.getInstance().meet(whoid, name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Карта
|
||||||
|
if (this.match(token, TokenType.DISABLE_ALL_ZONES)) {
|
||||||
|
this.consume(TokenType.LPAREN);
|
||||||
|
this.consume(TokenType.RPAREN);
|
||||||
|
ViewActivity.getInstance().disableAllZones();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.match(token, TokenType.DISABLE_CURRENT_ZONE)) {
|
||||||
|
this.consume(TokenType.LPAREN);
|
||||||
|
this.consume(TokenType.RPAREN);
|
||||||
|
ViewActivity.getInstance().disableCurrentZone();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.match(token, TokenType.RESET_ZONE)) {
|
||||||
|
this.consume(TokenType.LPAREN);
|
||||||
|
var zone = this.consume(TokenType.TEXT).getText();
|
||||||
|
this.consume(TokenType.RPAREN);
|
||||||
|
ViewActivity.getInstance().resetZone(zone);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.match(token, TokenType.SET_ZONE)) {
|
||||||
|
this.consume(TokenType.LPAREN);
|
||||||
|
var zone = this.consume(TokenType.TEXT).getText();
|
||||||
|
// TODO: this.consume(TokenType.COMMA)
|
||||||
|
var label = this.consume(TokenType.TEXT).getText();
|
||||||
|
this.consume(TokenType.RPAREN);
|
||||||
|
ViewActivity.getInstance().setZone(zone, label);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.match(token, TokenType.SHOW_MAP)) {
|
||||||
|
this.consume(TokenType.LPAREN);
|
||||||
|
this.consume(TokenType.RPAREN);
|
||||||
|
ViewActivity.getInstance().showMap();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (this.match(token, TokenType.WORD)) {
|
||||||
|
if (this.match(TokenType.EQ)) {
|
||||||
|
// variable = expression
|
||||||
|
Variables.setVariable(token.getText(), expression().eval());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.lookMatch(1, TokenType.EQ) && this.match(TokenType.PLUS)) {
|
||||||
|
// variable += expression
|
||||||
|
this.consume(TokenType.EQ);
|
||||||
|
var varValue = Variables.getVariable(token.getText());
|
||||||
|
Variables.setVariable(token.getText(), varValue + expression().eval());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.lookMatch(1, TokenType.EQ) && this.match(TokenType.MINUS)) {
|
||||||
|
// variable -= expression
|
||||||
|
this.consume(TokenType.EQ);
|
||||||
|
var varValue = Variables.getVariable(token.getText());
|
||||||
|
Variables.setVariable(token.getText(), varValue - expression().eval());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.scene = function() {
|
||||||
|
var type = "";
|
||||||
|
if (this.match(TokenType.BG)) type = "bg";
|
||||||
|
else if (this.match(TokenType.CG)) type = "cg";
|
||||||
|
else if (this.match(TokenType.ANIM)) type = "anim";
|
||||||
|
|
||||||
|
var name = this.consume(TokenType.WORD).getText();
|
||||||
|
var effect = this.matchWithEffect();
|
||||||
|
ViewActivity.getInstance().background(type, name, effect);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.show = function() {
|
||||||
|
var whoid = this.consume(TokenType.WORD).getText();
|
||||||
|
var params = ""; // emotion? cloth? distance?
|
||||||
|
while (this.lookMatch(0, TokenType.WORD)) {
|
||||||
|
var text = this.consume(TokenType.WORD).getText();
|
||||||
|
params += text;
|
||||||
|
if (text.equals("close") || text.equals("far")) break;
|
||||||
|
}
|
||||||
|
// Положение (left, cleft, ...)
|
||||||
|
var position = "";
|
||||||
|
if (this.match(TokenType.AT)) {
|
||||||
|
position = this.consume(TokenType.WORD).getText();
|
||||||
|
}
|
||||||
|
// Псевдоним (для показа одно и того же спрайта в разных местах)
|
||||||
|
var alias = "";
|
||||||
|
if (this.match(TokenType.AS)) {
|
||||||
|
alias = this.consume(TokenType.WORD).getText();
|
||||||
|
}
|
||||||
|
var effect = this.matchWithEffect();
|
||||||
|
ViewActivity.getInstance().sprite(whoid, params, position, alias, effect);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.hide = function() {
|
||||||
|
var whoid = this.consume(TokenType.WORD).getText();
|
||||||
|
var effect = this.matchWithEffect();
|
||||||
|
ViewActivity.getInstance().hideSprite(whoid, effect);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.play = function() {
|
||||||
|
if (this.match(TokenType.MUSIC)) return this.playMusic();
|
||||||
|
if (this.match(TokenType.AMBIENCE)) return this.playAmbience();
|
||||||
|
if (this.lookMatch(0, TokenType.SOUND) || this.lookMatch(0, TokenType.SOUNDLOOP)) {
|
||||||
|
return this.playSound();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.playMusic = function() {
|
||||||
|
var name = this.consumeMusicName();
|
||||||
|
var fade = this.matchFade();
|
||||||
|
ViewActivity.getInstance().music(name, fade);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.playSound = function() {
|
||||||
|
var loop = false;
|
||||||
|
if (this.match(TokenType.SOUND)) loop = false;
|
||||||
|
else if (this.match(TokenType.SOUNDLOOP)) loop = true;
|
||||||
|
|
||||||
|
var name = this.consumeMusicName();
|
||||||
|
var fade = this.matchFade();
|
||||||
|
ViewActivity.getInstance().sound(name, loop, fade);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.playAmbience = function() {
|
||||||
|
var name = this.consumeMusicName();
|
||||||
|
var fade = this.matchFade();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Parser.prototype.consumeMusicName = function() {
|
||||||
|
var name = "";
|
||||||
|
if (this.lookMatch(1, TokenType.LBRACKET)) {
|
||||||
|
// music_list["music"]
|
||||||
|
this.consume(TokenType.WORD);
|
||||||
|
this.consume(TokenType.LBRACKET);
|
||||||
|
name = this.consume(TokenType.TEXT).getText();
|
||||||
|
this.consume(TokenType.RBRACKET);
|
||||||
|
} else if (this.lookMatch(0, TokenType.TEXT)) {
|
||||||
|
name = this.consume(TokenType.TEXT).getText();
|
||||||
|
} else {
|
||||||
|
name = this.consume(TokenType.WORD).getText();
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.matchFade = function() {
|
||||||
|
var result = new FadeInfo();
|
||||||
|
if (this.match(TokenType.FADEIN)) {
|
||||||
|
result.fadeIn = true;
|
||||||
|
result.duration = this.consumeDouble();
|
||||||
|
} else if (this.match(TokenType.FADEOUT)) {
|
||||||
|
result.fadeOut = true;
|
||||||
|
result.duration = this.consumeDouble();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.matchWithEffect = function() {
|
||||||
|
if (this.match(TokenType.WITH)) {
|
||||||
|
return this.consume(TokenType.WORD).getText();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.consumeDouble = function() {
|
||||||
|
return parseFloat(this.consume(TokenType.NUMBER).getText());
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.consumeBoolean = function() {
|
||||||
|
return "true" === (this.consume(TokenType.NUMBER).getText().toLowerCase());
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.matchWithEffect = function() {
|
||||||
|
if (this.match(TokenType.WITH)) {
|
||||||
|
return this.consume(TokenType.WORD).getText();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.match_1 = function(type) {
|
||||||
|
if (this.get(0).getType() !== type) return false;
|
||||||
|
this.position++;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
Parser.prototype.match_2 = function(token, type) {
|
||||||
|
if (type !== token.getType()) return false;
|
||||||
|
this.position++;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
Parser.prototype.match = function(arg1, arg2) {
|
||||||
|
if (arguments.length === 1) return this.match_1(arg1);
|
||||||
|
else return this.match_2(arg1, arg2);
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.consume = function(type) {
|
||||||
|
if (this.get(0).getType() !== type) throw "Ожидался токен " + type + ".";
|
||||||
|
return this.tokens[this.position++];
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.lookMatch = function(pos, type) {
|
||||||
|
return (type === this.get(pos).getType());
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.get = function(offset) {
|
||||||
|
if (this.position + offset >= this.tokensCount) return this.EOF;
|
||||||
|
return this.tokens[this.position + offset];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
12
public_html/resources/js/Token.js
Normal file
12
public_html/resources/js/Token.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function Token(text, type) {
|
||||||
|
this.text = text;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token.prototype.getText = function () { return this.text; };
|
||||||
|
|
||||||
|
Token.prototype.getType = function () { return this.type; };
|
||||||
|
|
||||||
|
Token.prototype.toString = function () {
|
||||||
|
return this.type + " " + this.text;
|
||||||
|
};
|
76
public_html/resources/js/TokenType.js
Normal file
76
public_html/resources/js/TokenType.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
TokenType = {
|
||||||
|
COMMAND : 1, // начинается с $
|
||||||
|
WORD : 2,
|
||||||
|
TEXT : 3,
|
||||||
|
NUMBER : 4,
|
||||||
|
|
||||||
|
// операторы и спецсимволы
|
||||||
|
EQ : 5,
|
||||||
|
PLUS : 6,
|
||||||
|
MINUS : 7,
|
||||||
|
LT : 8,
|
||||||
|
GT : 9,
|
||||||
|
LPAREN : 10,
|
||||||
|
RPAREN : 11,
|
||||||
|
LBRACKET : 12,
|
||||||
|
RBRACKET : 13,
|
||||||
|
EXCL : 14,
|
||||||
|
COLON : 15,
|
||||||
|
|
||||||
|
// ключевые слова
|
||||||
|
PLAY : 16,
|
||||||
|
QUEUE : 17,
|
||||||
|
STOP : 18,
|
||||||
|
MUSIC : 19,
|
||||||
|
AMBIENCE : 20,
|
||||||
|
SOUND : 21,
|
||||||
|
SOUNDLOOP : 22,
|
||||||
|
FADEIN : 23,
|
||||||
|
FADEOUT : 24,
|
||||||
|
|
||||||
|
SCENE : 25,
|
||||||
|
ANIM : 26,
|
||||||
|
BG : 27,
|
||||||
|
CG : 28,
|
||||||
|
|
||||||
|
WINDOW : 29,
|
||||||
|
HIDE : 30,
|
||||||
|
SHOW : 31,
|
||||||
|
|
||||||
|
AT : 32,
|
||||||
|
AS : 33,
|
||||||
|
WITH : 34,
|
||||||
|
DEFINE : 35,
|
||||||
|
|
||||||
|
MENU : 36,
|
||||||
|
ENDMENU : 37,
|
||||||
|
JUMP : 38,
|
||||||
|
LABEL : 39,
|
||||||
|
RETURN : 40,
|
||||||
|
|
||||||
|
IF : 41,
|
||||||
|
ELSE : 42,
|
||||||
|
ENDIF : 43,
|
||||||
|
OR : 44,
|
||||||
|
AND : 45,
|
||||||
|
NOT : 46,
|
||||||
|
|
||||||
|
// команды
|
||||||
|
RENPY_PAUSE : 47,
|
||||||
|
RENPY_SAY : 48,
|
||||||
|
PERSISTENT_SPRITE_TIME : 49,
|
||||||
|
PROLOG_TIME : 50,
|
||||||
|
DAY_TIME : 51,
|
||||||
|
SUNSET_TIME : 52,
|
||||||
|
NIGHT_TIME : 53,
|
||||||
|
MAKE_NAMES_KNOWN : 54,
|
||||||
|
MAKE_NAMES_UNKNOWN : 55,
|
||||||
|
SET_NAME : 56,
|
||||||
|
DISABLE_ALL_ZONES : 57,
|
||||||
|
DISABLE_CURRENT_ZONE : 58,
|
||||||
|
RESET_ZONE : 59,
|
||||||
|
SET_ZONE : 60,
|
||||||
|
SHOW_MAP : 61,
|
||||||
|
|
||||||
|
EOF : 63
|
||||||
|
};
|
46
public_html/resources/js/Transitions.js
Normal file
46
public_html/resources/js/Transitions.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
function Transition(type) {
|
||||||
|
this.type = type;
|
||||||
|
};
|
||||||
|
|
||||||
|
Transition.prototype.TYPE_FADE = 0;
|
||||||
|
Transition.prototype.TYPE_DISSOLVE = 1;
|
||||||
|
|
||||||
|
var transitions = {
|
||||||
|
"fade": {
|
||||||
|
"type": Transition.TYPE_FADE,
|
||||||
|
"outTime": 500,
|
||||||
|
"holdTime": 0,
|
||||||
|
"inTime": 500
|
||||||
|
},
|
||||||
|
"fade2": {
|
||||||
|
"type": Transition.TYPE_FADE,
|
||||||
|
"outTime": 1000,
|
||||||
|
"holdTime": 0,
|
||||||
|
"inTime": 1000
|
||||||
|
},
|
||||||
|
"fade3": {
|
||||||
|
"type": Transition.TYPE_FADE,
|
||||||
|
"outTime": 1500,
|
||||||
|
"holdTime": 0,
|
||||||
|
"inTime": 1500
|
||||||
|
},
|
||||||
|
|
||||||
|
"dspr": {
|
||||||
|
"type": Transition.TYPE_FADE,
|
||||||
|
"outTime": 200,
|
||||||
|
"holdTime": 0,
|
||||||
|
"inTime": 200
|
||||||
|
},
|
||||||
|
"dissolve": {
|
||||||
|
"type": Transition.TYPE_FADE,
|
||||||
|
"outTime": 1000,
|
||||||
|
"holdTime": 0,
|
||||||
|
"inTime": 1000
|
||||||
|
},
|
||||||
|
"dissolve2": {
|
||||||
|
"type": Transition.TYPE_FADE,
|
||||||
|
"outTime": 2000,
|
||||||
|
"holdTime": 0,
|
||||||
|
"inTime": 2000
|
||||||
|
}
|
||||||
|
};
|
73
public_html/resources/js/Utils.js
Normal file
73
public_html/resources/js/Utils.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
function FadeInfo() {
|
||||||
|
this.fadeIn = false;
|
||||||
|
this.fadeOut = false;
|
||||||
|
this.duration = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function TextUtilsImpl() { }
|
||||||
|
|
||||||
|
TextUtilsImpl.prototype.isEmpty = function (text) {
|
||||||
|
if (text === undefined) return true;
|
||||||
|
return text.length === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
var TextUtils = new TextUtilsImpl();
|
||||||
|
|
||||||
|
|
||||||
|
String.prototype.equalsIgnoreCase = function(text) {
|
||||||
|
return this.toLowerCase() == text.toLowerCase();
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.equals = function(text) {
|
||||||
|
return this == text;
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.contains = function(text) {
|
||||||
|
return this.indexOf(text) >= 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*String.prototype.startsWith = function(text) {
|
||||||
|
return this.indexOf(text) == 0;
|
||||||
|
};*/
|
||||||
|
|
||||||
|
String.prototype.replaceAll = function (find, replace) {
|
||||||
|
var str = this;
|
||||||
|
return str.replace(new RegExp(find, 'g'), replace);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function toColor(num) {
|
||||||
|
num >>>= 0;
|
||||||
|
var b = num & 0xFF,
|
||||||
|
g = (num & 0xFF00) >>> 8,
|
||||||
|
r = (num & 0xFF0000) >>> 16,
|
||||||
|
a = ( (num & 0xFF000000) >>> 24 ) / 255 ;
|
||||||
|
return "rgba(" + [r, g, b, a].join(",") + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var PathResolver = new function () {
|
||||||
|
this.background = function (type, name) {
|
||||||
|
return "resources/images/" + type.toLowerCase() + "/" + name + ".jpg";
|
||||||
|
};
|
||||||
|
this.sprite = function (whoid, params) {
|
||||||
|
var path = "file:///E:/everlastingsummer/sprites/";
|
||||||
|
path += whoid.toLowerCase() + "/";
|
||||||
|
path += (TextUtils.isEmpty(params) ? "normal" : params);
|
||||||
|
path += ".png";
|
||||||
|
return path;
|
||||||
|
};
|
||||||
|
this.music = function (name) {
|
||||||
|
// return "resources/music/" + name + ".ogg";
|
||||||
|
return "file:///E:/everlastingsummer/music/" + name + ".ogg";
|
||||||
|
};
|
||||||
|
this.sound = function (name) {
|
||||||
|
var path = "file:///E:/everlastingsummer/sfx/";
|
||||||
|
if (path.startsWith("sfx_")) path += name.substring(4);
|
||||||
|
else path += name;
|
||||||
|
path += ".ogg";
|
||||||
|
return path;
|
||||||
|
// return "resources/music/" + name + ".ogg";
|
||||||
|
};
|
||||||
|
};
|
272
public_html/resources/js/Views.js
Normal file
272
public_html/resources/js/Views.js
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/* global TextUtils, PathResolver, ViewActivity, transitions, Transition */
|
||||||
|
|
||||||
|
function Views(parser) {
|
||||||
|
this.parser = parser;
|
||||||
|
this.screenWidth = window.innerWidth;
|
||||||
|
this.screenHeight = window.innerHeight;
|
||||||
|
|
||||||
|
this.backgroundTag = document.getElementById("background");
|
||||||
|
this.windowTag = document.getElementById("window");
|
||||||
|
this.textAuthorTag = document.getElementById("textAuthor");
|
||||||
|
this.textContentTag = document.getElementById("textContent");
|
||||||
|
|
||||||
|
this.musicPlayerAudio = new Audio();
|
||||||
|
this.soundPlayerAudio = new Audio();
|
||||||
|
|
||||||
|
this.backgroundName = "";
|
||||||
|
this.backgroundType = "";
|
||||||
|
this.characters = new Characters();
|
||||||
|
this.characters.makeNamesKnown();
|
||||||
|
|
||||||
|
this.useSpriteTransitions = true;
|
||||||
|
this.spriteInContainer = {};
|
||||||
|
|
||||||
|
this.blockTap = false;
|
||||||
|
this.cancelNextStep = false;
|
||||||
|
this.nextCommandRunnable = function () {
|
||||||
|
Views.blockTap = false;
|
||||||
|
if (!Views.cancelNextStep) parser.next();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Views.prototype.getInstance = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Views.prototype.onTouch = function (e) {
|
||||||
|
if (this.blockTap) return;
|
||||||
|
|
||||||
|
this.cancelNextStep = true;
|
||||||
|
this.parser.next();
|
||||||
|
};
|
||||||
|
|
||||||
|
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("");
|
||||||
|
|
||||||
|
var animationTime = 0;
|
||||||
|
if (name.equalsIgnoreCase("black")) {
|
||||||
|
this.backgroundTag.style.background = "black";
|
||||||
|
} else if (name.equalsIgnoreCase("white")) {
|
||||||
|
this.backgroundTag.style.background = "white";
|
||||||
|
} else {
|
||||||
|
this.backgroundTag.style.background = 'url("' + PathResolver.background(type, name) + '") no-repeat center center fixed';
|
||||||
|
this.backgroundTag.style.backgroundSize = 'cover';
|
||||||
|
}
|
||||||
|
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: " + this.screenHeight + "px;" });
|
||||||
|
this.spriteInContainer[key] = img;
|
||||||
|
}
|
||||||
|
var path = PathResolver.sprite(whoid, params);
|
||||||
|
try {
|
||||||
|
//if (useSpriteTransitions) ((AnimatableImageView)img).setImageBitmap(bitmap, effect);
|
||||||
|
//else img.setImageBitmap(bitmap);
|
||||||
|
img.one("load", function() {
|
||||||
|
ViewActivity.getInstance().setSpritePosition($(this), position);
|
||||||
|
});
|
||||||
|
img.attr('src', path);
|
||||||
|
if (!$.contains($('#container'), img))
|
||||||
|
$('#container').append(img);
|
||||||
|
if (effect in transitions) {
|
||||||
|
var transition = transitions[effect];
|
||||||
|
if (transition["type"] === Transition.TYPE_FADE) {
|
||||||
|
img.hide().fadeIn(transition["inTime"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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();
|
||||||
|
}
|
||||||
|
delete this.spriteInContainer[whoid];
|
||||||
|
};
|
||||||
|
|
||||||
|
Views.prototype.setSpritePosition = function (img, position) {
|
||||||
|
var width = this.screenWidth;
|
||||||
|
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(arg1);
|
||||||
|
else this.text_2(arg1, arg2);
|
||||||
|
};
|
||||||
|
|
||||||
|
Views.prototype.formatString = function (tag, text) {
|
||||||
|
var edited = text.replaceAll("\\{w.*?\\}", "");
|
||||||
|
if (edited.contains("{center}")) {
|
||||||
|
edited = text.replaceAll("\\{center\\}", "");
|
||||||
|
this.textContentTag.style.textAlign = "center";
|
||||||
|
} else {
|
||||||
|
this.textContentTag.style.textAlign = "left";
|
||||||
|
}
|
||||||
|
if (edited.contains("{html}")) {
|
||||||
|
edited = edited.replaceAll("\\{html\\}", "");
|
||||||
|
return edited;
|
||||||
|
}
|
||||||
|
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.replace("{"+ch+"}", "<"+ch+">");
|
||||||
|
edited = edited.replace("{/"+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 () {
|
||||||
|
};
|
||||||
|
|
||||||
|
Views.prototype.disableCurrentZone = function () {
|
||||||
|
};
|
||||||
|
|
||||||
|
Views.prototype.resetZone = function (zone) {
|
||||||
|
};
|
||||||
|
|
||||||
|
Views.prototype.setZone = function (name, label) {
|
||||||
|
};
|
||||||
|
|
||||||
|
Views.prototype.showMap = function () {
|
||||||
|
};
|
||||||
|
|
||||||
|
Views.prototype.menu = function (menu) {
|
||||||
|
};
|
||||||
|
|
||||||
|
Views.prototype.music = function (name, fade) {
|
||||||
|
// !musicPlayerAudio.paused;
|
||||||
|
this.musicPlayerAudio.src = PathResolver.music(name);
|
||||||
|
this.musicPlayerAudio.play();
|
||||||
|
if (fade.fadeIn || fade.fadeOut) {
|
||||||
|
var startVolume = fade.fadeIn ? 0.0 : 1.0;
|
||||||
|
$(this.musicPlayerAudio).prop("volume", startVolume);
|
||||||
|
var targetVolume = fade.fadeIn ? 1.0 : 0.0;
|
||||||
|
$(this.musicPlayerAudio).animate({volume: targetVolume}, fade.duration * 1000);
|
||||||
|
}
|
||||||
|
};
|
5
public_html/resources/js/jquery-1.11.3.min.js
vendored
Normal file
5
public_html/resources/js/jquery-1.11.3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user