作成日:2024年09月19日
GetSensor関数を使って玉転がし

ボールを転がせるか?
我ながら想像力が貧困で恐縮ですが、GetSensor関数を利用したゲームと考えると、ボールを転がしてゴールを目指すようなものしか思いつきませんでした
ですので、ゲーム要素はとりあえず排除して、ボールを違和感なく転がせるか、という事について試してみます
大まかな仕組み
前提として、ボールを移動させる場所は平面とし、X軸とY軸で構成されるとします
その平面上のどこかにボールが置かれ、最初は静止しています
板を傾けるとボールは徐々に移動し、端まで行けば停止します
端まで辿り着く前に反対に傾ければボールは徐々に減速し、やがて逆方向へ移動し始めます
板を並行に戻せば、ボールは緩やかに減速し、やがて停止します
動きとしてはこんな感じになるでしょう
使用する値
上記の仕組みから考え、処理上必要となる値は次の通りです
- 現在のボールの位置情報
- 現在のボールの速度情報
- 板の傾き情報(≒加速度情報)
- 板の抵抗情報(≒減速値)
試作
では試作してみます
必要な値は変数に保存し、ボールはオブジェクトフィールドに画像表示するとして作成したイメージが下図です

そして、ボールの移動を制御するスクリプトが次の様になります
「開始」
# ################################################## # ボール位置の初期化とOnTimer開始 # ################################################## 変数を設定 [$$x; 値: 1] Loop [フラッシュ: 延期] 変数を設定 [$$y; 値: 1] Loop [フラッシュ: 延期] フィールドを名前で設定 ["グローバル::position" & Right ( "000" & $$x; 3 ) & "[" & $$y & "]"; ""] 変数を設定 [$$y; 値: $$y + 1] Exit Loop If [$$y > 10] End Loop 変数を設定 [$$x; 値: $$x + 1] Exit Loop If [$$x > 10] End Loop # 初期位置と初速 変数を設定 [$$x; 値: 5] 変数を設定 [$$y; 値: 5] 変数を設定 [$$前後; 値: 0] 変数を設定 [$$左右; 値: 0] フィールドを名前で設定 ["グローバル::position" & Right ( "000" & $$x; 3 ) & "[" & $$y & "]"; グローバル::ball] # OnTimer開始 OnTimerスクリプトをインストール [「OnTimer」; 間隔: .1]
「OnTimer」
# ################################################## # 傾きによりボール位置を変更 # ################################################## # 抵抗による減速 変数を設定 [$$前後; 値: Case ( Abs ( $$前後 ) ≤ .1; 0; $$前後 > .1; $$前後 - .1; $$前後 < -.1; $$前後 + .1; $$前後 )] 変数を設定 [$$左右; 値: Case ( Abs ( $$左右 ) ≤ .1; 0; $$左右 > .1; $$左右 - .1; $$左右 < -.1; $$左右 + .1; $$左右 )] # 傾きを検知 変数を設定 [$attitude; 値: GetSensor ( "attitude" )] 変数を設定 [$左右; 値: GetValue ( $attitude; 1 )] 変数を設定 [$前後; 値: GetValue ( $attitude; 2 )] # 左右方向の加速度調整 変数を設定 [$$左右; 値: $$左右 + $左右] If [( $$x + Int ( $$左右 ) ) < 1] 変数を設定 [$x; 値: 1] 変数を設定 [$$左右; 値: 0] Else If [( $$x + Int ( $$左右 ) ) > 10] 変数を設定 [$x; 値: 10] 変数を設定 [$$左右; 値: 0] Else 変数を設定 [$x; 値: $$x + Int ( $$左右 )] End If # 前後方向の加速度調整 変数を設定 [$$前後; 値: $$前後 + $前後] If [( $$y + Int ( $$前後 ) ) < 1] 変数を設定 [$y; 値: 1] 変数を設定 [$$前後; 値: 0] Else If [( $$y + Int ( $$前後 ) ) > 10] 変数を設定 [$y; 値: 10] 変数を設定 [$$前後; 値: 0] Else 変数を設定 [$y; 値: $$y + Int ( $$前後 )] End If # ボール位置が変わっていたら再描画 If [$$x ≠ $x or $$y ≠ $y] フィールドを名前で設定 ["グローバル::position" & Right ( "000" & $$x; 3 ) & "[" & $$y & "]"; ""] 変数を設定 [$$x; 値: $x] 変数を設定 [$$y; 値: $y] フィールドを名前で設定 ["グローバル::position" & Right ( "000" & $$x; 3 ) & "[" & $$y & "]"; グローバル::ball] End If
試作評価
動かしてみると、とりあえず倒した方向にボールが転がっていきます
傾きに対する移動速度もそれ程違和感はありませんが、若干早いかもしれません
抵抗は、ちょっと強すぎて止まり過ぎです
あとは10マスではガタツキが強いですね
最後に、傾けすぎて画面向きが変わると、傾きとボールの移動方向が一致しなくなります
……といった所ですね
試作2
では先ほどの評価を承けて修正版を作成します
マス目を100×100とし、また画面回転用に4種類の画面を用意しておきます




