アフィリエイト広告を利用しています
最新記事
検索
プロフィール
てぅちかさんの画像
てぅちか
  • ・禁煙4年目
  • ・禁パチ挫折
  • ・禁睡眠薬2年目
  • ・猫様との同居生活2年目

 ブログランキング・にほんブログ村へ

にほんブログ村 ゲームブログ ブラウザゲームへ
にほんブログ村 IT技術ブログ JavaScriptへ
プロフィール
最新コメント
現在HTML調整中・・・・・・ by てぅちか (04/16)
月別アーカイブ
タグクラウド
ブログはこちらからお借りしてます A8ネット A8ネット サーバーはこちらを……借りたい ミックスホスト ミックスホスト エックスサーバー エックスサーバー

広告

posted by fanblog

2021年05月31日

【ばいん】解説【ばいん】

前回アップしたものをスマホでみると確認できるおかしな挙動を直すには、スプライトのサイズ指定をピクセルでがっちがちに指定してあげればいいのかな?
ピクセルと拡縮率とが混ざった指定をしていたので、そのあたりを見直そうと思います。

その前に前回の動きに至った経緯をまとめるぞー。

■参考サイト

にほんブログ村 IT技術ブログ JavaScriptへ 憧れサーバーその1その2
前回のおさらい
お手玉テスト http://juz.r.ribbon.to/teutika/01otedama04.html
スマホで見るとにゅーいんにゅいんした上で、落ちるとべこんべこんします。

I did it !

  • ボールサイズを可変にする
  • 衝突時にボールを歪ませる
  • まとめ

ボールサイズを可変にする

ボールをばいんばいんさせるにあたって、
元のサイズを保持しておきたかったので変数に入れておきました。
それを、ボールをスプライト化するときの幅と高さに代入します。
1| //ステージサイズ、ボールサイズ
2| const stageW = 400;
3| const stageH = 600;
4| const ballW = 150;
5| const ballH = 150;

57| ball.width = ballW; //ボールの大きさ
58| ball.height = ballH;


ボールをつついたら一瞬大きくなって欲しいので、「ball.on()」の中に1.1倍になる様記述。
62|  score++;
63|  ballVy = -10;
64|  ball.scale.x = 1.1; //クリックで変形
65|  ball.scale.y = 1.1;

これでつついたらボールがぐんと巨大化しました!!

そしてそのまま戻りません。
当然ですね。

と言うわけで次は元に戻しますよ。

124|   //クリックでのボール変形回復用 誤差1まで戻す
125|  if (ball.width < ballW && ballW - ball.width > 1) {
126|   ball.width += 2;
127|  }
128|  else if (ball.width > ballW && ballW - ball.width < -1) {
129|   ball.width -= 2;
130|  }
131|  if (ball.height < ballH && ballH - ball.height > 1) {
132|   ball.height += 2;
133|  }
134|  else if (ball.height > ballH && ballH - ball.height < -1) {
135|   ball.height -= 2;
136|  }

と、メインの「gameLoop()」の中に記述します。
やってることは以下の通り。
124|   //クリックでのボール変形回復用 誤差1まで戻す
125|  もし、今のボールの横幅が元の幅より小さくて、元の幅との差が1より大きければ{
126|   ボール幅に2加算;
127|  }
128|  もしくは、元幅より大きくて、差が1より大きければ) {
129|   ボール幅に2減算;
130|  }
131|  以下、高さで同文

加減算の値で元に戻るまでのアニメスピードが変わります。
現状パソコンで確認する限りは2がちょうどよさげです。

おそらく、ここがピクセル指定なのに対し、クリック時のスケール変化が拡縮率指定なのがスマホで見たときの違和感の原因だと思います。
直すのは次回次回。

衝突時にボールを歪ませる

次は壁にぶつかったときにボールを壁側にぎゅむっと潰してゆがませたいのですが……
回転しているので、ボール自身の幅や高さを変えるだけでは違和感が出るはず。

なので、コンテナを一個はさんでボールを配置するようにして、
回転はボールに、壁バウンドでのゆがみをコンテナに受け持ってもらおう!
42|  const gameScene = new PIXI.Container();//ゲームシーン生成
43|  app.stage.addChild(gameScene); //ゲームシーンをステージに追加
44|  const gameBall = new PIXI.Container(); //ボールゆがみ用コンテナ生成
45|  gameBall.width = stageW;
46|  gameBall.height = stageH;
47|  gameScene.addChild(gameBall); //入れ子で追加
48|  const background = new PIXI.Graphics()//確認用背景
49|     .beginFill(0xffffff)
50|     .drawRect(0, 0, 50, 50)
51|     .endFill();
52|  gameBall.addChild(background);

77|  gameBall.addChild(ball); //ボールをゲームシーンに追加

そう考えての所業がこの形です。
「createGameScene()」の中でゲームシーンのコンテナ「gameScene」を作ったら、ゆがみ用コンテナ「gameBall」を作ります。
そして「gameBall」コンテナの中に、改めてボールを配置しました。

動きが確定するまではちっちゃい白い四角を左上に配置して、コンテナの動きを確認できるようにしています。

