ページ 11

[Resolved] isometric scroll

Posted: 2020年2月27日(木) 00:33
by WTR
ちょっと込み入った話なんですが相談させてください。
まず説明からなんですが…

下の画像
青い部分が配置したマップタイルで、斜めのグリッドは遠景です。

image_20200226_224612.png


マップ上で、赤の線上を移動するキャラクターを、緑の線上に表示したくて
以下のプラグインを作りました。

コード: 全て選択




本質は screenX, screenY がそれぞれ、scrolledX() と scrolledY() 両方の関数になっていることで、他は相談ごとには関係ないはずです。
1画面に収まるマップであれば、これで事足りています。
が、1画面サイズを超えるマップを作って、スクロールすると問題が…

マップ座標 (x, y) = (0, 0) から (0, 8) へ、つまりマップの下方向へ移動すると
あたりまえですが下にスクロールします。
が、キャラクターは斜めに移動するのでスクロールの方向と合わなくておかしなことになります。
これをなんとかしたい。

スクロールも、キャラクターと同様に X, Y 両方の関数になるようにして方向を合わせたいです。
scrollDown() と scrollRight() を一緒に実行するようにしてみたりしたのですが
そもそも表示系が scrolledX(), scrolledY() の関数になってるので全然ダメでした。

端から筋の悪い手法なのかもという気がしなくもないですが
どうにかなりそうなら、お知恵を貸していただきたく…

あまりに大事になりそうだったらスクロール諦めるしかないかと思ってるんですが
絶対に1画面に収めないと、っていう制約があるとマップ作りのネタがきつくて…

補足
$gameMap._ofstX と $gameMap._ofstY は 独自に追加したプロパティです。
マップのメモ欄から読み取るようにしていて、添付画像の場合 <ofst: 3, 9> が設定されてますが、関係ないはず。
(赤〇 から緑〇 への座標変換のためのオフセットです)
リージョンIDが絡んでるのも、高さの疑似表現のためで、これも無関係。

Re: isometric scroll

Posted: 2020年2月27日(木) 17:23
by 剣崎 宗二
コードを見てのざっくりした所感で、回答ではなくて申し訳ないのですが…

まず、座標系の変換を行うのであれば、恐らくadjustX() adjustY()の中で行った方が宜しいかと。
これならscrolledX(), scrolledY() 自体に影響を与えられるので…

で、マップのスクロールですが、これは上記とは関係なくGame_Mapの_displayX _displayYを操作して見てください。
(この2つの値は、要は「画面の左上角が、マップのどのマスであるか」に相当します)
ただ、ScrollDownとScollLeftを同時に行ってみたのならこの場合うまくいくはずなんですが…
「そもそも表示系が scrolledX(), scrolledY() の関数になってるので全然ダメでした。」と言うのが、どういう現象を指しているのか(やってみたら何が起こったのか)を言っていただかないと何とも。

Re: isometric scroll

Posted: 2020年2月27日(木) 19:03
by WTR
剣崎 宗二 さんが書きました:まず、座標系の変換を行うのであれば、恐らくadjustX() adjustY()の中で行った方が宜しいかと。
これならscrolledX(), scrolledY() 自体に影響を与えられるので…


たしかに。
ありがとうございます。

弄ってみたのは Game_Player.prototype.updateScroll で (ここでいいのかも自信ないですが…)
とりあえず下のようにしてみました。

コード: 全て選択

   Game_Player.prototype.updateScroll = function(lastScrolledX, lastScrolledY) {
       var x1 = lastScrolledX;
       var y1 = lastScrolledY;
       var x2 = this.scrolledX();
       var y2 = this.scrolledY();
       if (y2 > y1 && y2 > this.centerY()) {
           $gameMap.scrollDown(y2 - y1);
           $gameMap.scrollRight(x2 - x1); // add
       }
       if (x2 < x1 && x2 < this.centerX()) {
           $gameMap.scrollLeft(x1 - x2);
           $gameMap.scrollDown(y2 - y1); // add
       }
       if (x2 > x1 && x2 > this.centerX()) {
           $gameMap.scrollRight(x2 - x1);
           $gameMap.scrollUp(y1 - y2); // add
       }
       if (y2 < y1 && y2 < this.centerY()) {
           $gameMap.scrollUp(y1 - y2);
           $gameMap.scrollLeft(x1 - x2); // add
       }
   };



通常であれば、下に移動して下にスクロールが発生するとき
この場合は右下にスクロールしたいので
scrollDown() + scrollRight()
の記述にしています。
が、実はコレ全然意味がなくて
実際にはキャラクターが下にしか移動していないので
x2, x1 は変化しない。scrollRight(x2 - x1) は実質動作しないです。

scrollRight(y2 - y1) なら?と思ったんですが
Y方向にしか移動していないのに scrollRight(y2 - y1) が実行されることで_displayX が変化してしまう。
_displayX が変化するということは scrolledX() が変化することになり
キャラクターの表示位置が影響受けるのでスクロールしてる間、変なところに歩いて行ってしまう。
このスクロールと表示位置の辻褄がどうしても合わせられないのです…

Re: isometric scroll

Posted: 2020年2月27日(木) 20:18
by 剣崎 宗二
その場合は移動自体に手を加える必要があると考えます。
要は先ほど申し上げたように、「下(実際は斜め下)に移動した際、scrolledX(), scrolledY() を同時に変動させる」、ですね。
(考え直した所、恐らく一番簡単なのは、screenX, screenY がそれぞれ、scrolledX() と scrolledY() 両方の関数に依存するようにした手法で、そちらではなくscrolledX() と scrolledY() をそれぞれadjustX() adjustY()に依存させる)

これなら下に移動した瞬間x2とx1、y2とy1に同時に差が出来、scrollRightとscrollDownが同時に動作するのではないでしょうか。

Re: isometric scroll

Posted: 2020年2月27日(木) 23:19
by WTR
scrolledX() と scrolledY() を同時に変動させるようにしたらうまくいきました!

ほんとの座標は変えないで、表示だけで表現するって頭から決めつけてしまってたので
きっと自分だけでは思考を切り替えられなかったと思います。

マニアック質問でダメ元だったんですが助かりました!
ありがとうございました!