そして、ボールの移動を制御するスクリプトが次の様になります
「開始」
# ################################################## # ボール位置の初期化とOnTimer開始 # ################################################## 変数を設定 [$$x; 値: 1] Loop [フラッシュ: 延期] 変数を設定 [$$y; 値: 1] Loop [フラッシュ: 延期] フィールドを名前で設定 ["グローバル::position" & Right ( "000" & $$x; 3 ) & "[" & $$y & "]"; ""] 変数を設定 [$$y; 値: $$y + 1] Exit Loop If [$$y > 100] End Loop 変数を設定 [$$x; 値: $$x + 1] Exit Loop If [$$x > 100] End Loop # 初期位置と初速 変数を設定 [$$x; 値: 50] 変数を設定 [$$y; 値: 50] 変数を設定 [$$前後; 値: 0] 変数を設定 [$$左右; 値: 0] フィールドを名前で設定 ["グローバル::position" & Right ( "000" & $$x; 3 ) & "[" & $$y & "]"; グローバル::ball] # OnTimer開始 OnTimerスクリプトをインストール [「OnTimer」; 間隔: .1]
「OnTimer」
# ################################################## # 傾きによりボール位置を変更 # ################################################## # 抵抗による減速 If [Get (ウインドウ方向) = 1] レイアウト切り替え [「縦向」; アニメーション: なし] Else If [Get (ウインドウ方向) = 2] レイアウト切り替え [「縦向逆」; アニメーション: なし] Else If [Get (ウインドウ方向) = -1] レイアウト切り替え [「横向右」; アニメーション: なし] Else If [Get (ウインドウ方向) = -2] レイアウト切り替え [「横向左」; アニメーション: なし] Else レイアウト切り替え [「縦向」; アニメーション: なし] End If # 抵抗による減速 変数を設定 [$$前後; 値: Case ( Abs ( $$前後 ) ≤ .1; 0; $$前後 > .1; $$前後 - .1; $$前後 < -.1; $$前後 + .1; $$前後 )] 変数を設定 [$$左右; 値: Case ( Abs ( $$左右 ) ≤ .1; 0; $$左右 > .1; $$左右 - .1; $$左右 < -.1; $$左右 + .1; $$左右 )] # 傾きを検知 変数を設定 [$attitude; 値: GetSensor ( "attitude" )] 変数を設定 [$左右; 値: GetValue ( $attitude; 1 )] 変数を設定 [$前後; 値: GetValue ( $attitude; 2 )] # 左右方向の加速度調整 変数を設定 [$$左右; 値: $$左右 + $左右 * 5] If [( $$x + Int ( $$左右 ) ) < 1] 変数を設定 [$x; 値: 1] 変数を設定 [$$左右; 値: 0] Else If [( $$x + Int ( $$左右 ) ) > 100] 変数を設定 [$x; 値: 100] 変数を設定 [$$左右; 値: 0] Else 変数を設定 [$x; 値: $$x + Int ( $$左右 )] End If # 前後方向の加速度調整 変数を設定 [$$前後; 値: $$前後 + $前後 * 5] If [( $$y + Int ( $$前後 ) ) < 1] 変数を設定 [$y; 値: 1] 変数を設定 [$$前後; 値: 0] Else If [( $$y + Int ( $$前後 ) ) > 100] 変数を設定 [$y; 値: 100] 変数を設定 [$$前後; 値: 0] Else 変数を設定 [$y; 値: $$y + Int ( $$前後 )] End If # ボール位置が変わっていたら再描画 If [$$x ≠ $x or $$y ≠ $y] フィールドを名前で設定 ["グローバル::position" & Right ( "000" & $$x; 3 ) & "[" & $$y & "]"; ""] 変数を設定 [$$x; 値: $x] 変数を設定 [$$y; 値: $y] フィールドを名前で設定 ["グローバル::position" & Right ( "000" & $$x; 3 ) & "[" & $$y & "]"; グローバル::ball] End If
試作2評価
改めて動かしてみるとかなり滑らかに動きます
速度、抵抗なんかも適当に設定した割に良さそうです
但し画面描画が遅すぎるので画面回転に耐えられません
画面回転を禁止できれば実用できそうですね
試作はこれで終了とします(レイアウト作成で疲れ果てました……)
課題は残っていますが、思ったよりまともなものが出来たと思います
試作品はこちらからダウンロードできますので、ご興味がありましたらどうぞ

以上で今日のメモ書きは終了です
内容はいかがでしたか?
もしご意見やご要望、誤りの指摘などありましたら、下記フォームよりお気軽にご連絡ください