ボールが壁にぶつかるたびにコンテナ縦横を圧縮して見たところ
なかなかそれっぽい動きになりました!
が、たぶんスマホではうまく動いていないんですよね。うーん。これも課題です。

ひとまず
ボールが右壁にぶつかった時の挙動を書きましょう。
138|  //壁衝突X
139|  let mathR = Math.abs(ballR); //回転速度の絶対値取得
140|  var temp = mathR - 0.001; //回転速度を減衰
141|  if (ball.x > stageW - ball.width / 2) { //X方向 右壁で反射
142|   if (ballR >= -0.1 && ballR < 0) ballR = -temp; //左回転に
143|   else if (ballR <= 0.1 && ballR >= 0) ballR = -temp; //左回転に
144|   if (ballVx > 5) { //ボールのゆがみ 速い衝突
145|   ball.scale.x = 1.1;
146|   gameBall.scale.x = 0.8;//コンテナ変形 右基準
147|   gameBall.x = stageW - (stageW * gameBall.scale.x);
148|   } else {  //ゆがみ 遅い
149|   gameBall.scale.x = 0.95;//コンテナ変形 右基準
150|   gameBall.x = stageW - (stageW * gameBall.scale.x);
151|   }

152|   ball.x = stageW - ball.width / 2;
153|   ballVx = -ballVx;//X反転
154|  }

ゲームのメイン「gameLoop()」の中に記述している壁にぶつかった時の処理に追記します。
回転についての記述の後、ボールの横移動量に応じたゆがみを発生させます。

「ballVx」が5を越えてるときは
  • ボール自体の幅を1.1倍に
  • コンテナの横幅を0.8倍に
  • 右壁での反射なので、横幅が変わった分右に移動させて壁に接地させる

それ以外のときは
  • コンテナの横幅を0.95倍に
  • 右壁での反射なので、横幅が変わった分右に移動させて壁に接地させる

この処理を書いた後で、「ball.x」と「ballVx」に値を入れていきます。
回転速度と一緒に先に書いてしまうと、反射時にブレが出るので注意です。

こうしてまとめていると、ボール自体の幅1.1倍いらないな。右接地の処理一本化できるな。など反省が良く見えてきますね。

なお左壁の処理は、右基準にするためのコンテナのx移動をしていないだけで右壁とほぼ同じです。
次はY方向行ってみましょう。
167|  //壁衝突Y
168|  ballVy += 0.3;//Y方向の挙動 重力
169|  if (ball.y <= ball.height / 2) {//天井を越えたら
172|   if (ballVy < -5) { //ゆがみ 速い
173|   ball.scale.x = 1.1;
174|   gameBall.scale.y = 0.9;//ボールコンテナ変形
175|   }
176|  }

天井への衝突はシンプルに。
すごく早くぶつかったときだけ、ボールの幅を1.1倍、コンテナ高さを0.9倍しています。
常に重力としてプラス方向にYを加算しているので、ボールのy位置移動はしません。

次は床。
177| if (ball.y > stageH - ball.height / 2) {//床を超えたら
178|  ball.y = stageH - ball.height / 2; //床に戻す
179|  if (ballVy > 5) { //ゆがみ 速い
180|   if (ballVx > 5) { //ゆがみ 横も速い
181|    if (ball.rotation >= -1.57 && ball.rotation < 1.57) {
182|     ball.scale.x = 1.2; //ボール変形
183|    } else {
184|     ball.scale.y = 1.2;
185|    }
186|    gameBall.scale.y = 0.8; //ボールコンテナ変形
187|   }
188|   else {
189|    ball.scale.x = 1.15; //ボール変形
190|    gameBall.scale.y = 0.9; //ボールコンテナ変形
191|   }
192|   gameBall.y = stageH - (stageH * gameBall.scale.y);
193|  } else if (ballVy > 3) {//ゆがみ 遅い
194|   ball.scale.x = 1.05;
195|   gameBall.scale.y = 0.95;
196|   gameBall.y = stageH - (stageH * gameBall.scale.y);
197|  }
198|  if (ballVy < 1 && ballVy > -1) ballVy = 0;
199|  else ballVy = -ballVy / 2; //Y 増加量極小以外跳ね返る
202| }


Vyが速くてVxも速い
  • ボールの回転に合わせて幅か高さを1.2倍
  • コンテナを0.8倍
  • コンテナ位置を下基準になるよう移動

Vyが速くてVxは速くない
  • ボール幅1.15倍
  • コンテナ0.9倍
  • コンテナ位置を下基準になるよう移動

Vyがある程度の速度
  • ボール幅1.05倍
  • コンテナ0.95倍
  • コンテナ位置を下基準になるよう移動

198、199行目は跳ね返りを掛け算で計算しているため、
静止しているようでしていない見た目になるのを避けるために書き加えました。

このあたりでボール幅やら高さをいじっているのも、スマホでのおかしな挙動に一役買ってしまっていると思うので改変予定でいます。

