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

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

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

広告

posted by fanblog

2021年05月25日

【JavaScript】ボールの挙動調整【ネチネチ】

今回は久々すぎて思い出す作業がほとんどでした。
まとめる間も指が痛い!

■参考サイト
にほんブログ村 IT技術ブログ JavaScriptへ 憧れサーバーその1その2
前回のおさらい
お手玉テスト http://juz.r.ribbon.to/teutika/01otedama02.html

I did it !

  • ソースを見直す
  • ステージとボールの位置関係調整
  • 放置して停止する挙動の調整
  • 壁にぶつかったしたときのボールの挙動
  • クリックしたときのボールの挙動調整

ソースを見直す

しばらく手を付けていなかったら、色々なことを忘れてしまっていました。
コメントもあまりきちんと書いていなかったので、なんだこりゃ?の文章も多々…。
でもそのおかげで細かいミスに気づけたので結果オーライかな!

  • ボールの端が画面外に出てる時がある
  • ボールの回転に違和感
  • ボールの主に横移動量の違和感

とりあえず気になったこの三点、ちょっと変だね直そうね。

うーん、それにしても、
この小規模スクリプトで3箇所はほぼ全部だよね!

まあ、気にせずひとつずつ見ていきましょう。

ステージとボールの位置関係調整

なんだか微妙にボールがステージからはみ出てたり、逆に端につく前にバウンドしているような気が…。下は意図的だったんですがちょっと調整しましょう。
 1|//ステージサイズ
2|const stageW = 400;
3|const stageH = 600;
4|
5|//サイズを指定してPIXI.JSアプリ呼び出し。htmlのbodyにapp.view(canvas)追加。
6|const app = new PIXI.Application({ width: stageW, height: stageH });
8|
9|//canvasのcss指定
11|app.renderer.view.style.width = stageW;
12|app.renderer.view.style.height = stageH;

今後、ボールの大きさを変更すると思うので、配置場所などを計算で出そうと思います。
なので先ずはステージサイズを変数に差し替えておきます。

