465 lines
10 KiB
JavaScript
465 lines
10 KiB
JavaScript
|
|
var ScrollTextView = defineObject(BaseObject,
|
|
{
|
|
_text: null,
|
|
_moveTime: 0,
|
|
_nextTime: 0,
|
|
_isMove: false,
|
|
_scrollTextParam: null,
|
|
_factoryArray: null,
|
|
_blockArray: null,
|
|
_isAcceleration: false,
|
|
|
|
openScrollTextViewCycle: function(scrollTextParam) {
|
|
this._prepareMemberData(scrollTextParam);
|
|
this._completeMemberData(scrollTextParam);
|
|
},
|
|
|
|
moveScrollTextViewCycle: function() {
|
|
var i, count;
|
|
|
|
// 表示しきったブロックは削除
|
|
if (this._blockArray.length > 0) {
|
|
if (this._blockArray[0].isLastBlock()) {
|
|
this._blockArray.shift();
|
|
}
|
|
}
|
|
|
|
if (!this._checkMove()) {
|
|
return MoveResult.CONTINUE;
|
|
}
|
|
|
|
// 経過時間をカウントする
|
|
this._moveTime += this.getBlockInterval();
|
|
|
|
// ブロックの表示間隔を一定にするために、高速化の検出も一定の間隔で行う
|
|
if (this._moveTime % this._getBaseTime() === 0) {
|
|
if (this._isAcceleration) {
|
|
if (!Miscellaneous.isGameAcceleration()) {
|
|
this._isAcceleration = false;
|
|
}
|
|
}
|
|
else {
|
|
if (Miscellaneous.isGameAcceleration()) {
|
|
this._isAcceleration = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
count = this._blockArray.length;
|
|
for (i = 0; i < count; i++) {
|
|
this._blockArray[i].notifyTime(this._moveTime);
|
|
this._blockArray[i].moveBlock();
|
|
}
|
|
|
|
if (count === 0) {
|
|
return MoveResult.END;
|
|
}
|
|
|
|
return MoveResult.CONTINUE;
|
|
},
|
|
|
|
drawScrollTextViewCycle: function() {
|
|
var i;
|
|
var count = this._blockArray.length;
|
|
|
|
this._drawScrollWindow();
|
|
|
|
for (i = 0; i < count; i++) {
|
|
this._blockArray[i].drawBlock();
|
|
}
|
|
},
|
|
|
|
// _getBaseTimeを割り切れる数値を返す
|
|
getBlockInterval: function() {
|
|
var n;
|
|
var speedType = this._scrollTextParam.speedType;
|
|
|
|
if (this._isAcceleration) {
|
|
return 20;
|
|
}
|
|
|
|
if (speedType === SpeedType.DIRECT) {
|
|
n = 8;
|
|
}
|
|
else if (speedType === SpeedType.SUPERHIGH) {
|
|
n = 5;
|
|
}
|
|
else if (speedType === SpeedType.HIGH) {
|
|
n = 4;
|
|
}
|
|
else if (speedType === SpeedType.NORMAL) {
|
|
n = 2.5;
|
|
}
|
|
else if (speedType === SpeedType.LOW) {
|
|
n = 2;
|
|
}
|
|
else {
|
|
n = 1;
|
|
}
|
|
|
|
return n;
|
|
},
|
|
|
|
getMoveTime: function() {
|
|
return this._moveTime;
|
|
},
|
|
|
|
setNextTime: function(nextTime) {
|
|
nextTime = this._nextTime;
|
|
},
|
|
|
|
getScrollTextParam: function() {
|
|
return this._scrollTextParam;
|
|
},
|
|
|
|
_prepareMemberData: function(scrollTextParam) {
|
|
this._text = scrollTextParam.text;
|
|
this._moveTime = 0;
|
|
this._nextTime = 0;
|
|
this._isMove = false;
|
|
this._scrollTextParam = scrollTextParam;
|
|
|
|
this._factoryArray = [];
|
|
this._configureFactoryObject(this._factoryArray);
|
|
|
|
this._blockArray = [];
|
|
},
|
|
|
|
_completeMemberData: function(scrollTextParam) {
|
|
var i, count, oneblock;
|
|
var text = this._text;
|
|
|
|
while (text.length !== 0) {
|
|
// WaitBlockFactoryがthis._nextTimeを変更するため、毎回初期化している
|
|
this._nextTime = this._getBaseTime();
|
|
|
|
// テキストから一行取得する
|
|
oneblock = this._readBlock(text);
|
|
|
|
// 取得した行を処理できるオブジェクトを探す
|
|
count = this._factoryArray.length;
|
|
for (i = 0; i < count; i++) {
|
|
if (this._factoryArray[i].checkBlock(oneblock, this._blockArray, this)) {
|
|
// 行を処理できた場合は次の行を探すため抜ける
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 仮の経過時間をカウントする
|
|
this._moveTime += this._nextTime;
|
|
|
|
// 次の行の先頭のテキストを取得
|
|
text = this._nextBlock(text);
|
|
}
|
|
|
|
// 後のmoveScrollTextViewCycleのために、初期化
|
|
this._moveTime = 0;
|
|
},
|
|
|
|
_readBlock: function(text) {
|
|
var i;
|
|
var count = text.length;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
if (text.charAt(i) === '\n') {
|
|
// 改行までに存在していたテキストを取得
|
|
return text.substring(0, i);
|
|
}
|
|
}
|
|
|
|
// 改行がない場合は、これが最後の行であるためそのまま返してよい
|
|
return text;
|
|
},
|
|
|
|
_nextBlock: function(text) {
|
|
var i;
|
|
var count = text.length;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
if (text.charAt(i) === '\n') {
|
|
// 改行までに存在していたテキストを取得
|
|
return text.substring(i + 1, text.length);
|
|
}
|
|
}
|
|
|
|
return '';
|
|
},
|
|
|
|
_checkMove: function() {
|
|
if (!DataConfig.isHighPerformance()) {
|
|
return true;
|
|
}
|
|
|
|
this._isMove = !this._isMove;
|
|
|
|
return this._isMove;
|
|
},
|
|
|
|
_getBaseTime: function() {
|
|
return 40;
|
|
},
|
|
|
|
_drawScrollWindow: function() {
|
|
var textui = root.queryTextUI('messagescroll_window');
|
|
var pic = textui.getUIImage();
|
|
var n = this._scrollTextParam.margin;
|
|
var x = n;
|
|
var y = n;
|
|
var width = root.getGameAreaWidth() - (n * 2);
|
|
var height = root.getGameAreaHeight() - (n * 2);
|
|
|
|
if (pic !== null) {
|
|
WindowRenderer.drawStretchWindow(x, y, width, height, pic);
|
|
}
|
|
},
|
|
|
|
_configureFactoryObject: function(groupArray) {
|
|
groupArray.appendObject(BlockFactory.Picture);
|
|
groupArray.appendObject(BlockFactory.Wait);
|
|
|
|
// テキスト処理オブジェクトには\spaceなどの印を持たない。
|
|
// よって、最後に確認されるようにする。
|
|
groupArray.appendObject(BlockFactory.Text);
|
|
}
|
|
}
|
|
);
|
|
|
|
// BaseBlockFactoryは、ScrollBlockを作成するオブジェクト
|
|
var BaseBlockFactory = defineObject(BaseObject,
|
|
{
|
|
checkBlock: function(text, arr, parentTextView) {
|
|
return true;
|
|
}
|
|
}
|
|
);
|
|
|
|
var BlockFactory = {};
|
|
|
|
BlockFactory.Text = defineObject(BaseBlockFactory,
|
|
{
|
|
checkBlock: function(text, arr, parentTextView) {
|
|
var obj = createObject(TextScrollBlock);
|
|
|
|
obj.setBlockData(text, parentTextView);
|
|
arr.push(obj);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
);
|
|
|
|
BlockFactory.Picture = defineObject(BaseBlockFactory,
|
|
{
|
|
checkBlock: function(text, arr, parentTextView) {
|
|
var obj;
|
|
var key = this.getKey();
|
|
var c = text.match(key);
|
|
|
|
if (c !== null) {
|
|
obj = createObject(PictureScrollBlock);
|
|
obj.setBlockData(c[1], parentTextView);
|
|
arr.push(obj);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
|
|
getKey: function() {
|
|
var key = /\\pic\[(.+)\]/;
|
|
|
|
return key;
|
|
}
|
|
}
|
|
);
|
|
|
|
BlockFactory.Wait = defineObject(BaseBlockFactory,
|
|
{
|
|
checkBlock: function(text, arr, parentTextView) {
|
|
var key = this.getKey();
|
|
var c = text.match(key);
|
|
|
|
if (c !== null) {
|
|
parentTextView.setNextTime(Number(c[1]));
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
|
|
getKey: function() {
|
|
var key = /\\space\[(\d+)\]/;
|
|
|
|
return key;
|
|
}
|
|
}
|
|
);
|
|
|
|
// BaseScrollBlockは、画面上を実際に移動するオブジェクト
|
|
var BaseScrollBlock = defineObject(BaseObject,
|
|
{
|
|
_x: 0,
|
|
_y: 0,
|
|
_top: 0,
|
|
_bottom: 0,
|
|
_value: null,
|
|
_startTime: 0,
|
|
_isStart: false,
|
|
_isLast: false,
|
|
_alpha: 0,
|
|
_parentTextView: null,
|
|
|
|
setBlockData: function(value, parentTextView) {
|
|
var scrollTextParam = parentTextView.getScrollTextParam();
|
|
var n = scrollTextParam.margin;
|
|
var size = root.queryTextUI('messagescroll_window').getFont().getSize();
|
|
|
|
this._top = n;
|
|
this._bottom = root.getGameAreaHeight() - n - size;
|
|
this._x = scrollTextParam.x;
|
|
this._y = this._bottom;
|
|
this._value = value;
|
|
this._startTime = parentTextView.getMoveTime();
|
|
this._isStart = false;
|
|
this._isLast = false;
|
|
this._alpha = 0;
|
|
this._parentTextView = parentTextView;
|
|
},
|
|
|
|
moveBlock: function() {
|
|
var zone = this._getAlphaZone();
|
|
var blockInterval = this._parentTextView.getBlockInterval();
|
|
var d = Math.floor(zone / blockInterval);
|
|
var da = Math.floor(255 / d);
|
|
|
|
if (this._isLast) {
|
|
return MoveResult.END;
|
|
}
|
|
|
|
if (this._isStart) {
|
|
// 現在位置がbottom - zoneの値より大きい場合は、アルファ値を上げる
|
|
if (this._y > this._bottom - zone) {
|
|
this._alpha += da;
|
|
if (this._alpha > 255) {
|
|
this._alpha = 255;
|
|
}
|
|
}
|
|
|
|
// 現在位置がtopの値より低い場合は、アルファ値を下げる
|
|
if (this._y < this._top + zone) {
|
|
this._alpha -= da;
|
|
if (this._alpha < 0) {
|
|
this._alpha = 0;
|
|
}
|
|
}
|
|
|
|
this._y -= blockInterval;
|
|
// 現在位置が、top - zoneを超えている場合は完全に透明になっているはずだから、終了フラグを立てる
|
|
if (this._y < this._top) {
|
|
this._isLast = true;
|
|
}
|
|
}
|
|
|
|
return MoveResult.CONTINUE;
|
|
},
|
|
|
|
drawBlock: function() {
|
|
},
|
|
|
|
isLastBlock: function() {
|
|
return this._isLast;
|
|
},
|
|
|
|
notifyTime: function(time) {
|
|
if (!this._isStart) {
|
|
// 通知された時間が、ブロックが動き始めるべき時間を超えた場合
|
|
if (time >= this._startTime) {
|
|
// ブロックの動きを開始する
|
|
this._isStart = true;
|
|
}
|
|
}
|
|
},
|
|
|
|
_getAlphaZone: function() {
|
|
return 40;
|
|
}
|
|
}
|
|
);
|
|
|
|
var TextScrollBlock = defineObject(BaseScrollBlock,
|
|
{
|
|
drawBlock: function() {
|
|
var x, width, textui, color, font;
|
|
var text = this._value;
|
|
|
|
if (this._isStart) {
|
|
textui = root.queryTextUI('messagescroll_window');
|
|
color = textui.getColor();
|
|
font = textui.getFont();
|
|
|
|
if (this._x === -1) {
|
|
width = TextRenderer.getTextWidth(text, font);
|
|
x = LayoutControl.getCenterX(-1, width);
|
|
}
|
|
else {
|
|
x = this._x;
|
|
}
|
|
|
|
TextRenderer.drawAlphaText(x, this._y, text, -1, color, this._alpha, font);
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
var PictureScrollBlock = defineObject(BaseScrollBlock,
|
|
{
|
|
_pictureId: -1,
|
|
|
|
setBlockData: function(value, parentTextView) {
|
|
var i, data;
|
|
var list = root.getBaseData().getGraphicsResourceList(GraphicsType.PICTURE, false);
|
|
var count = list.getCount();
|
|
|
|
BaseScrollBlock.setBlockData.call(this, value, parentTextView);
|
|
|
|
for (i = 0; i < count; i++) {
|
|
data = list.getCollectionData(i, 0);
|
|
if (data.getName() === value) {
|
|
this._pictureId = data.getId();
|
|
}
|
|
}
|
|
},
|
|
|
|
drawBlock: function() {
|
|
var x, width, pic;
|
|
var text = this._value;
|
|
|
|
if (this._isStart) {
|
|
pic = this._getGraphics(text);
|
|
if (pic === null) {
|
|
return;
|
|
}
|
|
|
|
width = pic.getWidth();
|
|
|
|
if (this._x === -1) {
|
|
x = LayoutControl.getCenterX(-1, width);
|
|
}
|
|
else {
|
|
x = this._x;
|
|
}
|
|
|
|
pic.setAlpha(this._alpha);
|
|
pic.draw(x, this._y);
|
|
}
|
|
},
|
|
|
|
_getGraphics: function(text) {
|
|
var list = root.getBaseData().getGraphicsResourceList(GraphicsType.PICTURE, false);
|
|
|
|
return list.getCollectionDataFromId(this._pictureId, 0);
|
|
}
|
|
}
|
|
);
|