地球を描画

円の描画は

            Circle()

                .fill(Color.blue)

                .frame(width:200, height:200)

                .offset(x: 0, y: -0)

地球の直径 earth.d

地球の位置 earth.x earth.y

描画スケール scale

がDoubleで与えられているとすると

   Circle()

        .fill(Color.blue)

        .frame(width:CGFloat(earth.d * scale), height: CGFloat(earth.d * scale))

        .offset(x: CGFloat(earth.x * Scale), y: CGFloat(earth.y * scale))

でいいはず。

縦は下がプラスなので、符号反転するほうがいいかも。

 

 

 

小数表示

SWIFTUIで小数を表示する方法

Cで言えば、sprintf なんだけど、ググってもなかなか出て来なかったので書いておく。

 

String(format: "AAA = %.3f km/h", 123.45)

 

AAA =  は数値の前に表示するだけ

%.3f 数値を小数点以下3桁に変換

km/h も数値の後に表示するだけ

,123.45  が表示したい数値。変数にしても良い。というか、変数の値をフォーマットして表示するためのもの。

これで文字列にして、Text なんかで表示する。

 

小数表示

SWIFTUIで小数を表示する方法

Cで言えば、sprintf なんだけど、ググってもなかなか出て来なかったので書いておく。

 

String(format: "AAA = %.3f km/h", 123.45)

 

AAA =  は数値の前に表示するだけ

%.3f 数値を小数点以下3桁に変換

km/h も数値の後に表示するだけ

,123.45  が表示したい数値。変数にしても良い。というか、変数の値をフォーマットして表示するためのもの。

これで文字列にして、Text なんかで表示する。

 

SWIFT UI タイマー

動画じゃない画像を動かそうと思ったら、一定時間ごとに座標やスケールを更新してやればよい。この時使うのがタイマー。

昔よくやったのは、ループで座標とかを変更し、そのままでは早く動きすぎてわからないので、タイマーというか、WAITを入れて動きの速さを調整するというもの。でも、SWIFTではこの方法はダメ。いくらループ内で座標を変更しても動いてくれない。この関数を抜け出たときに初めて最終的な座標に動いてくれる。つまり、待たされた挙げ句、最終的なところにワープしてしまう。ワープって通じるのかな?瞬間移動の意味です。

なので、

一定時間ごとにタイマーで関数を呼び出し、関数では1ステップ座標を更新したらそれでおしまい、というふうにプログラムを組む。

 

class game{

var timer = Timer()

func TimerStart(){

    self.timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true){ timer in

         myFunc()

    }

}

func myFunc(){

   x = x + 1 // とか

}

タイマ用の変数timerを用意しておいて、

TimerStart でインスタンスを作成。

withTimerInterval は呼び出し間隔を秒単位で。

repeats は繰り返しか1回だけか。

timer in の後に呼び出す関数を書いておく。

 

タイマーを止めたいときは、invalidateを使う。

func TimerStop(){

  timer.invalidate()

}

 

 

 

ロケットシミュレーション

地球暦XXXX年、地球は大変なことになっていた。どう大変かって?それはさておき、この地球を救うには月軌道にあるアイテムを持って帰るしかない。ところが地球には自動運転出来るロケットや航法システムが無い。この騒ぎで失ってしまったのである。あるのはマニュアルで操縦するしょぼいロケットだけ。

「キミ、ロケットを操縦して、月まで行って来てくれんかね」

「えーっ?ロケットなんて操縦したことないし」

「でも、操縦したくてここへ来たんでしょ?」

「まぁ、そりゃそうなんだけど」

「ロケットなんて簡単、簡単。タイミングを見計らって点火ボタン押すだけだから」

「でも、ハンドル触ったことないし」

「心配いらんよ、ハンドルなんて無いから」

「えーっ? ハンドルないのに、どうやって月へ行くの?」

「このロケットは、進行方向にしか加速できないんだよ」

「それじゃぁ、どうやって月へ向かうの?」

「地球や月に引力があるから、それで勝手に進行方向が変わるんだよ」

「勝手にって」

「ボールを斜めに投げ上げると、放物線を描いて落ちてくるでしょ。一番高いところでは、その進行方向は真横になっているから、そこで加速すると地球を周回する軌道に乗れるってこと。まっすぐ上に向かって加速すると、加速をやめたら地球に落ちてしまうから、周回軌道に乗せるのが大切」

「それだと地球をぐるぐる回ってるだけで、月に行けないんじゃ?」

「月も地球をぐるぐる回っているでしょ。周回軌道に乗ったら加速してやれば高度が上がって月まで行けるよ」

「じゃあ、地球に帰るのはどうするの?」

「応用のきかん人だな、加速すると高度が上がるんだから、減速すれば高度が下がるのだよ」

「ブレーキがあるの?」

「おお、それを言ってなかったな。ブレーキはないけれど、第4段ロケットには減速ボタンがあるからそれを使ってくれ」

「先に言ってよ」

「あ、それから、減速も燃料を使用するから、使いすぎない様にな」

「へ?どして?」

「燃料がなくなると加速も減速もできなくなるから、宇宙の藻屑になってしまう」

「ヒエー」

「それから、このロケットは4段ロケットなんだが、1段から3段までは、いったん点火すると燃料がなくなるまで止めることはできん。第4段だけが自由に噴射を止めたり、減速したり出来るという仕様じゃ」

次のネタ

擬似ギャンブルがダメなので、シミュレーションゲームでも作ってみよう。

昔、Excelマクロで作ったロケットシミュレーション

私的にはおもしろいけれど、一般受けするかどうか。

ま、いいや。

問題はSWIFTUIでどうやって「動かす」か。

ボタンを押すと関数が呼ばれるのだけれど、その関数が終了するまで画面更新しない。

ポチポチ押すたびに1ステップずつ動いていたのではゲームにならない。

株札でやったのは、タイマ関数で関数を延々呼び続ける事。

グラフィックのスケールとか、調べることは山ほどある。

ま、ボチボチやりましょ。