35|    //6.ゲームのメインシーンを生成する関数
36| function createGameScene() {
44|  ball.anchor.set(0.5, 0.5);
45|  ball.x = stageW / 2; //ボールの配置最大400
46|  ball.y = stageH * 0.7; //最大600

ステージサイズを元に、ボールの配置は「createGameScene()」で。
アンカーを0.5にしているため、これで横中央、縦下から三分の一くらいに表示されます。

 78|  function gameLoop() {
86|   if (ball.x > stageW - ball.width / 2) { //X方向 右壁で反射
92|   if (ball.x < ball.width / 2) { //X方向 左壁で反射
100|   if (ball.y <= ball.height / 2) {//Y方向 上で反射
104|   if (ball.y > stageH - ball.height / 2) {//Y方向 下でバウンド

上下左右の壁の位置指定部分です。
アンカーが0.5=ボール中央なので、そのズレの分を加味して条件にしています。

これでとりあえずの配置は正しくなるはず!


次はボールの回転と横移動の違和感を直しましょう!
参考サイト様にて解説されていますが、今回のスクリプトは「イベント駆動開発」という考え方で組んでいます。要は、

 起点:タッチなどの入力
 処理:イベントロジック
 結果:画像や文字を出力


という分別で書いていくやり方です。
なので、「回転と横移動」を調整したいなら、
先ずはそれぞれが何を起点に起きている結果なのかを考えてみる必要があります。

 回転
 ボールをクリックした時。壁にぶつかった時。放置して停止する時。
 横移動
 ボールをクリックした時。壁にぶつかった時。放置して停止する時。


はい、どっちも一緒でした。
むしろプレイ中の全イベントの起点と言っても過言ではありません。

ではプレイ中の内容を書いている個所のほぼ全体を直していきましょうか。
もう少し具体的に言うと、ボールのX移動量「ballVx」と回転量「ballR」の数値をいじっている箇所を見直します。


放置して停止する挙動の調整

シンプルなところから見ていきます。本来のサンプルでは、放置すると画面下部に落下してゲーム終了→次の画面へ遷移。という流れなのですが、
今は放置すると下部の壁にぶつかってバウンド→徐々に停止。としています。
104|  if (ball.y > stageH - ball.height / 2) {//☆下に壁を作って落ちないようにする
105| ball.y = stageH - ball.height / 2;
106| ballVy = -ballVy / 2; //Y 落ちたら跳ね返る
107| ballVx *= 0.9; //X 摩擦で徐々に減速
108| ballR *= 0.9;
109| }

今回の頭で設定しなおしたステージサイズを使っています。
これを分かる言葉にするとこんな感じ。
104| ボールのY位置がステージ上限を越えたら
105|  ボールY位置を上限値にする  //壁
106|  Y増加量を半分にして反転させる//跳ね返る
107|  X増加量をちょこっと減らす  //摩擦で減衰
108|  回転量をちょこっと減らす

こうすると、見た目では停止していてもずっと極小になった増加量、回転量がボールに加算され続けるのがちょっと気になるのですが、ひとまずはこれでOK。

本当はストップしたら加算処理をスキップさせる様にしようかと思ったのですが、妙なところで躓いた挙句、煩雑になるだけだったのでやめました。
妙な躓きはこれ。
ss_20210524_01.png

「 t u r e 」!!

ss_20210524_02.png
正しく書くと色が変わるんですね。


壁にぶつかったしたときのボールの挙動

続いて、今度はX方向です。前項と同じく、「gameLoop()」内の壁反射処理です。
壁にぶつかったら、X増加量の反転と、回転量の反転をしたいのですが、
「スピードが上がるとボールがひたすら頭をぶつけ続ける人のように見えるのが気持ち悪いなぁ」「もう少しリアルに動いて欲しいなぁ」と思ったので少し複雑化させました。

衝突時の挙動
  • X増加量は反転
  • 回転量が小さい時だけ回転を反転
  • 反転すると回転量は少し小さくなる

82| let mathR = Math.abs(ballR); //回転速度の絶対値取得
86| if (ball.x > stageW - ball.width / 2) { //X方向 右壁で反射
87|  ball.x = stageW - ball.width / 2;
88|  ballVx = -ballVx;
89|  if (ballR >= -0.1 && ballR < 0) { ballR = -(mathR - 0.001); } //減衰して左回転に
90|  else if (ballR <= 0.1 && ballR >= 0) { ballR = -(mathR - 0.001); } //左回転に
91| }
翻訳します↓
82| 変数「mathR」に「ballR」の絶対値を入れる。
86| ボールのX位置がステージ上限を越えたら
87|  ボールX位置を上限値にする  //壁
88|  X増加量を反転させる     //跳ね返る
89|  回転量が-0.1以上0未満なら「ballR」の絶対値を減らして-の値で入れる
90|  同じく回転量が0.1以下0以上なら同上
91| }

右の壁なので、低速でぶつかった場合は左回転で返すために「-mathR」を入れています。
右回転は正、左回転は負。なので、減速をさせるために絶対値を取り出して計算してから戻しました。

高速でぶつかったときに、回転は反転せずにXだけ返すとめっちゃ早い!と言う感じがして面白いです。
でもこれをやってしまうと、高速でぶつかった後に低速でぶつかった場合「ballR = -ballR」では回転が逆転してしまうので絶対値を使いました。

89行目、90行目は高速の時以外と書けばもしかして一行にできるかしらん?
「mathR」はもっといい名前があったよなぁ。
などなど思いながら、まあ、いっか次々!


92| if (ball.x < ball.width / 2) {  //X方向 左壁で反射
93|  ball.x = ball.width / 2;
94|  ballVx = -ballVx;
95|  if (ballR >= -0.1 && ballR < 0) { ballR = mathR - 0.001; } //減衰して右回転に
96|  else if (ballR <= 0.1 && ballR >= 0) { ballR = mathR - 0.001; } //右回転に
97| }

はい、こちらは左の壁です。やってることは右と同じ。
右回転で返したいので、回転量の正負が逆になっているだけですね。


クリックしたときのボールの挙動調整

次はクリック時の処理なので、createGameScene()内のball.on()内を見ていきましょう。
55| //X増加量が少ない場合規定値を入れる それなりにあれば10まで増やす
56| if (ballVx < 2 && ballVx >= 0) { ballVx = 2; }
57| else if (ballVx > -2 && ballVx < 0) { ballVx = -2; }
58| else if (ballVx >= -10 && ballVx <= 10) { ballVx *= 1.2; }
59|
60| //回転増加量が少ない場合規定値 それなりにあれば0.5まで増やす
61| if (ballR < 0.017 && ballR >= 0) { ballR = 0.02; }
62| else if (ballR > -0.017 && ballR < 0) { ballR = -0.02; }
63| else if (ballR >= -0.5 && ballR <= 0.5) { ballR *= 1.2 }

ちょっと綺麗にまとまった気がしています。
55行目のコメントで説明が済んでしまっていますね。

「ballVx」はボールのX増加量なので、正で右移動、負で左移動します。
移動増加量が少なすぎる時は規定値に戻し、
それ以外の場合、-10から10までの間で都度1.2倍にする。
という処理をしています。

「ballR」はボールの回転量正で右回り、負で左回り。
やってることは「ballVx」と同様です。



そんなこんなで、こうなりました!
 お手玉テスト http://juz.r.ribbon.to/teutika/01otedama03.html

上に追いつめて連打した時が面白い。うん。
次こそ、拡縮させてばいんばいんとか複数スプライト表示をやるぞ!


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

お名前:

メールアドレス:


ホームページアドレス:

コメント:

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

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

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

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