さてさて、壁バウンドで起こる「gameBall」コンテナのゆがみを作ってきましたが
これらが元に戻る所も記述していきましょう。
ボール自体の変形を元に戻す処理の手前、「gameLoop()」に書いていきます。
102|  //壁反射でのボールコンテナ移動変形回復用
103|  if (gameBall.scale.x != 1 || gameBall.scale.y != 1) {
104|   let i = 0.08;//戻す量 scaleの値
105|   var temp = i / (1 - gameBall.scale.x); //戻り率
106|   if (gameBall.scale.x < 1) {//小さければ
107|    gameBall.scale.x += i; //徐々に戻す
108|    gameBall.x -= gameBall.x * temp;//位置も戻す
109|    if (gameBall.scale.x >= 1) {//こえたら規定値
110|     gameBall.scale.x = 1;
111|     gameBall.x = 0;
112|     }
113|   }

毎度の翻訳です↓
102|  //壁反射でのボールコンテナ移動変形回復用
103|  もしコンテナ幅が等倍じゃない、もしくは、高さが等倍じゃないなら{
104|   変数iに0.08を入れる;//戻す量 scaleの値
105|   変数tempに「i / (1 - コンテナ幅)」を入れる; //戻り率
106|   もしコンテナ幅の大きさが等倍未満なら{
107|    コンテナ幅の大きさに i を足す; //徐々に戻す
108|    コンテナX位置から「コンテナX位置*temp」を引く;//位置も戻す
109|    もしコンテナ幅が等倍を超えたら{//こえたら規定値
110|     コンテナ幅を等倍にする;
111|     コンテナX位置を0にする;
112|     }
113|   }

「gameLoop()」に書かれているので、変数「i = 0.08」は「bameBall.scale.x」が1になるまで加算され続けます。
変数「temp」は、変化させたい値(目標-現在値)で変数i(1回の変化量)を割ることで出した、1回の処理で変化する数値の目標値から見た割合=戻り率です。分かりにくいですね。
それをコンテナの現在X位置にかけた値を、改めて現在X位置の値から引いてあげれば、コンテナの幅が等倍にもどるのに合わせてX位置も0に戻るという計算です。

解説を書いていて混乱してきました。合っているかも怪しい。数学は苦手です。

yに対してもほぼ同じ処理を続けて記述しています。

まとめ

ばいんばいんする動きを実現したいために、
「ボール」と「コンテナ」の二つに対して移動や変形を適応しています。そもそもそれが間違いかも知れないという気持ちを持ちつつ、次回は変形に使っている数値をとりあえず統一させてみようと思います。

そのための現状まとめです。

「ball」
  • 「gameBall」コンテナに子として追加したスプライト
  • 元の幅と高さは「ballW」「ballH」として150pxを指定
  • クリックで「ball.scale.x」と「ball.scale.y」を1.1倍
  • 「ballW」と比較して変形している場合、「ball.width」を2pxずつ「ballW」に近づける
  • 「ball.width」と「ballW」の差が1px未満の場合は誤差とみなしてスルー
  • 「ballH」「ball.height」も同様
  • 壁、天井に高速で衝突すると「ball.scale.x」を1.1倍
  • 床に衝突するとXY両方高速なら「ball.scale.x」角度によっては「同.y」を1.2倍
  • 床に衝突するとYが高速なら「ball.scale.x」を1.15倍
  • 床に衝突するとYがある程度の速度なら「ball.scale.x」を1.05倍


「gameBall」コンテナ
  • 「gameScene」コンテナに子として追加したコンテナ
  • 元の幅と高さはステージと同値を「stageW」「stageH」として指定
  • 「gameBall.scale.x」が等倍じゃない場合、8%ずつ加減算して等倍に戻す
  • 「gameBall.x」が0じゃない場合、スケールと同じく徐々に元に戻す
  • スケールを戻す計算で等倍を超えた場合、「gameBall.scale.x」に1を代入する。
  • 同じ場合、「gameBall.x」に0を代入する。
  • 「gameBall.scale.y」「gameBall.y」も同様。
  • 壁に高速で衝突すると「gameBall.scale.x」を0.8倍
  • 壁にそれなりの速さで衝突すると「gameBall.scale.x」を0.95倍
  • 天井に高速で衝突すると「gameBall.scale.y」を0.9倍
  • 床に衝突するとXY両方高速なら「gameBall.scale.y」を0.8倍
  • 床に衝突するとYが高速なら「gameBall.scale.y」を0.9倍
  • 床に衝突するとYがある程度の速度なら「gameBall.scale.y」を0.95倍




そんなこんなで、現状。サンプルは前回のままです。
 お手玉テスト http://juz.r.ribbon.to/teutika/01otedama04.html

PCで見ると結構面白い動きをしているように見えるんですが、まだ不自然さがありますなぁ。スマホでの見た目は言わずもがな。
まだまだ手の入れ甲斐がありますね!

エックスサーバーエックスサーバーミックスホストミックスホストにほんブログ村 にほんブログ村へたまにクリックしてくれたら励みになります
この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/10764884
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック
×

この広告は30日以上新しい記事の更新がないブログに表示されております。