//viewport
//x, y, w, h
//repeat //折り返し表示の有無 overflow してる場合反対側に表示するか
//size(w,h);//
//repeat(mode);
//setPos(px,py);実座標をスプライト座標としてviewportの左上をどこに置くか指定
//viewtoReal(x,y)ビューポート変換後の画面表示座標
//(スプライト座標!=画面表示座標とする処理
//戻り値{x:,y:表示座標,in:(true:表示範囲内(false:表示範囲外)}
//スプライト座標!=画面表示座標とする処理\
//ワールド座標系として管理して表示する場合\
//これを通してビューポート内にあるスプライトのみ表示する
/**
* @class
* @classdesc
* ワールド座標系と実際の画面表示座標系の変換を管理するクラスです。<br>\
* ゲーム内のスプライトがどの位置にあり、画面のどこに表示されるべきか、<br>\
* また、表示範囲内にあるかどうかの判定を行います。
*/
class viewport {
/**
* homeposition x (leftup)
* @type {number}
* @description
* ワールド座標系におけるビューポート(左上)の水平基準位置
*/
x;
/**
* homeposition y (leftup)
* @type {number}
* @description
* ワールド座標系におけるビューポート(左上)の垂直基準位置
*/
y;
/**
* viewport size width
* @type {number}
* @description
* ビューポートの表示領域幅
*/
w;
/**
* viewport size height
* @type {number}
* @description
* ビューポートの表示領域高さ
*/
h;
/**
* border size x
* @type {number}
* @description
* ビューポート周囲の余白幅
*/
bmw;
/**
* border size y
* @type {number}
* @description
* ビューポート周囲の余白高さ
*/
bmh;
/**
* @constructor
*/
constructor() {
let x_, y_, w_, h_, bmw_, bmh_, repeat_ = true;
x_ = 0; y_ = 0, bmw_ = 0, bmh_ = 0;
this.x = 0;
this.y = 0;
this.w = w_;
this.h = h_;
this.bmw = bmw_;
this.bmh = bmh_;
const update = () => {
this.x = x_;
this.y = y_;
this.w = w_;
this.h = h_;
this.bmw = bmw_;
this.bmh = bmh_;
}
/**
* Repeat Mode Enable
* @method
* @param {boolean} [mode=true] 有効/無効
* @description
* ビューポートの繰り返しモードを有効/無効にします。<br>\
* このモードが`true`の場合、画面外に出たオブジェクトが反対側から現れるように<br>\
* 座標が折り返して計算されます。
*/
this.repeat = function (mode = true) {
repeat_ = mode;
};
/**
* Set viewport size
* @method
* @param {number} w 表示領域幅
* @param {number} h 表示領域高さ
* @description
* ビューポートの表示領域の幅と高さを設定します。<br>\
* 通常、これはゲームの実際の画面解像度に合わせて設定され、<br>\
* 表示可能な範囲を定義します。
*/
this.size = function (w, h) {
w_ = w; h_ = h;
update();
};
/**
* SetHomePotition
* @method
* @param {number} x 基準位置X
* @param {number} y 基準位置Y
* @description
* ワールド座標系におけるビューポートの基準位置(左上)を設定します。<br>\
* この位置を移動させることで、ゲームの世界をスクロールさせたり<br>\
* カメラの視点を変更したりできます。
*/
this.setPos = function (x, y) {
x_ = x; y_ = y;
update();
};
/**
* set border margin
* @method
* @param {number} w 余白幅
* @param {number} h 余白高さ
* @description
* 表示範囲の判定に使用する、ビューポート周囲の余白を設定します。<br>\
* オブジェクトがこの余白範囲から外に出るまで<br>\
* ビューポート内に存在すると判定されます。
*/
this.border = function (w, h) {
bmw_ = w; bmh_ = h;
update();
};
/**
* viewport.viewtoReal Result
* @typedef {object} viewportResult チェック結果
* @property {number} x 表示領域内での座標X
* @property {number} y 表示領域内での座標Y
* @property {boolean} in 表示領域内+余白の中かどうか
* @description ワールド座標から実画面座標に変換
*/
/**
* in viewport check and positionConvert
* @method
* @param {number} sx ワールド座標X
* @param {number} sy ワールド座標Y
* @returns {viewportResult}
* @description
* ワールド座標を実際の画面表示座標に変換し、ビューポート内にあるかを判定します。<br>\
* スプライトなどのワールド座標をこのメソッドに通すことで、<br>\
* 正しい画面上の位置と表示可否の情報を取得できます。
*/
this.viewtoReal = function (sx, sy) {
let rx = sx + x_;
let ry = sy + y_;
let f = false;
if (repeat_) { // repeat true;
if (rx < 0) rx = w_ + rx;
if (rx > w_) rx = rx % w_;
if (ry < 0) ry = h_ + ry;
if (ry > h_) ry = ry % h_;
}
f = (rx + bmw_ < 0 || rx > w_ + bmw_ || ry + bmh_ < 0 || ry > h_ + bmh_) ? false : true;
//console.log("x" + x_ + ",y" + y_ + ",w" + w_);
return { x: rx, y: ry, in: f };
};
}
}