尼崎に引っ越しておよそ1年、これまでは外部で借りていた作業場や試験場が本社に併設されていることで、当社のエンジニアはますます活発に非常用発電機の改造や試験に取り組んでいます。
もちろん仕事に打ち込むのも大切なのですが、それ以上に大事なのが安全です。怪我をしては元も子もありませんものね。社内作業であっても当然、危険予知活動(KY)は行っていますが、当社ではこのたび、KYシートをiOSアプリ化しました。その名も「安全くん」といいます。
これがその画面です。作業内容、考えられる危険、私たちはこうする! を順々にタップして選んでいくだけでその日のKYシートが出来上がります。もちろん選択肢にない項目は自由に追加でき、みんなで共有できる優れたアプリです。こうしてできた安全管理項目は社内サーバに登録され、社内のデジタルサイネージでも表示されるようになっています。
もちろん、こういうのは使ってもらえないとあまり意味がないので、日々アプリを触ってもらえるよう、ちょっと工夫してみました。
隠しゲーム機能の搭載です。自機が中央で回転しながら弾丸を発射し、迫り来る敵をやっつけます。画面をタップするか指を動かすと自機がその方向に回転するのですが、即座に期待する方向を向いたのでは簡単すぎるので、回転速度を一定に制限しているのがポイントです。開発はSwiftで、今回はじめてSpriteKitを使ったのですが、SpriteKitは本当に使いやすい。ただ、1箇所とても苦労したところがありました。
func rotatePlayer(_ pos:CGPoint){
let rad =
atan2(pos.x - player.position.x, pos.y - player.position.y) * -1
//自機の座標とタッチ座標から目標の角度を計算
let prad = player.zRotation //今現在の自機の角度
var diff = abs(Double(rad - prad)) //回転角を計算
if diff > Double.pi {
diff = (Double.pi * 2) - diff
//回転角が180度超えてたら角度の小さい方の値を拾う
}
diff = (diff/Double.pi) * 0.5
//回転角から回転にかかる時間を算出、
//係数を変えると速くなったり遅くなったり
let act = SKAction.rotate(
toAngle: rad,
duration: diff,
shortestUnitArc: true
)
//SKActionを生成
player.run(act, withKey: "rotate")
}
これが自機の回転をコントロールするメソッドで(見づらくてすみません)、touchesMovedの度に呼ばれるのですが、これだとシミュレータでは動いても、iPhone実機ではどんなにタッチしてもまったく回転してくれないという問題が発生してしまいました。これにはネットを探しても似たような情報がなくて相当苦労したのですが、色々試した結果、原因は最後の1行
player.run(act, withKey: "rotate")
にあるとわかりました。
run(_: withKey:)メソッドはキーを指定してアクションを実行するもので、ドキュメントには同じキーを指定したアクションがすでに実行されていたら、実行中のアクションをremoveしてから新しいアクションをaddすると書いてあります。アクションを終了前にremoveするにはキーを指定しておく必要があるので、ドラッグ操作で頻繁に回転方向がころころ変わりアクションが中断させられるこのゲームでは、run(_: withKey:)を使わないといけないんじゃないかとなんとなく思っていたんですね。でも実際には(詳しくはわからないのですが)アクションのremoveがいらない処理になっていたようで、この行を
player.run(act)
としてやると全く問題なく動くようになりました。なんか実行中アクションをremoveしてないからメモリリークしてるんじゃないかと不安になったりもするのですが、そんな様子もなさそうなので、きっと実行終了後に勝手に消えてくれているのでしょう。イヤイヤこれはいかん他に方法があるよというのを知っている人がいたら教えてください。
それにしてもSpriteKitは本当に面白いですね。はじめてさわった私でもこのゲームを1日で作れてしまったくらい簡単だし、物理演算エンジンもオモシロ便利。三友工業は非常用発電機の会社なので、そのうち非常用発電機をモチーフにしたゲームを作ってAppStoreで公開してみようと思います。お楽しみに!